This commit is contained in:
2026-06-14 19:09:18 +01:00
parent 14bd1a9271
commit 13fa90a0e9
3958 changed files with 999286 additions and 4 deletions
@@ -0,0 +1,250 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/*
* Copyright 2018-2020 Mark Callow.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file DrawTexture.cpp
* @brief Draw textures at actual size using the DrawTexture functions
* from OES_draw_texture.
*
* @author Mark Callow
*/
#if defined(_WIN32)
#if _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iomanip>
#include <sstream>
#include <ktx.h>
#include "disable_glm_warnings.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "reenable_warnings.h"
#include "DrawTexture.h"
#include "frame.h"
/* ------------------------------------------------------------------------ */
#if 0
static int isPowerOfTwo (int x)
{
if (x < 0) x = -1;
return ((x != 0) && !(x & (x - 1)));
}
#endif
/* ------------------------------------------------------------------------ */
LoadTestSample*
DrawTexture::create(uint32_t width, uint32_t height,
const char* const szArgs,
const std::string sBasePath)
{
return new DrawTexture(width, height, szArgs, sBasePath);
}
DrawTexture::DrawTexture(uint32_t width, uint32_t height,
const char* const szArgs,
const std::string sBasePath)
: LoadTestSample(width, height, sBasePath)
{
GLint iCropRect[4] = {0, 0, 0, 0};
const GLchar* szExtensions = (const GLchar*)glGetString(GL_EXTENSIONS);
const char* filename;
std::string pathname;
GLenum target;
GLboolean npotTexture;
GLenum glerror;
ktxTexture* kTexture;
KTX_error_code ktxresult;
GLint sign_s = 1, sign_t = 1;
bInitialized = false;
gnTexture = 0;
if (strstr(szExtensions, "OES_draw_texture") != NULL) {
glDrawTexsOES = (PFNGLDRAWTEXSOESPROC)SDL_GL_GetProcAddress("glDrawTexsOES");
glDrawTexiOES = (PFNGLDRAWTEXIOESPROC)SDL_GL_GetProcAddress("glDrawTexiOES");
glDrawTexxOES = (PFNGLDRAWTEXXOESPROC)SDL_GL_GetProcAddress("glDrawTexxOES");
glDrawTexfOES = (PFNGLDRAWTEXFOESPROC)SDL_GL_GetProcAddress("glDrawTexfOES");
glDrawTexsvOES = (PFNGLDRAWTEXSVOESPROC)SDL_GL_GetProcAddress("glDrawTexsvOES");
glDrawTexivOES = (PFNGLDRAWTEXIVOESPROC)SDL_GL_GetProcAddress("glDrawTexivOES");
glDrawTexxvOES = (PFNGLDRAWTEXXVOESPROC)SDL_GL_GetProcAddress("glDrawTexxvOES");
glDrawTexfvOES = (PFNGLDRAWTEXFVOESPROC)SDL_GL_GetProcAddress("glDrawTexfvOES");
} else {
/* Can't do anything */
std::stringstream message;
message << "DrawTexture: this OpenGL ES implementation does not support"
<< " OES_draw_texture. Can't Run Test";
throw std::runtime_error(message.str());
}
if (strstr(szExtensions, "OES_texture_npot") != NULL)
bNpotSupported = GL_TRUE;
else
bNpotSupported = GL_FALSE;
if ((filename = strchr(szArgs, ' ')) != NULL) {
npotTexture = GL_FALSE;
if (!strncmp(szArgs, "--npot ", 7)) {
npotTexture = GL_TRUE;
#if defined(DEBUG)
} else {
assert(0); /* Unknown argument in sampleInvocations */
#endif
}
} else {
filename = szArgs;
npotTexture = GL_FALSE;
}
if (npotTexture && !bNpotSupported) {
/* Load error texture. */
filename = "no-npot.ktx";
}
pathname = getAssetPath() + filename;
ktxresult = ktxTexture_CreateFromNamedFile(pathname.c_str(),
KTX_TEXTURE_CREATE_NO_FLAGS,
&kTexture);
if (KTX_SUCCESS != ktxresult) {
std::stringstream message;
message << "Creation of ktxTexture from \"" << pathname
<< "\" failed: " << ktxErrorString(ktxresult);
throw std::runtime_error(message.str());
}
ktxresult = ktxTexture_GLUpload(kTexture, &gnTexture, &target, &glerror);
if (KTX_SUCCESS == ktxresult) {
if (target != GL_TEXTURE_2D) {
/* Can only draw 2D textures */
glDeleteTextures(1, &gnTexture);
return;
}
if (kTexture->orientation.x == KTX_ORIENT_X_LEFT)
sign_s = -1;
if (kTexture->orientation.y == KTX_ORIENT_Y_DOWN)
sign_t = -1;
iCropRect[2] = uTexWidth = kTexture->baseWidth;
iCropRect[3] = uTexHeight = kTexture->baseHeight;
iCropRect[2] *= sign_s;
iCropRect[3] *= sign_t;
glEnable(target);
if (kTexture->numLevels > 1)
// Enable bilinear mipmapping.
// TO DO: application can consider inserting a key,value pair in
// the KTX file that indicates what type of filtering to use.
glTexParameteri(target,
GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
else
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexParameteriv(target, GL_TEXTURE_CROP_RECT_OES, iCropRect);
/* Check for any errors */
assert(GL_NO_ERROR == glGetError());
ktxTexture_Destroy(kTexture);
} else {
std::stringstream message;
message << "Load of texture from \"" << pathname << "\" failed: ";
if (ktxresult == KTX_GL_ERROR) {
message << std::showbase << "GL error " << std::hex << glerror
<< "occurred.";
} else {
message << ktxErrorString(ktxresult);
}
throw std::runtime_error(message.str());
}
glClearColor(0.4f, 0.4f, 0.5f, 1.0f);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_BYTE, 0, (GLvoid *)frame_position);
bInitialized = GL_TRUE;
}
/* ------------------------------------------------------------------------ */
DrawTexture::~DrawTexture()
{
if (bInitialized) {
glDeleteTextures(1, &gnTexture);
}
assert(GL_NO_ERROR == glGetError());
}
/* ------------------------------------------------------------------------ */
void
DrawTexture::resize(uint32_t uNewWidth, uint32_t uNewHeight)
{
glViewport(0, 0, uNewWidth, uNewHeight);
this->uWidth = uNewWidth;
this->uHeight = uNewHeight;
// Set up an orthographic projection where 1 = 1 pixel
framePMatrix = glm::ortho(0.f, (float)uWidth, 0.f, (float)uHeight);
// Move (0,0,0) to the center of the window.
framePMatrix *= glm::translate(glm::mat4(),
glm::vec3((float)uWidth/2, (float)uHeight/2, 0));
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(framePMatrix));
glMatrixMode(GL_MODELVIEW);
// Scale the frame to fill the viewport. To guarantee its lines
// appear we need to inset them by half-a-pixel hence the -1.
// [Lines at the edges of the clip volume may or may not appear
// depending on the OpenGL ES implementation. This is because
// (a) the edges are on the points of the diamonds of the diamond
// exit rule and slight precision errors can easily push the
// lines outside the diamonds.
// (b) the specification allows lines to be up to 1 pixel either
// side of the exact position.]
glLoadIdentity();
glScalef((float)(uWidth - 1) / 2, (float)(uHeight - 1) / 2, 1);
}
/* ------------------------------------------------------------------------ */
void
DrawTexture::run(uint32_t /*msTicks*/)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
glDrawArrays(GL_LINE_LOOP, 0, 4);
glEnable(GL_TEXTURE_2D);
glDrawTexiOES(uWidth/2 - uTexWidth/2,
(uHeight)/2 - uTexHeight/2,
0,
uTexWidth, uTexHeight);
assert(GL_NO_ERROR == glGetError());
}
/* ------------------------------------------------------------------------ */
@@ -0,0 +1,66 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/*
* Copyright 2018-2020 Mark Callow.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file DrawTexture.h
* @brief Draw textures at actual size using the DrawTexture functions
* from OES_draw_texture.
*
* @author Mark Callow
*/
#ifndef DRAW_TEXTURE_H
#define DRAW_TEXTURE_H
#include <GLES/gl.h>
#include <GLES/glext.h>
#include "LoadTestSample.h"
class DrawTexture : public LoadTestSample {
public:
DrawTexture(uint32_t width, uint32_t height,
const char* const szArgs,
const std::string sBasePath);
~DrawTexture();
virtual void resize(uint32_t width, uint32_t height);
virtual void run(uint32_t msTicks);
//virtual void getOverlayText(GLTextOverlay *textOverlay);
static LoadTestSample*
create(uint32_t width, uint32_t height,
const char* const szArgs, const std::string sBasePath);
protected:
PFNGLDRAWTEXSOESPROC glDrawTexsOES;
PFNGLDRAWTEXIOESPROC glDrawTexiOES;
PFNGLDRAWTEXXOESPROC glDrawTexxOES;
PFNGLDRAWTEXFOESPROC glDrawTexfOES;
PFNGLDRAWTEXSVOESPROC glDrawTexsvOES;
PFNGLDRAWTEXIVOESPROC glDrawTexivOES;
PFNGLDRAWTEXXVOESPROC glDrawTexxvOES;
PFNGLDRAWTEXFVOESPROC glDrawTexfvOES;
uint32_t uWidth;
uint32_t uHeight;
uint32_t uTexWidth;
uint32_t uTexHeight;
glm::mat4 framePMatrix;
GLuint gnTexture;
bool bNpotSupported;
bool bInitialized;
};
#endif /* DRAW_TEXTURE_H */
@@ -0,0 +1,109 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/*
* Copyright 2018-2020 Mark Callow.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file ES1LoadTests.cpp
* @brief List of tests of the KTX loader for OpenGL ES 1.1.
*
* The loader is tested by loading and drawing KTX textures in various formats
* using the DrawTexture and TexturedCube samples.
*/
#include <sstream>
#include <ktx.h>
#include "GLLoadTests.h"
#include "DrawTexture.h"
#include "TexturedCube.h"
LoadTestSample*
GLLoadTests::showFile(const std::string& filename)
{
KTX_error_code ktxresult;
ktxTexture* kTexture;
ktxresult = ktxTexture_CreateFromNamedFile(filename.c_str(),
KTX_TEXTURE_CREATE_NO_FLAGS,
&kTexture);
if (KTX_SUCCESS != ktxresult) {
std::stringstream message;
message << "Creation of ktxTexture from \"" << getAssetPath()
<< filename << "\" failed: " << ktxErrorString(ktxresult);
throw std::runtime_error(message.str());
}
LoadTestSample::PFN_create createViewer;
LoadTestSample* pViewer;
createViewer = DrawTexture::create;
ktxTexture_Destroy(kTexture);
pViewer = createViewer(w_width, w_height, filename.c_str(), "");
return pViewer;
}
const GLLoadTests::sampleInvocation siSamples[] = {
{ DrawTexture::create,
"--npot hi_mark.ktx",
"RGB8 NPOT HI Logo"
},
{ DrawTexture::create,
"--npot luminance-reference-metadata.ktx",
"LUMINANCE8 NPOT"
},
{ DrawTexture::create,
"orient-up-metadata.ktx",
"RGB8 + KTXOrientation up"
},
{ DrawTexture::create,
"orient-down-metadata.ktx",
"RGB8 + KTXOrientation down"
},
{ DrawTexture::create,
"etc1.ktx",
"ETC1 RGB8"
},
{ DrawTexture::create,
"etc2-rgb.ktx",
"ETC2 RGB8"
},
{ DrawTexture::create,
"etc2-rgba1.ktx",
"ETC2 RGB8A1"
},
{ DrawTexture::create,
"etc2-rgba8.ktx",
"ETC2 RGB8A8"
},
{ DrawTexture::create,
"rgba-reference.ktx",
"RGBA8"
},
{ TexturedCube::create,
"rgb-reference.ktx",
"RGB8"
},
{ TexturedCube::create,
"rgb-amg-reference.ktx",
"RGB8 + Auto Mipmap"
},
{ TexturedCube::create,
"rgb-mipmap-reference.ktx",
"RGB8 Color/level mipmap"
},
{ TexturedCube::create,
"--npot hi_mark_sq.ktx",
"RGB8 NPOT HI Logo"
},
};
const int iNumSamples = sizeof(siSamples) / sizeof(GLLoadTests::sampleInvocation);
AppBaseSDL* theApp = new GLLoadTests(siSamples, iNumSamples,
"KTX Loader Tests for OpenGL ES 1",
SDL_GL_CONTEXT_PROFILE_ES, 1, 1);
@@ -0,0 +1,202 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/*
* Copyright 2018-2020 Mark Callow.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file TexturedCube.cpp
* @brief Draw a textured cube.
*/
#if defined(_WIN32)
#if _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iomanip>
#include <sstream>
#include <ktx.h>
#include "disable_glm_warnings.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "reenable_warnings.h"
#include "TexturedCube.h"
#include "cube.h"
#if defined(_WIN32)
#define snprintf _snprintf
#endif
/* ------------------------------------------------------------------------- */
LoadTestSample*
TexturedCube::create(uint32_t width, uint32_t height,
const char* const szArgs,
const std::string sBasePath)
{
return new TexturedCube(width, height, szArgs, sBasePath);
}
TexturedCube::TexturedCube(uint32_t width, uint32_t height,
const char* const szArgs,
const std::string sBasePath)
: LoadTestSample(width, height, sBasePath)
{
const GLchar* szExtensions = (const GLchar*)glGetString(GL_EXTENSIONS);
const char* filename;
std::string pathname;
GLuint gnTexture = 0;
GLenum target;
GLenum glerror;
GLboolean npotSupported, npotTexture;
ktxTexture* kTexture;
KTX_error_code ktxresult;
if (strstr(szExtensions, "OES_texture_npot") != NULL)
npotSupported = GL_TRUE;
else
npotSupported = GL_FALSE;
if ((filename = strchr(szArgs, ' ')) != NULL) {
npotTexture = GL_FALSE;
if (!strncmp(szArgs, "--npot ", 7)) {
npotTexture = GL_TRUE;
#if defined(DEBUG)
} else {
assert(0); /* Unknown argument in sampleInvocations */
#endif
}
} else {
filename = szArgs;
npotTexture = GL_FALSE;
}
if (npotTexture && !npotSupported) {
/* Load error texture. */
filename = "no-npot.ktx";
}
pathname = getAssetPath() + filename;
ktxresult = ktxTexture_CreateFromNamedFile(pathname.c_str(),
KTX_TEXTURE_CREATE_NO_FLAGS,
&kTexture);
if (KTX_SUCCESS != ktxresult) {
std::stringstream message;
message << "Creation of ktxTexture from \"" << pathname
<< "\" failed: " << ktxErrorString(ktxresult);
throw std::runtime_error(message.str());
}
ktxresult = ktxTexture_GLUpload(kTexture, &gnTexture, &target, &glerror);
if (KTX_SUCCESS == ktxresult) {
if (target != GL_TEXTURE_2D) {
/* Can only draw 2D textures */
glDeleteTextures(1, &gnTexture);
return;
}
glEnable(target);
if (kTexture->numLevels > 1)
// Enable bilinear mipmapping.
// TO DO: application can consider inserting a key,value pair in
// the KTX file that indicates what type of filtering to use.
glTexParameteri(target,
GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
else
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
ktxTexture_Destroy(kTexture);
} else {
std::stringstream message;
message << "Load of texture from \"" << pathname << "\" failed: ";
if (ktxresult == KTX_GL_ERROR) {
message << std::showbase << "GL error " << std::hex << glerror
<< "occurred.";
} else {
message << ktxErrorString(ktxresult);
}
throw std::runtime_error(message.str());
}
/* By default dithering is enabled. Dithering does not provide visual
* improvement in this sample so disable it to improve performance.
*/
glDisable(GL_DITHER);
glEnable(GL_CULL_FACE);
glClearColor(0.2f,0.3f,0.4f,1.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, cube_face);
glColorPointer(4, GL_FLOAT, 0, cube_color);
glTexCoordPointer(2, GL_FLOAT, 0, cube_texture);
}
TexturedCube::~TexturedCube()
{
glDisable(GL_TEXTURE_2D);
glEnable(GL_DITHER);
glDisable(GL_CULL_FACE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
assert(GL_NO_ERROR == glGetError());
}
void
TexturedCube::resize(uint32_t uWidth, uint32_t uHeight)
{
glm::mat4 matProj;
glViewport(0, 0, uWidth, uHeight);
glMatrixMode( GL_PROJECTION );
matProj = glm::perspective(glm::radians(45.f),
uWidth / (float)uHeight,
1.f, 100.f);
glLoadIdentity();
glLoadMatrixf(glm::value_ptr(matProj));
glMatrixMode( GL_MODELVIEW );
assert(GL_NO_ERROR == glGetError());
}
void
TexturedCube::run(uint32_t msTicks)
{
/* Setup the view matrix : just turn around the cube. */
const float fDistance = 5.0f;
glm::vec3 eye((float)cos( msTicks*0.001f ) * fDistance,
(float)sin( msTicks*0.0007f ) * fDistance,
(float)sin( msTicks*0.001f ) * fDistance);
glm::vec3 look(0.,0.,0.);
glm::vec3 up(0.,1.,0.);
glm::mat4 matView = glm::lookAt( eye, look, up );
glLoadIdentity();
glLoadMatrixf(glm::value_ptr(matView));
/* Draw */
glClear( GL_COLOR_BUFFER_BIT );
glDrawElements(GL_TRIANGLES, CUBE_NUM_INDICES,
GL_UNSIGNED_SHORT, cube_index_buffer);
assert(GL_NO_ERROR == glGetError());
}
/* ------------------------------------------------------------------------- */
@@ -0,0 +1,38 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/*
* Copyright 2018-2020 Mark Callow.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file TexturedCube.cpp
* @brief Draw a textured cube.
*/
#ifndef TEXTURED_CUBE_H
#define TEXTURED_CUBE_H
#include <GLES/gl.h>
#include <GLES/glext.h>
#include "LoadTestSample.h"
class TexturedCube : public LoadTestSample {
public:
TexturedCube(uint32_t width, uint32_t height,
const char* const szArgs,
const std::string sBasePath);
~TexturedCube();
virtual void resize(uint32_t width, uint32_t height);
virtual void run(uint32_t msTicks);
//virtual void getOverlayText(GLTextOverlay *textOverlay);
static LoadTestSample*
create(uint32_t width, uint32_t height,
const char* const szArgs, const std::string sBasePath);
};
#endif /* TEXTURED_CUBE_H */