Files
scummvm-cursorfix/test/graphics/tinygl_texenv.h
2026-02-02 04:50:13 +01:00

205 lines
7.4 KiB
C++

#include <cxxtest/TestSuite.h>
#ifdef USE_TINYGL
#include "graphics/tinygl/tinygl.h"
// every test sets up some texture environment
// then draws a single pixel and checks the resulting output pixel
class TinyGLTexEnvTestSuite : public CxxTest::TestSuite {
TinyGL::ContextHandle *_context = nullptr;
public:
void setUp() {
_context = TinyGL::createContext(2, 2, Graphics::PixelFormat::createFormatARGB32(), 2, false, false);
TinyGL::setContext(_context);
tglEnable(TGL_TEXTURE_2D);
tglDisable(TGL_BLEND);
tglDisable(TGL_DEPTH_TEST);
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
tglViewport(0, 0, 2, 2);
}
void tearDown() {
if (_context != nullptr) {
TinyGL::destroyContext(_context);
_context = nullptr;
}
}
// these three functions use RGBA order instead of ARGB to make it consistent with tglColor4ub which we also call
void setConstant(byte r, byte g, byte b, byte a) {
const float values[] = { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
tglTexEnvfv(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_COLOR, values);
}
void drawPixel(byte texR, byte texG, byte texB, byte texA) {
const float S = 10.0f;
const byte texData[] = { texR, texG, texB, texA };
TGLuint texture;
tglGenTextures(1, &texture);
tglBindTexture(TGL_TEXTURE_2D, texture);
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP);
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP);
tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, 1, 1, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, &texData);
tglBegin(TGL_TRIANGLES);
tglTexCoord2f(0.0f, 0.0f); tglVertex2f(-S, -S);
tglTexCoord2f(1.0f, 0.0f); tglVertex2f(+S, -S);
tglTexCoord2f(0.5f, 1.0f); tglVertex2f(0, +S);
tglEnd();
}
void checkOutput(byte expR, byte expG, byte expB, byte expA) {
byte actA, actR, actG, actB;
Graphics::Surface surface;
TinyGL::presentBuffer();
TinyGL::getSurfaceRef(surface);
surface.format.colorToARGB(surface.getPixel(0, 0), actA, actR, actG, actB);
TS_ASSERT_EQUALS(expA, actA);
TS_ASSERT_EQUALS(expR, actR);
TS_ASSERT_EQUALS(expG, actG);
TS_ASSERT_EQUALS(expB, actB);
}
void testModulate() {
// no tglTexEnvi setup because TGL_MODULATE should be the default
tglColor4ub(255, 255, 255, 127);
drawPixel(255, 127, 0, 255);
checkOutput(255, 127, 0, 127);
}
void testReplace() {
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_REPLACE);
tglColor4ub(255, 255, 255, 127);
drawPixel(255, 127, 0, 255);
checkOutput(255, 127, 0, 255);
}
void testDecal() {
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_DECAL);
tglColor4ub(100, 200, 255, 123);
drawPixel(200, 100, 0, 192);
checkOutput(176, 125, 63, 123);
}
void testAdd() {
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_ADD);
tglColor4ub(50, 100, 150, 127);
drawPixel(25, 50, 150, 200);
checkOutput(75, 150, 255, 100);
// attention: TGL_ADD still modulates alpha
}
void testBlend() {
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_BLEND);
tglColor4ub(210, 210, 200, 127);
setConstant(123, 123, 100, 42);
drawPixel(0, 255, 128, 200);
checkOutput(211, 123, 150, 100);
// the 211 is an unfortunate rounding problem
}
void setCombineMode(TGLuint combineRGB, TGLuint combineAlpha) {
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_COMBINE);
tglTexEnvi(TGL_TEXTURE_ENV, TGL_COMBINE_RGB, combineRGB);
tglTexEnvi(TGL_TEXTURE_ENV, TGL_COMBINE_ALPHA, combineAlpha);
}
void setCombineArg(int arg, TGLuint rgbSource, TGLuint rgbOperand, TGLuint alphaSource, TGLuint alphaOperand) {
assert(arg >= 0 && arg <= 1);
tglTexEnvi(TGL_TEXTURE_ENV, arg ? TGL_SOURCE1_RGB : TGL_SOURCE0_RGB, rgbSource);
tglTexEnvi(TGL_TEXTURE_ENV, arg ? TGL_SOURCE1_ALPHA : TGL_SOURCE0_ALPHA, alphaSource);
tglTexEnvi(TGL_TEXTURE_ENV, arg ? TGL_OPERAND1_RGB : TGL_OPERAND0_RGB, rgbOperand);
tglTexEnvi(TGL_TEXTURE_ENV, arg ? TGL_OPERAND1_ALPHA : TGL_OPERAND0_ALPHA, alphaOperand);
}
void testCombineArgTexture() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_TEXTURE, TGL_SRC_COLOR, TGL_TEXTURE, TGL_SRC_ALPHA);
drawPixel(13, 37, 42, 24);
checkOutput(13, 37, 42, 24);
}
void testCombineArgPrimaryColor() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_PRIMARY_COLOR, TGL_SRC_COLOR, TGL_PRIMARY_COLOR, TGL_SRC_ALPHA);
tglColor4ub(12, 34, 56, 78);
drawPixel(13, 37, 42, 24);
checkOutput(12, 34, 56, 78);
}
void testCombineArgConstant() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_CONSTANT, TGL_SRC_COLOR, TGL_CONSTANT, TGL_SRC_ALPHA);
setConstant(12, 34, 56, 78);
drawPixel(13, 37, 42, 24);
checkOutput(12, 34, 56, 78);
}
void testCombineArgMixed() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_PRIMARY_COLOR, TGL_SRC_ALPHA, TGL_TEXTURE, TGL_SRC_ALPHA);
tglColor4ub(12, 34, 56, 78);
drawPixel(13, 37, 42, 24);
checkOutput(78, 78, 78, 24);
}
void testCombineOpOneMinus() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_TEXTURE, TGL_ONE_MINUS_SRC_COLOR, TGL_TEXTURE, TGL_ONE_MINUS_SRC_ALPHA);
drawPixel(13, 37, 42, 24);
checkOutput(242, 218, 213, 231);
}
void testCombineOpSrcAlpha() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_TEXTURE, TGL_SRC_ALPHA, TGL_TEXTURE, TGL_ONE_MINUS_SRC_ALPHA);
drawPixel(13, 37, 42, 24);
checkOutput(24, 24, 24, 231);
}
void testCombineReplace() {
setCombineMode(TGL_REPLACE, TGL_REPLACE);
setCombineArg(0, TGL_TEXTURE, TGL_SRC_COLOR, TGL_TEXTURE, TGL_SRC_ALPHA);
setCombineArg(1, TGL_PRIMARY_COLOR, TGL_SRC_COLOR, TGL_PRIMARY_COLOR, TGL_SRC_ALPHA);
tglColor4ub(12, 34, 56, 78); // just to confuse the implementation
drawPixel(13, 37, 42, 24);
checkOutput(13, 37, 42, 24);
}
void testCombineModulate() {
setCombineMode(TGL_MODULATE, TGL_MODULATE);
setCombineArg(0, TGL_TEXTURE, TGL_SRC_COLOR, TGL_TEXTURE, TGL_SRC_ALPHA);
setCombineArg(1, TGL_PRIMARY_COLOR, TGL_SRC_COLOR, TGL_PRIMARY_COLOR, TGL_SRC_ALPHA);
tglColor4ub(255, 255, 255, 127);
drawPixel(255, 127, 0, 255);
checkOutput(255, 127, 0, 127);
}
void testCombineAdd() {
setCombineMode(TGL_ADD, TGL_ADD);
setCombineArg(0, TGL_TEXTURE, TGL_SRC_COLOR, TGL_TEXTURE, TGL_SRC_ALPHA);
setCombineArg(1, TGL_PRIMARY_COLOR, TGL_SRC_COLOR, TGL_PRIMARY_COLOR, TGL_SRC_ALPHA);
tglColor4ub(50, 100, 150, 100);
drawPixel(25, 50, 150, 200);
checkOutput(75, 150, 255, 255);
// attention: TGL_COMBINE TGL_ADD does *not* modulate alpha
}
void testSaveTexEnvState() {
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_REPLACE);
tglColor4ub(0, 0, 0, 0);
drawPixel(255, 127, 0, 255);
tglTexEnvi(TGL_TEXTURE_ENV, TGL_TEXTURE_ENV_MODE, TGL_MODULATE); // before executing the drawcall
checkOutput(255, 127, 0, 255);
}
};
#endif