diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd498c807..38cc45189 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -239,33 +239,6 @@ set( ZDOOM_LIBS ${ZDOOM_LIBS} ${OPENGL_LIBRARIES} ) include_directories( ${OPENGL_INCLUDE_DIR} ) -# check for GLEW -find_path( GLEW_INCLUDE_DIR GL/glew.h - PATHS "/usr/include" - "/usr/local/include" ) - -if( GLEW_INCLUDE_DIR ) - message( STATUS "GLEW include files found at ${GLEW_INCLUDE_DIR}" ) -else( GLEW_INCLUDE_DIR ) - message( SEND_ERROR "Could not find GLEW include files" ) -endif( GLEW_INCLUDE_DIR ) - -# GLEW include directory -include_directories( "${GLEW_INCLUDE_DIR}" ) - -if( NOT WIN32 OR APPLE ) - find_library( GLEW_LIBRARY libGLEW.so ) -else( NOT WIN32 OR APPLE ) - find_library( GLEW_LIBRARY glew32 ) -endif( NOT WIN32 OR APPLE ) - -if( NOT GLEW_LIBRARY ) - message( SEND_ERROR "Could not find GLEW library files" ) -endif( NOT GLEW_LIBRARY ) - -set( ZDOOM_LIBS ${ZDOOM_LIBS} ${GLEW_LIBRARY} ) - - # Decide on the name of the FMOD library we want to use. if( NOT FMOD_LIB_NAME AND MSVC ) @@ -581,6 +554,10 @@ endif( NOT DYN_FLUIDSYNTH ) # Start defining source files for ZDoom set( PLAT_WIN32_SOURCES + gl/hqnx_asm/hq2x_asm.cpp + gl/hqnx_asm/hq3x_asm.cpp + gl/hqnx_asm/hq4x_asm.cpp + gl/hqnx_asm/hqnx_asm_Image.cpp win32/eaxedit.cpp win32/fb_d3d9.cpp win32/fb_d3d9_wipe.cpp @@ -727,6 +704,7 @@ file( GLOB HEADER_FILES gl/data/*.h gl/dynlights/*.h gl/hqnx/*.h + gl/hqnx_asm/*.h gl/models/*.h gl/renderer/*.h gl/scene/*.h @@ -1046,6 +1024,7 @@ add_executable( zdoom WIN32 gl/data/gl_data.cpp gl/data/gl_portaldata.cpp gl/data/gl_setup.cpp + gl/data/gl_matrix.cpp gl/data/gl_vertexbuffer.cpp gl/dynlights/a_dynlight.cpp gl/utility/gl_clock.cpp @@ -1063,6 +1042,7 @@ add_executable( zdoom WIN32 gl/textures/gl_material.cpp gl/textures/gl_hirestex.cpp gl/textures/gl_bitmap.cpp + gl/textures/gl_samplers.cpp gl/textures/gl_translate.cpp gl/textures/gl_hqresize.cpp gl/textures/gl_skyboxtexture.cpp @@ -1093,6 +1073,7 @@ add_executable( zdoom WIN32 gl/system/gl_framebuffer.cpp gl/system/gl_menu.cpp gl/system/gl_wipe.cpp + gl/system/gl_load.c gl/models/gl_models_md3.cpp gl/models/gl_models_md2.cpp gl/models/gl_models.cpp @@ -1297,6 +1278,7 @@ source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/ source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+") source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+") source_group("OpenGL Renderer\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx/.+") +source_group("OpenGL Renderer\\HQ Resize Assembly version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+") source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+") source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+") source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+") diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index 385b7409b..52166f0a8 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -356,7 +356,6 @@ void InitGLRMapinfoData() glset.map_notexturefill = opt->notexturefill; glset.skyrotatevector = opt->skyrotatevector; glset.skyrotatevector2 = opt->skyrotatevector2; - if (gl.shadermodel == 2 && glset.map_lightmode ==2) glset.map_lightmode = 3; } else { @@ -469,9 +468,8 @@ void gl_RecalcVertexHeights(vertex_t * v) void gl_InitData() { - LineSpecials[157]=LS_SetGlobalFogParameter; - LineSpecials[159]=LS_Sector_SetPlaneReflection; - gl_InitModels(); + LineSpecials[157] = LS_SetGlobalFogParameter; + LineSpecials[159] = LS_Sector_SetPlaneReflection; AdjustSpriteOffsets(); } diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 6a71dd1ac..42b6df26e 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -33,7 +33,7 @@ EXTERN_CVAR(Int, gl_weaponlight); inline int getExtraLight() { - return extralight * gl_weaponlight; // ((glset.lightmode == 8)? 16:8); + return extralight * gl_weaponlight; } void gl_RecalcVertexHeights(vertex_t * v); @@ -57,5 +57,8 @@ extern TArray currentmapsection; void gl_InitPortals(); void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); +void gl_InitData(); + +extern long gl_frameMS; #endif diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp new file mode 100644 index 000000000..35683dbb8 --- /dev/null +++ b/src/gl/data/gl_matrix.cpp @@ -0,0 +1,495 @@ +/* -------------------------------------------------- + +Lighthouse3D + +VSMatrix - Very Simple Matrix Library + +http://www.lighthouse3d.com/very-simple-libs + +This is a simplified version of VSMatrix that has been adjusted for GZDoom's needs. + +----------------------------------------------------*/ + +#include "gl/system/gl_system.h" +#include +#include +#include +#include +#include "doomtype.h" +#include "gl/data/gl_matrix.h" + +static inline FLOATTYPE +DegToRad(FLOATTYPE degrees) +{ + return (FLOATTYPE)(degrees * (M_PI / 180.0f)); +}; + +// sets the square matrix mat to the identity matrix, +// size refers to the number of rows (or columns) +void +VSMatrix::setIdentityMatrix( FLOATTYPE *mat, int size) { + + // fill matrix with 0s + for (int i = 0; i < size * size; ++i) + mat[i] = 0.0f; + + // fill diagonal with 1s + for (int i = 0; i < size; ++i) + mat[i + i * size] = 1.0f; +} + + + +// gl LoadIdentity implementation +void +VSMatrix::loadIdentity() +{ + // fill matrix with 0s + for (int i = 0; i < 16; ++i) + mMatrix[i] = 0.0f; + + // fill diagonal with 1s + for (int i = 0; i < 4; ++i) + mMatrix[i + i * 4] = 1.0f; +} + + +// gl MultMatrix implementation +void +VSMatrix::multMatrix(const FLOATTYPE *aMatrix) +{ + + FLOATTYPE res[16]; + + for (int i = 0; i < 4; ++i) + { + for (int j = 0; j < 4; ++j) + { + res[j*4 + i] = 0.0f; + for (int k = 0; k < 4; ++k) + { + res[j*4 + i] += mMatrix[k*4 + i] * aMatrix[j*4 + k]; + } + } + } + memcpy(mMatrix, res, 16 * sizeof(FLOATTYPE)); +} + +#ifdef USE_DOUBLE +// gl MultMatrix implementation +void +VSMatrix::multMatrix(const float *aMatrix) +{ + + FLOATTYPE res[16]; + + for (int i = 0; i < 4; ++i) + { + for (int j = 0; j < 4; ++j) + { + res[j * 4 + i] = 0.0f; + for (int k = 0; k < 4; ++k) + { + res[j*4 + i] += mMatrix[k*4 + i] * aMatrix[j*4 + k]; + } + } + } + memcpy(mMatrix, res, 16 * sizeof(FLOATTYPE)); +} +#endif + + + +// gl LoadMatrix implementation +void +VSMatrix::loadMatrix(const FLOATTYPE *aMatrix) +{ + memcpy(mMatrix, aMatrix, 16 * sizeof(FLOATTYPE)); +} + +#ifdef USE_DOUBLE +// gl LoadMatrix implementation +void +VSMatrix::loadMatrix(const float *aMatrix) +{ + for (int i = 0; i < 16; ++i) + { + mMatrix[i] = aMatrix[i]; + } +} +#endif + + +// gl Translate implementation with matrix selection +void +VSMatrix::translate(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z) +{ + FLOATTYPE mat[16]; + + setIdentityMatrix(mat); + mat[12] = x; + mat[13] = y; + mat[14] = z; + + multMatrix(mat); +} + + +// gl Scale implementation with matrix selection +void +VSMatrix::scale(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z) +{ + FLOATTYPE mat[16]; + + setIdentityMatrix(mat,4); + mat[0] = x; + mat[5] = y; + mat[10] = z; + + multMatrix(mat); +} + + +// gl Rotate implementation with matrix selection +void +VSMatrix::rotate(FLOATTYPE angle, FLOATTYPE x, FLOATTYPE y, FLOATTYPE z) +{ + FLOATTYPE mat[16]; + FLOATTYPE v[3]; + + v[0] = x; + v[1] = y; + v[2] = z; + + FLOATTYPE radAngle = DegToRad(angle); + FLOATTYPE co = cos(radAngle); + FLOATTYPE si = sin(radAngle); + normalize(v); + FLOATTYPE x2 = v[0]*v[0]; + FLOATTYPE y2 = v[1]*v[1]; + FLOATTYPE z2 = v[2]*v[2]; + +// mat[0] = x2 + (y2 + z2) * co; + mat[0] = co + x2 * (1 - co);// + (y2 + z2) * co; + mat[4] = v[0] * v[1] * (1 - co) - v[2] * si; + mat[8] = v[0] * v[2] * (1 - co) + v[1] * si; + mat[12]= 0.0f; + + mat[1] = v[0] * v[1] * (1 - co) + v[2] * si; +// mat[5] = y2 + (x2 + z2) * co; + mat[5] = co + y2 * (1 - co); + mat[9] = v[1] * v[2] * (1 - co) - v[0] * si; + mat[13]= 0.0f; + + mat[2] = v[0] * v[2] * (1 - co) - v[1] * si; + mat[6] = v[1] * v[2] * (1 - co) + v[0] * si; +// mat[10]= z2 + (x2 + y2) * co; + mat[10]= co + z2 * (1 - co); + mat[14]= 0.0f; + + mat[3] = 0.0f; + mat[7] = 0.0f; + mat[11]= 0.0f; + mat[15]= 1.0f; + + multMatrix(mat); +} + + +// gluLookAt implementation +void +VSMatrix::lookAt(FLOATTYPE xPos, FLOATTYPE yPos, FLOATTYPE zPos, + FLOATTYPE xLook, FLOATTYPE yLook, FLOATTYPE zLook, + FLOATTYPE xUp, FLOATTYPE yUp, FLOATTYPE zUp) +{ + FLOATTYPE dir[3], right[3], up[3]; + + up[0] = xUp; up[1] = yUp; up[2] = zUp; + + dir[0] = (xLook - xPos); + dir[1] = (yLook - yPos); + dir[2] = (zLook - zPos); + normalize(dir); + + crossProduct(dir,up,right); + normalize(right); + + crossProduct(right,dir,up); + normalize(up); + + FLOATTYPE m1[16],m2[16]; + + m1[0] = right[0]; + m1[4] = right[1]; + m1[8] = right[2]; + m1[12] = 0.0f; + + m1[1] = up[0]; + m1[5] = up[1]; + m1[9] = up[2]; + m1[13] = 0.0f; + + m1[2] = -dir[0]; + m1[6] = -dir[1]; + m1[10] = -dir[2]; + m1[14] = 0.0f; + + m1[3] = 0.0f; + m1[7] = 0.0f; + m1[11] = 0.0f; + m1[15] = 1.0f; + + setIdentityMatrix(m2,4); + m2[12] = -xPos; + m2[13] = -yPos; + m2[14] = -zPos; + + multMatrix(m1); + multMatrix(m2); +} + + +// gluPerspective implementation +void +VSMatrix::perspective(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE farp) +{ + FLOATTYPE f = 1.0f / tan (fov * (M_PI / 360.0f)); + + loadIdentity(); + mMatrix[0] = f / ratio; + mMatrix[1 * 4 + 1] = f; + mMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp); + mMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp); + mMatrix[2 * 4 + 3] = -1.0f; + mMatrix[3 * 4 + 3] = 0.0f; +} + + +// gl Ortho implementation +void +VSMatrix::ortho(FLOATTYPE left, FLOATTYPE right, + FLOATTYPE bottom, FLOATTYPE top, + FLOATTYPE nearp, FLOATTYPE farp) +{ + loadIdentity(); + + mMatrix[0 * 4 + 0] = 2 / (right - left); + mMatrix[1 * 4 + 1] = 2 / (top - bottom); + mMatrix[2 * 4 + 2] = -2 / (farp - nearp); + mMatrix[3 * 4 + 0] = -(right + left) / (right - left); + mMatrix[3 * 4 + 1] = -(top + bottom) / (top - bottom); + mMatrix[3 * 4 + 2] = -(farp + nearp) / (farp - nearp); +} + + +// gl Frustum implementation +void +VSMatrix::frustum(FLOATTYPE left, FLOATTYPE right, + FLOATTYPE bottom, FLOATTYPE top, + FLOATTYPE nearp, FLOATTYPE farp) +{ + FLOATTYPE m[16]; + + setIdentityMatrix(m,4); + + m[0 * 4 + 0] = 2 * nearp / (right-left); + m[1 * 4 + 1] = 2 * nearp / (top - bottom); + m[2 * 4 + 0] = (right + left) / (right - left); + m[2 * 4 + 1] = (top + bottom) / (top - bottom); + m[2 * 4 + 2] = - (farp + nearp) / (farp - nearp); + m[2 * 4 + 3] = -1.0f; + m[3 * 4 + 2] = - 2 * farp * nearp / (farp-nearp); + m[3 * 4 + 3] = 0.0f; + + multMatrix(m); +} + + +/* +// returns a pointer to the requested matrix +FLOATTYPE * +VSMatrix::get(MatrixTypes aType) +{ + return mMatrix[aType]; +} +*/ + + +/* ----------------------------------------------------- + SEND MATRICES TO OPENGL +------------------------------------------------------*/ + + + + +// universal +void +VSMatrix::matrixToGL(int loc) +{ +#ifdef USE_DOUBLE + float copyto[16]; + copy(copyto); + glUniformMatrix4fv(loc, 1, false, copyto); +#else + glUniformMatrix4fv(loc, 1, false, mMatrix); +#endif +} + +// ----------------------------------------------------- +// AUX functions +// ----------------------------------------------------- + + +// Compute res = M * point +void +VSMatrix::multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *res) +{ + + for (int i = 0; i < 4; ++i) + { + + res[i] = 0.0f; + + for (int j = 0; j < 4; j++) { + + res[i] += point[j] * mMatrix[j*4 + i]; + } + } +} + +// res = a cross b; +void +VSMatrix::crossProduct(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res) { + + res[0] = a[1] * b[2] - b[1] * a[2]; + res[1] = a[2] * b[0] - b[2] * a[0]; + res[2] = a[0] * b[1] - b[0] * a[1]; +} + + +// returns a . b +FLOATTYPE +VSMatrix::dotProduct(const FLOATTYPE *a, const FLOATTYPE *b) { + + FLOATTYPE res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + + return res; +} + + +// Normalize a vec3 +void +VSMatrix::normalize(FLOATTYPE *a) { + + FLOATTYPE mag = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); + + a[0] /= mag; + a[1] /= mag; + a[2] /= mag; +} + + +// res = b - a +void +VSMatrix::subtract(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res) { + + res[0] = b[0] - a[0]; + res[1] = b[1] - a[1]; + res[2] = b[2] - a[2]; +} + + +// res = a + b +void +VSMatrix::add(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res) { + + res[0] = b[0] + a[0]; + res[1] = b[1] + a[1]; + res[2] = b[2] + a[2]; +} + + +// returns |a| +FLOATTYPE +VSMatrix::length(const FLOATTYPE *a) { + + return(sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])); + +} + + +static inline int +M3(int i, int j) +{ + return (i*3+j); +}; + + + +// computes the derived normal matrix for the view matrix +void +VSMatrix::computeNormalMatrix(const FLOATTYPE *aMatrix) +{ + + FLOATTYPE mMat3x3[9]; + + mMat3x3[0] = aMatrix[0]; + mMat3x3[1] = aMatrix[1]; + mMat3x3[2] = aMatrix[2]; + + mMat3x3[3] = aMatrix[4]; + mMat3x3[4] = aMatrix[5]; + mMat3x3[5] = aMatrix[6]; + + mMat3x3[6] = aMatrix[8]; + mMat3x3[7] = aMatrix[9]; + mMat3x3[8] = aMatrix[10]; + + FLOATTYPE det, invDet; + + det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) + + mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + + mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]); + + invDet = 1.0f/det; + + mMatrix[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet; + mMatrix[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet; + mMatrix[2] = (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]) * invDet; + mMatrix[3] = 0.0f; + mMatrix[4] = (mMat3x3[2] * mMat3x3[7] - mMat3x3[1] * mMat3x3[8]) * invDet; + mMatrix[5] = (mMat3x3[0] * mMat3x3[8] - mMat3x3[2] * mMat3x3[6]) * invDet; + mMatrix[6] = (mMat3x3[1] * mMat3x3[6] - mMat3x3[7] * mMat3x3[0]) * invDet; + mMatrix[7] = 0.0f; + mMatrix[8] = (mMat3x3[1] * mMat3x3[5] - mMat3x3[4] * mMat3x3[2]) * invDet; + mMatrix[9] = (mMat3x3[2] * mMat3x3[3] - mMat3x3[0] * mMat3x3[5]) * invDet; + mMatrix[10] =(mMat3x3[0] * mMat3x3[4] - mMat3x3[3] * mMat3x3[1]) * invDet; + mMatrix[11] = 0.0; + mMatrix[12] = 0.0; + mMatrix[13] = 0.0; + mMatrix[14] = 0.0; + mMatrix[15] = 1.0; + +} + + +// aux function resMat = resMat * aMatrix +void +VSMatrix::multMatrix(FLOATTYPE *resMat, const FLOATTYPE *aMatrix) +{ + + FLOATTYPE res[16]; + + for (int i = 0; i < 4; ++i) + { + for (int j = 0; j < 4; ++j) + { + res[j*4 + i] = 0.0f; + for (int k = 0; k < 4; ++k) + { + res[j*4 + i] += resMat[k*4 + i] * aMatrix[j*4 + k]; + } + } + } + memcpy(resMat, res, 16 * sizeof(FLOATTYPE)); +} diff --git a/src/gl/data/gl_matrix.h b/src/gl/data/gl_matrix.h new file mode 100644 index 000000000..de4b400da --- /dev/null +++ b/src/gl/data/gl_matrix.h @@ -0,0 +1,112 @@ + +// Matrix class based on code from VSML: + +/** ---------------------------------------------------------- + * \class VSMathLib + * + * Lighthouse3D + * + * VSMathLib - Very Simple Matrix Library + * + * Full documentation at + * http://www.lighthouse3d.com/very-simple-libs + * + * This class aims at easing geometric transforms, camera + * placement and projection definition for programmers + * working with OpenGL core versions. + * + * + ---------------------------------------------------------------*/ +#ifndef __VSMatrix__ +#define __VSMatrix__ + +#include + +#ifdef USE_DOUBLE +typedef double FLOATTYPE; +#else +typedef float FLOATTYPE; +#endif + +class VSMatrix { + + public: + + VSMatrix() + { + } + + VSMatrix(int) + { + loadIdentity(); + } + + void translate(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z); + void scale(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z); + void rotate(FLOATTYPE angle, FLOATTYPE x, FLOATTYPE y, FLOATTYPE z); + void loadIdentity(); +#ifdef USE_DOUBLE + void multMatrix(const float *aMatrix); +#endif + void multMatrix(const FLOATTYPE *aMatrix); + void multMatrix(const VSMatrix &aMatrix) + { + multMatrix(aMatrix.mMatrix); + } + void loadMatrix(const FLOATTYPE *aMatrix); +#ifdef USE_DOUBLE + void loadMatrix(const float *aMatrix); +#endif + void lookAt(FLOATTYPE xPos, FLOATTYPE yPos, FLOATTYPE zPos, FLOATTYPE xLook, FLOATTYPE yLook, FLOATTYPE zLook, FLOATTYPE xUp, FLOATTYPE yUp, FLOATTYPE zUp); + void perspective(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE farp); + void ortho(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, FLOATTYPE nearp=-1.0f, FLOATTYPE farp=1.0f); + void frustum(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, FLOATTYPE nearp, FLOATTYPE farp); + void copy(FLOATTYPE * pDest) + { + memcpy(pDest, mMatrix, 16 * sizeof(FLOATTYPE)); + } + +#ifdef USE_DOUBLE + void copy(float * pDest) + { + for (int i = 0; i < 16; i++) + { + pDest[i] = (float)mMatrix[i]; + } + } +#endif + + const FLOATTYPE *get() const + { + return mMatrix; + } + + void matrixToGL(int location); + void multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *res); + +#ifdef USE_DOUBLE + void computeNormalMatrix(const float *aMatrix); +#endif + void computeNormalMatrix(const FLOATTYPE *aMatrix); + void computeNormalMatrix(const VSMatrix &aMatrix) + { + computeNormalMatrix(aMatrix.mMatrix); + } + + protected: + static void crossProduct(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res); + static FLOATTYPE dotProduct(const FLOATTYPE *a, const FLOATTYPE * b); + static void normalize(FLOATTYPE *a); + static void subtract(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res); + static void add(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res); + static FLOATTYPE length(const FLOATTYPE *a); + static void multMatrix(FLOATTYPE *resMatrix, const FLOATTYPE *aMatrix); + + static void setIdentityMatrix(FLOATTYPE *mat, int size = 4); + + /// The storage for matrices + FLOATTYPE mMatrix[16]; + +}; + +#endif \ No newline at end of file diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index dae203774..5e6e0767b 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -62,7 +62,6 @@ #include "gl/gl_functions.h" void InitGLRMapinfoData(); -void gl_InitData(); //========================================================================== // @@ -614,15 +613,6 @@ void gl_PreprocessLevel() { int i; - static int datadone=-1; - - - if (datadone != restart) - { - datadone = restart; - gl_InitData(); - } - PrepareSegs(); PrepareSectorData(); InitVertexData(); diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index c07b6cea3..0e9065557 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -45,27 +45,11 @@ #include "c_cvars.h" #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderer.h" +#include "gl/shaders/gl_shader.h" #include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" -CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - if (self < -1 || self > 2) - { - self = 0; - } - else if (self == -1) - { - if (!(gl.flags & RFL_NVIDIA)) self = 0; - else self = 2; - } - else if (GLRenderer != NULL && GLRenderer->mVBO != NULL && GLRenderer->mVBO->vbo_arg != self) - { - Printf("Vertex buffer use will be changed for the next level.\n"); - } -} - //========================================================================== // // Create / destroy the VBO @@ -74,9 +58,10 @@ CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA FVertexBuffer::FVertexBuffer() { - vbo_id = 0; - if (gl_usevbo == -1) gl_usevbo.Callback(); + vao_id = vbo_id = 0; glGenBuffers(1, &vbo_id); + glGenVertexArrays(1, &vao_id); + } FVertexBuffer::~FVertexBuffer() @@ -85,6 +70,15 @@ FVertexBuffer::~FVertexBuffer() { glDeleteBuffers(1, &vbo_id); } + if (vao_id != 0) + { + glDeleteVertexArrays(1, &vao_id); + } +} + +void FVertexBuffer::BindVBO() +{ + glBindVertexArray(vao_id); } //========================================================================== @@ -96,13 +90,60 @@ FVertexBuffer::~FVertexBuffer() FFlatVertexBuffer::FFlatVertexBuffer() : FVertexBuffer() { - vbo_arg = gl_usevbo; - map = NULL; + if (gl.flags & RFL_BUFFER_STORAGE) + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + + glBindVertexArray(vao_id); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glVertexAttribPointer(VATTR_VERTEX, 3,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); + glVertexAttribPointer(VATTR_TEXCOORD, 2,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); + glEnableVertexAttribArray(VATTR_VERTEX); + glEnableVertexAttribArray(VATTR_TEXCOORD); + glBindVertexArray(0); + } + else + { + vbo_shadowdata.Reserve(BUFFER_SIZE); + map = &vbo_shadowdata[0]; + } + mNumReserved = mIndex = mCurIndex = 0; } FFlatVertexBuffer::~FFlatVertexBuffer() { - UnmapVBO(); + if (gl.flags & RFL_BUFFER_STORAGE) + { + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } +} + +//========================================================================== +// +// immediate mode fallback for drivers without GL_ARB_buffer_storage +// +// No single core method is performant enough to handle this adequately +// so we have to resort to immediate mode instead... +// +//========================================================================== + +void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count) +{ + // this will only get called if we can't acquire a persistently mapped buffer. +#ifndef CORE_PROFILE + glBegin(primtype); + for (unsigned int i = 0; i < count; i++) + { + glVertexAttrib2fv(VATTR_TEXCOORD, &map[offset + i].u); + glVertexAttrib3fv(VATTR_VERTEX, &map[offset + i].x); + } + glEnd(); +#endif } //========================================================================== @@ -118,7 +159,6 @@ void FFlatVertex::SetFlatVertex(vertex_t *vt, const secplane_t & plane) z = plane.ZatPoint(vt->fx, vt->fy); u = vt->fx/64.f; v = -vt->fy/64.f; - w = /*dc = df =*/ 0; } //========================================================================== @@ -260,58 +300,18 @@ void FFlatVertexBuffer::CreateFlatVBO() // //========================================================================== -void FFlatVertexBuffer::MapVBO() -{ - if (map == NULL) - { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, vbo_shadowdata.Size() * sizeof(FFlatVertex), - GL_MAP_WRITE_BIT|GL_MAP_FLUSH_EXPLICIT_BIT|GL_MAP_UNSYNCHRONIZED_BIT); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatVertexBuffer::UnmapVBO() -{ - if (map != NULL) - { - glUnmapBuffer(GL_ARRAY_BUFFER); - map = NULL; - } -} - -//========================================================================== -// -// -// -//========================================================================== - void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) { int startvt = sec->vboindex[plane]; int countvt = sec->vbocount[plane]; secplane_t &splane = sec->GetSecPlane(plane); FFlatVertex *vt = &vbo_shadowdata[startvt]; - for(int i=0; iz = splane.ZatPoint(vt->x, vt->y); if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; - } - if (gl.flags & RFL_MAP_BUFFER_RANGE) - { - MapVBO(); - if (map == NULL) return; // Error - memcpy(&map[startvt], &vbo_shadowdata[startvt], countvt * sizeof(FFlatVertex)); - glFlushMappedBufferRange(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex)); - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex), &vbo_shadowdata[startvt]); + mapvt->z = vt->z; } } @@ -323,12 +323,12 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { - vbo_shadowdata.Clear(); - if (vbo_arg > 0) + if (gl.flags & RFL_BUFFER_STORAGE) { + vbo_shadowdata.Resize(mNumReserved); CreateFlatVBO(); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, vbo_shadowdata.Size() * sizeof(FFlatVertex), &vbo_shadowdata[0], GL_DYNAMIC_DRAW); + mCurIndex = mIndex = vbo_shadowdata.Size(); + memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); } else if (sectors) { @@ -340,27 +340,7 @@ void FFlatVertexBuffer::CreateVBO() sectors[i].vboheight[1] = sectors[i].vboheight[0] = FIXED_MIN; } } -} -//========================================================================== -// -// -// -//========================================================================== - -void FFlatVertexBuffer::BindVBO() -{ - if (vbo_arg > 0) - { - UnmapVBO(); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x); - glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_INDEX_ARRAY); - } } //========================================================================== @@ -373,39 +353,31 @@ void FFlatVertexBuffer::CheckPlanes(sector_t *sector) { if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) { - if (sector->ceilingdata == NULL) // only update if there's no thinker attached - { - UpdatePlaneVertices(sector, sector_t::ceiling); - sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling); - } + UpdatePlaneVertices(sector, sector_t::ceiling); + sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling); } if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor]) { - if (sector->floordata == NULL) // only update if there's no thinker attached - { - UpdatePlaneVertices(sector, sector_t::floor); - sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor); - } + UpdatePlaneVertices(sector, sector_t::floor); + sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor); } } //========================================================================== // // checks the validity of all planes attached to this sector -// and updates them if possible. Anything moving will not be -// updated unless it stops. This is to ensure that we never -// have to synchronize with the rendering process. +// and updates them if possible. // //========================================================================== void FFlatVertexBuffer::CheckUpdate(sector_t *sector) { - if (vbo_arg == 2) + if (gl.flags & RFL_BUFFER_STORAGE) { CheckPlanes(sector); sector_t *hs = sector->GetHeightSec(); if (hs != NULL) CheckPlanes(hs); - for(unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) + for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) CheckPlanes(sector->e->XFloor.ffloors[i]->model); } } \ No newline at end of file diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 49db1c7db..b6d61f2da 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -2,6 +2,8 @@ #define __VERTEXBUFFER_H #include "tarray.h" +#include "gl/utility/gl_clock.h" +#include "gl/system/gl_interface.h" struct vertex_t; struct secplane_t; @@ -13,20 +15,28 @@ class FVertexBuffer { protected: unsigned int vbo_id; + unsigned int vao_id; public: FVertexBuffer(); virtual ~FVertexBuffer(); - virtual void BindVBO() = 0; + void BindVBO(); }; -struct FFlatVertex // exactly 32 bytes large +struct FFlatVertex { - float x,z,y,w; // w only for padding to make one vertex 32 bytes - maybe it will find some use later + float x,z,y; // world position float u,v; // texture coordinates - //float dc, df; // distance to floor and ceiling on walls - used for glowing void SetFlatVertex(vertex_t *vt, const secplane_t &plane); + void Set(float xx, float zz, float yy, float uu, float vv) + { + x = xx; + z = zz; + y = yy; + u = uu; + v = vv; + } }; #define VTO ((FFlatVertex*)NULL) @@ -35,28 +45,169 @@ struct FFlatVertex // exactly 32 bytes large class FFlatVertexBuffer : public FVertexBuffer { FFlatVertex *map; + unsigned int mIndex; + unsigned int mCurIndex; + unsigned int mNumReserved; - void MapVBO(); void CheckPlanes(sector_t *sector); -public: - int vbo_arg; - TArray vbo_shadowdata; // this is kept around for non-VBO rendering + const unsigned int BUFFER_SIZE = 2000000; + const unsigned int BUFFER_SIZE_TO_USE = 1999500; + + void ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count); public: + TArray vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer and as stand-in for pre GL 4.x + FFlatVertexBuffer(); ~FFlatVertexBuffer(); + void CreateVBO(); + void CheckUpdate(sector_t *sector); + + FFlatVertex *GetBuffer() + { + return &map[mCurIndex]; + } + unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset) + { + + unsigned int newofs = (unsigned int)(newptr - map); + unsigned int diff = newofs - mCurIndex; + *poffset = mCurIndex; + mCurIndex = newofs; + if (mCurIndex >= BUFFER_SIZE_TO_USE) mCurIndex = mIndex; + return diff; + } +#ifdef __GL_PCH_H // we need the system includes for this but we cannot include them ourselves without creating #define clashes. The affected files wouldn't try to draw anyway. + void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count) + { + drawcalls.Clock(); + if (gl.flags & RFL_BUFFER_STORAGE) + { + glDrawArrays(primtype, offset, count); + } + else + { + ImmRenderBuffer(primtype, offset, count); + } + drawcalls.Unclock(); + } + + void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL) + { + unsigned int offset; + unsigned int count = GetCount(newptr, &offset); + RenderArray(primtype, offset, count); + if (poffset) *poffset = offset; + if (pcount) *pcount = count; + } + +#endif + void Reset() + { + mCurIndex = mIndex; + } + +private: int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor); int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); void CreateFlatVBO(); - void CreateVBO(); void UpdatePlaneVertices(sector_t *sec, int plane); - void BindVBO(); - void CheckUpdate(sector_t *sector); - void UnmapVBO(); }; + +struct FSkyVertex +{ + float x, y, z, u, v; + PalEntry color; + + void Set(float xx, float zz, float yy, float uu=0, float vv=0, PalEntry col=0xffffffff) + { + x = xx; + z = zz; + y = yy; + u = uu; + v = vv; + color = col; + } + +}; + +class FSkyVertexBuffer : public FVertexBuffer +{ +public: + static const int SKYHEMI_UPPER = 1; + static const int SKYHEMI_LOWER = 2; + + enum + { + SKYMODE_MAINLAYER = 0, + SKYMODE_SECONDLAYER = 1, + SKYMODE_FOGLAYER = 2 + }; + +private: + TArray mVertices; + TArray mPrimStart; + + int mRows, mColumns; + + void SkyVertex(int r, int c, bool yflip); + void CreateSkyHemisphere(int hemi); + void CreateDome(); + void RenderRow(int prim, int row); + +public: + + FSkyVertexBuffer(); + virtual ~FSkyVertexBuffer(); + void RenderDome(FMaterial *tex, int mode); + +}; + +#define VSO ((FSkyVertex*)NULL) + +struct FModelVertex +{ + float x, y, z; // world position + float u, v; // texture coordinates + + void Set(float xx, float yy, float zz, float uu, float vv) + { + x = xx; + y = yy; + z = zz; + u = uu; + v = vv; + } + + void SetNormal(float nx, float ny, float nz) + { + // GZDoom currently doesn't use normals. This function is so that the high level code can pretend it does. + } +}; + + +class FModelVertexBuffer : public FVertexBuffer +{ + int mIndexFrame[2]; + unsigned int ibo_id; + +public: + // these are public because it's the models having to fill them in. + TArray vbo_shadowdata; // this is kept around for interpolating on GL 2.0 + TArray ibo_shadowdata; // this is kept around for interpolating on GL 2.0 + + FModelVertexBuffer(); + ~FModelVertexBuffer(); + + unsigned int SetupFrame(unsigned int frame1, unsigned int frame2, float factor); +}; + +#define VMO ((FModelVertex*)NULL) + + #endif \ No newline at end of file diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index a123f34fc..bcc126ecf 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -521,11 +521,14 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius) { if (!subSec) return; - bool additive = (flags4&MF4_ADDITIVE) || gl_lights_additive; - subSec->validcount = ::validcount; - touching_subsectors = AddLightNode(&subSec->lighthead[additive], subSec, this, touching_subsectors); + touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors); + if (subSec->sector->validcount != ::validcount) + { + touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector); + subSec->sector->validcount = ::validcount; + } for (unsigned int i = 0; i < subSec->numlines; i++) { @@ -537,8 +540,7 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius) if (DMulScale32 (y-seg->v1->y, seg->v2->x-seg->v1->x, seg->v1->x-x, seg->v2->y-seg->v1->y) <=0) { seg->linedef->validcount=validcount; - touching_sides = AddLightNode(&seg->sidedef->lighthead[additive], - seg->sidedef, this, touching_sides); + touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides); } } @@ -581,15 +583,21 @@ void ADynamicLight::LinkLight() node->lightsource = NULL; node = node->nextTarget; } + node = touching_sector; + while (node) + { + node->lightsource = NULL; + node = node->nextTarget; + } if (radius>0) { // passing in radius*radius allows us to do a distance check without any calls to sqrtf - ::validcount++; subsector_t * subSec = R_PointInSubsector(x, y); if (subSec) { float fradius = FIXED2FLOAT(radius); + ::validcount++; CollectWithinRadius(subSec, fradius*fradius); } } @@ -618,6 +626,17 @@ void ADynamicLight::LinkLight() else node = node->nextTarget; } + + node = touching_sector; + while (node) + { + if (node->lightsource == NULL) + { + node = DeleteLightNode(node); + } + else + node = node->nextTarget; + } } @@ -670,8 +689,8 @@ size_t AActor::PropagateMark() CCMD(listlights) { - int walls, sectors; - int allwalls=0, allsectors=0; + int walls, sectors, subsecs; + int allwalls=0, allsectors=0, allsubsecs = 0; int i=0; ADynamicLight * dl; TThinkerIterator it; @@ -680,6 +699,7 @@ CCMD(listlights) { walls=0; sectors=0; + subsecs = 0; Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f ", dl->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(), FIXED2FLOAT(dl->x), FIXED2FLOAT(dl->y), FIXED2FLOAT(dl->z), dl->args[LIGHT_RED], @@ -706,17 +726,25 @@ CCMD(listlights) node=dl->touching_subsectors; + while (node) + { + allsubsecs++; + subsecs++; + node = node->nextTarget; + } + + node = dl->touching_sector; + while (node) { allsectors++; sectors++; node = node->nextTarget; } - - Printf("- %d walls, %d subsectors\n", walls, sectors); + Printf("- %d walls, %d subsectors, %d sectors\n", walls, subsecs, sectors); } - Printf("%i dynamic lights, %d walls, %d subsectors\n\n\n", i, allwalls, allsectors); + Printf("%i dynamic lights, %d walls, %d subsectors, %d sectors\n\n\n", i, allwalls, allsubsecs, allsectors); } CCMD(listsublights) @@ -725,22 +753,15 @@ CCMD(listsublights) { subsector_t *sub = &subsectors[i]; int lights = 0; - int addlights = 0; - FLightNode * node = sub->lighthead[0]; + FLightNode * node = sub->lighthead; while (node != NULL) { lights++; node = node->nextLight; } - node = sub->lighthead[1]; - while (node != NULL) - { - addlights++; - node = node->nextLight; - } - Printf(PRINT_LOG, "Subsector %d - %d lights, %d additive lights\n", i, lights, addlights); + Printf(PRINT_LOG, "Subsector %d - %d lights\n", i, lights); } } diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index ca3b2ec90..568630898 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -95,6 +95,7 @@ public: FState *targetState; FLightNode * touching_sides; FLightNode * touching_subsectors; + FLightNode * touching_sector; private: float DistToSeg(seg_t *seg); @@ -182,9 +183,8 @@ struct FDynLightData -bool gl_GetLight(Plane & p, ADynamicLight * light, int desaturation, bool checkside, bool forceadditive, FDynLightData &data); -bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, int desaturation, bool checkside=true, bool forceadditive=true); -bool gl_SetupLightTexture(); +bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data); +void gl_UploadLights(FDynLightData &data); #endif diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 0b2ffa43d..c504a33c4 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -68,11 +68,6 @@ CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN else gl_DeleteAllAttachedLights(); } -CUSTOM_CVAR (Bool, gl_dynlight_shader, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - if (self && (gl.maxuniforms < 1024 || gl.shadermodel < 4)) self = false; -} - CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Float, gl_lights_intensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); @@ -90,8 +85,7 @@ CUSTOM_CVAR (Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG // Sets up the parameters to render one dynamic light onto one plane // //========================================================================== -bool gl_GetLight(Plane & p, ADynamicLight * light, - int desaturation, bool checkside, bool forceadditive, FDynLightData &ldata) +bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &ldata) { Vector fn, pos; int i = 0; @@ -137,14 +131,6 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, i = 1; } - if (desaturation>0) - { - float gray=(r*77 + g*143 + b*37)/257; - - r= (r*(32-desaturation)+ gray*desaturation)/32; - g= (g*(32-desaturation)+ gray*desaturation)/32; - b= (b*(32-desaturation)+ gray*desaturation)/32; - } float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)]; data[0] = x; data[1] = z; @@ -158,109 +144,3 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, } - - -//========================================================================== -// -// Sets up the parameters to render one dynamic light onto one plane -// -//========================================================================== -bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, - float & scale, int desaturation, bool checkside, bool forceadditive) -{ - Vector fn, pos; - - float x = FIXED2FLOAT(light->x); - float y = FIXED2FLOAT(light->y); - float z = FIXED2FLOAT(light->z); - - float dist = fabsf(p.DistToPoint(x, z, y)); - float radius = (light->GetRadius() * gl_lights_size); - - if (radius <= 0.f) return false; - if (dist > radius) return false; - if (checkside && gl_lights_checkside && p.PointOnSide(x, z, y)) - { - return false; - } - if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer()) - { - return false; - } - - scale = 1.0f / ((2.f * radius) - dist); - - // project light position onto plane (find closest point on plane) - - - pos.Set(x,z,y); - fn=p.Normal(); - fn.GetRightUp(right, up); - -#ifdef _MSC_VER - nearPt = pos + fn * dist; -#else - Vector tmpVec = fn * dist; - nearPt = pos + tmpVec; -#endif - - float cs = 1.0f - (dist / radius); - if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs*=0.2f; // otherwise the light gets too strong. - float r = light->GetRed() / 255.0f * cs * gl_lights_intensity; - float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity; - float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity; - - if (light->IsSubtractive()) - { - Vector v; - - gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT); - v.Set(r, g, b); - r = v.Length() - r; - g = v.Length() - g; - b = v.Length() - b; - } - else - { - gl_RenderState.BlendEquation(GL_FUNC_ADD); - } - if (desaturation>0) - { - float gray=(r*77 + g*143 + b*37)/257; - - r= (r*(32-desaturation)+ gray*desaturation)/32; - g= (g*(32-desaturation)+ gray*desaturation)/32; - b= (b*(32-desaturation)+ gray*desaturation)/32; - } - glColor3f(r,g,b); - return true; -} - - -//========================================================================== -// -// -// -//========================================================================== - -bool gl_SetupLightTexture() -{ - - if (GLRenderer->gllight == NULL) return false; - FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight); - pat->BindPatch(CM_DEFAULT, 0); - return true; -} - - -//========================================================================== -// -// -// -//========================================================================== - -inline fixed_t P_AproxDistance3(fixed_t dx, fixed_t dy, fixed_t dz) -{ - return P_AproxDistance(P_AproxDistance(dx,dy),dz); -} - diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index 9f141e6af..7e96c43ce 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -1,9 +1,9 @@ /* -** gl_dynlight1.cpp -** dynamic light buffer for shader rendering +** gl_lightbuffer.cpp +** Buffer data maintenance for dynamic lights ** **--------------------------------------------------------------------------- -** Copyright 2009 Christoph Oelckers +** Copyright 2014 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -38,206 +38,184 @@ ** */ -#if 0 // unused for now. Code doesn't work - #include "gl/system/gl_system.h" -#include "c_dispatch.h" -#include "p_local.h" -#include "vectors.h" -#include "g_level.h" - -#include "gl/system/gl_cvars.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_lightbuffer.h" -#include "gl/scene/gl_drawinfo.h" -#include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_material.h" +#include "gl/dynlights/gl_lightbuffer.h" +#include "gl/dynlights/gl_dynlight.h" +#include "gl/system/gl_interface.h" +#include "gl/utility//gl_clock.h" +static const int INITIAL_BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB. -//========================================================================== -// -// -// -//========================================================================== +float *mMap; FLightBuffer::FLightBuffer() { - glGenBuffers(1, &mIDbuf_RGB); - glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_RGB); - glGenBuffers(1, &mIDbuf_Position); - glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_Position); + mBufferSize = INITIAL_BUFFER_SIZE; + mByteSize = mBufferSize * sizeof(float); + if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + { + mBufferType = GL_SHADER_STORAGE_BUFFER; + mBlockAlign = -1; + mBlockSize = mBufferSize; + } + else + { + mBufferType = GL_UNIFORM_BUFFER; + mBlockSize = gl.maxuniformblock / 16; + if (mBlockSize > 2048) mBlockSize = 2048; // we don't really need a larger buffer + mBlockAlign = mBlockSize / 2; + } - glGenTextures(1, &mIDtex_RGB); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_RGB); - gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, mIDbuf_RGB); + glGenBuffers(1, &mBufferId); + glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId); + if (gl.flags & RFL_BUFFER_STORAGE) + { + glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + } + else + { + glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW); + mBufferPointer = NULL; + } - glGenTextures(1, &mIDtex_Position); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_Position); - gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA32F, mIDbuf_Position); + Clear(); + mLastMappedIndex = UINT_MAX; } - -//========================================================================== -// -// -// -//========================================================================== - FLightBuffer::~FLightBuffer() { - glBindBuffer(GL_TEXTURE_BUFFER, 0); - glDeleteBuffers(1, &mIDbuf_RGB); - glDeleteBuffers(1, &mIDbuf_Position); - - glBindTexture(GL_TEXTURE_BUFFER, 0); - glDeleteTextures(1, &mIDtex_RGB); - glDeleteTextures(1, &mIDtex_Position); - + glBindBuffer(mBufferType, 0); + glDeleteBuffers(1, &mBufferId); } -//========================================================================== -// -// -// -//========================================================================== - -void FLightBuffer::BindTextures(int texunit1, int texunit2) +void FLightBuffer::Clear() { - glActiveTexture(texunit1); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_RGB); - glActiveTexture(texunit2); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_Position); - glActiveTexture(GL_TEXTURE0); + mIndex = 0; + mIndices.Clear(); + mUploadIndex = 0; } - -//========================================================================== -// -// This collects all currently actove -// -//========================================================================== - -void FLightBuffer::CollectLightSources() +int FLightBuffer::UploadLights(FDynLightData &data) { - if (gl_dynlight_shader && gl_lights && GLRenderer->mLightCount && gl_fixedcolormap == CM_DEFAULT) + int size0 = data.arrays[0].Size()/4; + int size1 = data.arrays[1].Size()/4; + int size2 = data.arrays[2].Size()/4; + int totalsize = size0 + size1 + size2 + 1; + + if (mBlockAlign >= 0 && totalsize + (mIndex % mBlockAlign) > mBlockSize) { - TArray pLights(100); - TArray pPos(100); - TThinkerIterator it(STAT_DLIGHT); + mIndex = ((mIndex + mBlockAlign) / mBlockAlign) * mBlockAlign; - ADynamicLight *light; - - while ((light = it.Next()) != NULL) + // can't be rendered all at once. + if (totalsize > mBlockSize) { - if (!(light->flags2 & MF2_DORMANT)) + int diff = totalsize - mBlockSize; + + size2 -= diff; + if (size2 < 0) { - FLightRGB rgb; - FLightPosition pos; - - rgb.R = light->GetRed(); - rgb.G = light->GetGreen(); - rgb.B = light->GetBlue(); - rgb.Type = (light->flags4 & MF4_SUBTRACTIVE)? 128 : (light->flags4 & MF4_ADDITIVE || foggy)? 255:0; - pos.X = FIXED2FLOAT(light->x); - pos.Y = FIXED2FLOAT(light->y); - pos.Z = FIXED2FLOAT(light->z); - pos.Distance = (light->GetRadius() * gl_lights_size); - light->bufferindex = pPos.Size(); - pLights.Push(rgb); - pPos.Push(pos); + size1 += size2; + size2 = 0; } - else light->bufferindex = -1; + if (size1 < 0) + { + size0 += size1; + size1 = 0; + } + totalsize = size0 + size1 + size2 + 1; } - GLRenderer->mLightCount = pPos.Size(); - - glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_RGB); - glBufferData(GL_TEXTURE_BUFFER, pLights.Size() * sizeof (FLightRGB), &pLights[0], GL_STREAM_DRAW); - - glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_Position); - glBufferData(GL_TEXTURE_BUFFER, pPos.Size() * sizeof (FLightPosition), &pPos[0], GL_STREAM_DRAW); - } -} + if (totalsize <= 1) return -1; -//========================================================================== -// -// -// -//========================================================================== - -FLightIndexBuffer::FLightIndexBuffer() -{ - glGenBuffers(1, &mIDBuffer); - glBindBuffer(GL_TEXTURE_BUFFER, mIDBuffer); - - glGenTextures(1, &mIDTexture); - glBindTexture(GL_TEXTURE_BUFFER, mIDTexture); - gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_R16UI, mIDBuffer); -} - -//========================================================================== -// -// -// -//========================================================================== - -FLightIndexBuffer::~FLightIndexBuffer() -{ - glBindBuffer(GL_TEXTURE_BUFFER, 0); - glDeleteBuffers(1, &mIDBuffer); - - glBindTexture(GL_TEXTURE_BUFFER, 0); - glDeleteTextures(1, &mIDTexture); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FLightIndexBuffer::AddLight(ADynamicLight *light) -{ - if (light->bufferindex >= 0) + if (mIndex + totalsize > mBufferSize) { - mBuffer.Push(light->bufferindex); + // reallocate the buffer with twice the size + unsigned int newbuffer; + + // first unmap the old buffer + glBindBuffer(mBufferType, mBufferId); + glUnmapBuffer(mBufferType); + + // create and bind the new buffer, bind the old one to a copy target (too bad that DSA is not yet supported well enough to omit this crap.) + glGenBuffers(1, &newbuffer); + glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, newbuffer); + glBindBuffer(GL_COPY_READ_BUFFER, mBufferId); + + // create the new buffer's storage (twice as large as the old one) + mBufferSize *= 2; + mByteSize *= 2; + if (gl.flags & RFL_BUFFER_STORAGE) + { + glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + } + else + { + glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW); + mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT); + } + + // copy contents and delete the old buffer. + glCopyBufferSubData(GL_COPY_READ_BUFFER, mBufferType, 0, 0, mByteSize/2); + glBindBuffer(GL_COPY_READ_BUFFER, 0); + glDeleteBuffers(1, &mBufferId); + mBufferId = newbuffer; + } + + float *copyptr; + + assert(mBufferPointer != NULL); + if (mBufferPointer == NULL) return -1; + copyptr = mBufferPointer + mIndex * 4; + + float parmcnt[] = { 0, size0, size0 + size1, size0 + size1 + size2 }; + + memcpy(©ptr[0], parmcnt, 4 * sizeof(float)); + memcpy(©ptr[4], &data.arrays[0][0], 4 * size0*sizeof(float)); + memcpy(©ptr[4 + 4*size0], &data.arrays[1][0], 4 * size1*sizeof(float)); + memcpy(©ptr[4 + 4*(size0 + size1)], &data.arrays[2][0], 4 * size2*sizeof(float)); + + unsigned int bufferindex = mIndex; + mIndex += totalsize; + draw_dlight += (totalsize-1) / 2; + return bufferindex; +} + +void FLightBuffer::Begin() +{ + if (!(gl.flags & RFL_BUFFER_STORAGE)) + { + glBindBuffer(mBufferType, mBufferId); + mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT); } } -//========================================================================== -// -// -// -//========================================================================== - -void FLightIndexBuffer::SendBuffer() +void FLightBuffer::Finish() { - glBindBuffer(GL_TEXTURE_BUFFER, mIDBuffer); - glBufferData(GL_TEXTURE_BUFFER, mBuffer.Size() * sizeof (short), &mBuffer[0], GL_STREAM_DRAW); - glBindBuffer(GL_TEXTURE_BUFFER, 0); + if (!(gl.flags & RFL_BUFFER_STORAGE)) + { + glBindBuffer(mBufferType, mBufferId); + glUnmapBuffer(mBufferType); + mBufferPointer = NULL; + } } - -//========================================================================== -// -// -// -//========================================================================== - -void FLightIndexBuffer::BindTexture(int texunit1) +int FLightBuffer::BindUBO(unsigned int index) { - glActiveTexture(texunit1); - glBindTexture(GL_TEXTURE_BUFFER, mIDTexture); - glActiveTexture(GL_TEXTURE0); + unsigned int offset = (index / mBlockAlign) * mBlockAlign; + + if (offset != mLastMappedIndex) + { + // this will only get called if a uniform buffer is used. For a shader storage buffer we only need to bind the buffer once at the start to all shader programs + mLastMappedIndex = offset; + glBindBufferRange(GL_UNIFORM_BUFFER, LIGHTBUF_BINDINGPOINT, mBufferId, offset*16, mBlockSize*16); // we go from counting vec4's to counting bytes here. + } + return (index - offset); } -#endif \ No newline at end of file diff --git a/src/gl/dynlights/gl_lightbuffer.h b/src/gl/dynlights/gl_lightbuffer.h index d0da46b98..8781ccb57 100644 --- a/src/gl/dynlights/gl_lightbuffer.h +++ b/src/gl/dynlights/gl_lightbuffer.h @@ -1,66 +1,39 @@ #ifndef __GL_LIGHTBUFFER_H #define __GL_LIGHTBUFFER_H -#if 0 -class ADynamicLight; - -const int MAX_DYNLIGHTS = 40000; // should hopefully be enough - -struct FLightRGB -{ - unsigned char R,G,B,Type; // Type is 0 for normal, 1 for additive and 2 for subtractive -}; - -struct FLightPosition -{ - float X,Z,Y,Distance; -}; +#include "tarray.h" +struct FDynLightData; class FLightBuffer { - unsigned int mIDbuf_RGB; - unsigned int mIDbuf_Position; + TArray mIndices; + unsigned int mBufferId; + float * mBufferPointer; - unsigned int mIDtex_RGB; - unsigned int mIDtex_Position; + unsigned int mBufferType; + unsigned int mIndex; + unsigned int mUploadIndex; + unsigned int mLastMappedIndex; + unsigned int mBlockAlign; + unsigned int mBlockSize; + unsigned int mBufferSize; + unsigned int mByteSize; public: + FLightBuffer(); ~FLightBuffer(); - //void MapBuffer(); - //void UnmapBuffer(); - void BindTextures(int uniloc1, int uniloc2); - //void AddLight(ADynamicLight *light, bool foggy); - void CollectLightSources(); -}; - -class FLightIndexBuffer -{ - unsigned int mIDBuffer; - unsigned int mIDTexture; - - TArray mBuffer; - -public: - - FLightIndexBuffer(); - ~FLightIndexBuffer(); - void AddLight(ADynamicLight *light); - void SendBuffer(); - void BindTexture(int loc1); - - void ClearBuffer() - { - mBuffer.Clear(); - } - - int GetLightIndex() - { - return mBuffer.Size(); - } - + void Clear(); + int UploadLights(FDynLightData &data); + void Begin(); + void Finish(); + int BindUBO(unsigned int index); + unsigned int GetBlockSize() const { return mBlockSize; } + unsigned int GetBufferType() const { return mBufferType; } + unsigned int GetIndexPtr() const { return mIndices.Size(); } + void StoreIndex(int index) { mIndices.Push(index); } + int GetIndex(int i) const { return mIndices[i]; } }; #endif -#endif \ No newline at end of file diff --git a/src/gl/hqnx_asm/hq2x_asm.cpp b/src/gl/hqnx_asm/hq2x_asm.cpp new file mode 100644 index 000000000..59d52c180 --- /dev/null +++ b/src/gl/hqnx_asm/hq2x_asm.cpp @@ -0,0 +1,2991 @@ +//hq2x filter demo program +//---------------------------------------------------------- +//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 2.1 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser General Public +//License along with this program; if not, write to the Free Software +//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "hqnx_asm.h" + +namespace HQnX_asm +{ + +extern int LUT16to32[65536*2]; +extern int RGBtoYUV[65536*2]; + +static const __int64 reg_blank = 0; +static const __int64 const3 = 0x0003000300030003; +static const __int64 const5 = 0x0005000500050005; +static const __int64 const6 = 0x0006000600060006; +static const __int64 const14 = 0x000E000E000E000E; +static const __int64 treshold = 0x0000000000300706; + +inline void Interp1(unsigned char * pc, int c1, int c2) +{ + //*((int*)pc) = (c1*3+c2)/4; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + pmullw mm1, const3 + paddw mm1, mm2 + psrlw mm1, 2 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp2(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*2+c2+c3) >> 2; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + psllw mm1, 1 + paddw mm1, mm2 + paddw mm1, mm3 + psrlw mm1, 2 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp5(unsigned char * pc, int c1, int c2) +{ + //*((int*)pc) = (c1+c2)/2; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + paddw mm1, mm2 + psrlw mm1, 1 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp6(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*5+c2*2+c3)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const5 + psllw mm2, 1 + paddw mm1, mm3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp7(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*6+c2+c3)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const6 + paddw mm2, mm3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp9(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*2+(c2+c3)*3)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + psllw mm1, 1 + paddw mm2, mm3 + pmullw mm2, const3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp10(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*14+c2+c3)/16; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const14 + paddw mm2, mm3 + paddw mm1, mm2 + psrlw mm1, 4 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +#define PIXEL00_0 *((int*)(pOut)) = c[5]; +#define PIXEL00_10 Interp1(pOut, c[5], c[1]); +#define PIXEL00_11 Interp1(pOut, c[5], c[4]); +#define PIXEL00_12 Interp1(pOut, c[5], c[2]); +#define PIXEL00_20 Interp2(pOut, c[5], c[4], c[2]); +#define PIXEL00_21 Interp2(pOut, c[5], c[1], c[2]); +#define PIXEL00_22 Interp2(pOut, c[5], c[1], c[4]); +#define PIXEL00_60 Interp6(pOut, c[5], c[2], c[4]); +#define PIXEL00_61 Interp6(pOut, c[5], c[4], c[2]); +#define PIXEL00_70 Interp7(pOut, c[5], c[4], c[2]); +#define PIXEL00_90 Interp9(pOut, c[5], c[4], c[2]); +#define PIXEL00_100 Interp10(pOut, c[5], c[4], c[2]); +#define PIXEL01_0 *((int*)(pOut+4)) = c[5]; +#define PIXEL01_10 Interp1(pOut+4, c[5], c[3]); +#define PIXEL01_11 Interp1(pOut+4, c[5], c[2]); +#define PIXEL01_12 Interp1(pOut+4, c[5], c[6]); +#define PIXEL01_20 Interp2(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_21 Interp2(pOut+4, c[5], c[3], c[6]); +#define PIXEL01_22 Interp2(pOut+4, c[5], c[3], c[2]); +#define PIXEL01_60 Interp6(pOut+4, c[5], c[6], c[2]); +#define PIXEL01_61 Interp6(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_70 Interp7(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_90 Interp9(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_100 Interp10(pOut+4, c[5], c[2], c[6]); +#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5]; +#define PIXEL10_10 Interp1(pOut+BpL, c[5], c[7]); +#define PIXEL10_11 Interp1(pOut+BpL, c[5], c[8]); +#define PIXEL10_12 Interp1(pOut+BpL, c[5], c[4]); +#define PIXEL10_20 Interp2(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_21 Interp2(pOut+BpL, c[5], c[7], c[4]); +#define PIXEL10_22 Interp2(pOut+BpL, c[5], c[7], c[8]); +#define PIXEL10_60 Interp6(pOut+BpL, c[5], c[4], c[8]); +#define PIXEL10_61 Interp6(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_70 Interp7(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_90 Interp9(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_100 Interp10(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL11_0 *((int*)(pOut+BpL+4)) = c[5]; +#define PIXEL11_10 Interp1(pOut+BpL+4, c[5], c[9]); +#define PIXEL11_11 Interp1(pOut+BpL+4, c[5], c[6]); +#define PIXEL11_12 Interp1(pOut+BpL+4, c[5], c[8]); +#define PIXEL11_20 Interp2(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_21 Interp2(pOut+BpL+4, c[5], c[9], c[8]); +#define PIXEL11_22 Interp2(pOut+BpL+4, c[5], c[9], c[6]); +#define PIXEL11_60 Interp6(pOut+BpL+4, c[5], c[8], c[6]); +#define PIXEL11_61 Interp6(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_70 Interp7(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_90 Interp9(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_100 Interp10(pOut+BpL+4, c[5], c[6], c[8]); + + +int Diff(unsigned int w5, unsigned int w1); + +void DLL hq2x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ) +{ + int i, j, k; + int w[10]; + unsigned int c[10]; + + // +----+----+----+ + // | | | | + // | w1 | w2 | w3 | + // +----+----+----+ + // | | | | + // | w4 | w5 | w6 | + // +----+----+----+ + // | | | | + // | w7 | w8 | w9 | + // +----+----+----+ + + for (j=0; j0) + { + w[1] = *(pIn - Xres - 1); + } + else + { + w[1] = 0; + } + + w[2] = *(pIn - Xres); + + if (i0) + { + w[4] = *(pIn - 1); + } + else + { + w[4] = 0; + } + + w[5] = *(pIn); + if (i0) + { + w[7] = *(pIn + Xres - 1); + } + else + { + w[7] = 0; + } + + w[8] = *(pIn + Xres); + if (i0) w[1] = *(pIn - Xres - 1); else w[1] = 0; + w[2] = *(pIn - Xres); + if (i0) w[4] = *(pIn - 1); else w[4] = 0; + w[5] = *(pIn); + if (i0) w[7] = *(pIn + Xres - 1); else w[7] = 0; + w[8] = *(pIn + Xres); + if (i +#include +#include +#include +#include "hqnx_asm.h" + +namespace HQnX_asm +{ + +int LUT16to32[65536*2]; +int RGBtoYUV[65536*2]; + +static const __int64 reg_blank = 0; +static const __int64 const3 = 0x0003000300030003; +static const __int64 const5 = 0x0005000500050005; +static const __int64 const6 = 0x0006000600060006; +static const __int64 const7 = 0x0007000700070007; +static const __int64 treshold = 0x0000000000300706; + + +inline void Interp1(unsigned char * pc, int c1, int c2) +{ + //*((int*)pc) = (c1*3+c2)/4; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + pmullw mm1, const3 + paddw mm1, mm2 + psrlw mm1, 2 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp2(unsigned char * pc, int c1, int c2, int c3) +{ +// *((int*)pc) = (c1*2+c2+c3)/4; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + psllw mm1, 1 + paddw mm1, mm2 + paddw mm1, mm3 + psrlw mm1, 2 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp3(unsigned char * pc, int c1, int c2) +{ + //*((int*)pc) = (c1*7+c2)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + pmullw mm1, const7 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp5(unsigned char * pc, int c1, int c2) +{ + //*((int*)pc) = (c1+c2)/2; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + paddw mm1, mm2 + psrlw mm1, 1 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp6(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*5+c2*2+c3)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const5 + psllw mm2, 1 + paddw mm1, mm3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp7(unsigned char * pc, int c1, int c2, int c3) +{ + //*((int*)pc) = (c1*6+c2+c3)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const6 + paddw mm2, mm3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +inline void Interp8(unsigned char * pc, int c1, int c2) +{ + //*((int*)pc) = (c1*5+c2*3)/8; + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + pmullw mm1, const5 + pmullw mm2, const3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +} + +#define PIXEL00_0 *((int*)(pOut)) = c[5]; +#define PIXEL00_11 Interp1(pOut, c[5], c[4]); +#define PIXEL00_12 Interp1(pOut, c[5], c[2]); +#define PIXEL00_20 Interp2(pOut, c[5], c[2], c[4]); +#define PIXEL00_50 Interp5(pOut, c[2], c[4]); +#define PIXEL00_80 Interp8(pOut, c[5], c[1]); +#define PIXEL00_81 Interp8(pOut, c[5], c[4]); +#define PIXEL00_82 Interp8(pOut, c[5], c[2]); +#define PIXEL01_0 *((int*)(pOut+4)) = c[5]; +#define PIXEL01_10 Interp1(pOut+4, c[5], c[1]); +#define PIXEL01_12 Interp1(pOut+4, c[5], c[2]); +#define PIXEL01_14 Interp1(pOut+4, c[2], c[5]); +#define PIXEL01_21 Interp2(pOut+4, c[2], c[5], c[4]); +#define PIXEL01_31 Interp3(pOut+4, c[5], c[4]); +#define PIXEL01_50 Interp5(pOut+4, c[2], c[5]); +#define PIXEL01_60 Interp6(pOut+4, c[5], c[2], c[4]); +#define PIXEL01_61 Interp6(pOut+4, c[5], c[2], c[1]); +#define PIXEL01_82 Interp8(pOut+4, c[5], c[2]); +#define PIXEL01_83 Interp8(pOut+4, c[2], c[4]); +#define PIXEL02_0 *((int*)(pOut+8)) = c[5]; +#define PIXEL02_10 Interp1(pOut+8, c[5], c[3]); +#define PIXEL02_11 Interp1(pOut+8, c[5], c[2]); +#define PIXEL02_13 Interp1(pOut+8, c[2], c[5]); +#define PIXEL02_21 Interp2(pOut+8, c[2], c[5], c[6]); +#define PIXEL02_32 Interp3(pOut+8, c[5], c[6]); +#define PIXEL02_50 Interp5(pOut+8, c[2], c[5]); +#define PIXEL02_60 Interp6(pOut+8, c[5], c[2], c[6]); +#define PIXEL02_61 Interp6(pOut+8, c[5], c[2], c[3]); +#define PIXEL02_81 Interp8(pOut+8, c[5], c[2]); +#define PIXEL02_83 Interp8(pOut+8, c[2], c[6]); +#define PIXEL03_0 *((int*)(pOut+12)) = c[5]; +#define PIXEL03_11 Interp1(pOut+12, c[5], c[2]); +#define PIXEL03_12 Interp1(pOut+12, c[5], c[6]); +#define PIXEL03_20 Interp2(pOut+12, c[5], c[2], c[6]); +#define PIXEL03_50 Interp5(pOut+12, c[2], c[6]); +#define PIXEL03_80 Interp8(pOut+12, c[5], c[3]); +#define PIXEL03_81 Interp8(pOut+12, c[5], c[2]); +#define PIXEL03_82 Interp8(pOut+12, c[5], c[6]); +#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5]; +#define PIXEL10_10 Interp1(pOut+BpL, c[5], c[1]); +#define PIXEL10_11 Interp1(pOut+BpL, c[5], c[4]); +#define PIXEL10_13 Interp1(pOut+BpL, c[4], c[5]); +#define PIXEL10_21 Interp2(pOut+BpL, c[4], c[5], c[2]); +#define PIXEL10_32 Interp3(pOut+BpL, c[5], c[2]); +#define PIXEL10_50 Interp5(pOut+BpL, c[4], c[5]); +#define PIXEL10_60 Interp6(pOut+BpL, c[5], c[4], c[2]); +#define PIXEL10_61 Interp6(pOut+BpL, c[5], c[4], c[1]); +#define PIXEL10_81 Interp8(pOut+BpL, c[5], c[4]); +#define PIXEL10_83 Interp8(pOut+BpL, c[4], c[2]); +#define PIXEL11_0 *((int*)(pOut+BpL+4)) = c[5]; +#define PIXEL11_30 Interp3(pOut+BpL+4, c[5], c[1]); +#define PIXEL11_31 Interp3(pOut+BpL+4, c[5], c[4]); +#define PIXEL11_32 Interp3(pOut+BpL+4, c[5], c[2]); +#define PIXEL11_70 Interp7(pOut+BpL+4, c[5], c[4], c[2]); +#define PIXEL12_0 *((int*)(pOut+BpL+8)) = c[5]; +#define PIXEL12_30 Interp3(pOut+BpL+8, c[5], c[3]); +#define PIXEL12_31 Interp3(pOut+BpL+8, c[5], c[2]); +#define PIXEL12_32 Interp3(pOut+BpL+8, c[5], c[6]); +#define PIXEL12_70 Interp7(pOut+BpL+8, c[5], c[6], c[2]); +#define PIXEL13_0 *((int*)(pOut+BpL+12)) = c[5]; +#define PIXEL13_10 Interp1(pOut+BpL+12, c[5], c[3]); +#define PIXEL13_12 Interp1(pOut+BpL+12, c[5], c[6]); +#define PIXEL13_14 Interp1(pOut+BpL+12, c[6], c[5]); +#define PIXEL13_21 Interp2(pOut+BpL+12, c[6], c[5], c[2]); +#define PIXEL13_31 Interp3(pOut+BpL+12, c[5], c[2]); +#define PIXEL13_50 Interp5(pOut+BpL+12, c[6], c[5]); +#define PIXEL13_60 Interp6(pOut+BpL+12, c[5], c[6], c[2]); +#define PIXEL13_61 Interp6(pOut+BpL+12, c[5], c[6], c[3]); +#define PIXEL13_82 Interp8(pOut+BpL+12, c[5], c[6]); +#define PIXEL13_83 Interp8(pOut+BpL+12, c[6], c[2]); +#define PIXEL20_0 *((int*)(pOut+BpL+BpL)) = c[5]; +#define PIXEL20_10 Interp1(pOut+BpL+BpL, c[5], c[7]); +#define PIXEL20_12 Interp1(pOut+BpL+BpL, c[5], c[4]); +#define PIXEL20_14 Interp1(pOut+BpL+BpL, c[4], c[5]); +#define PIXEL20_21 Interp2(pOut+BpL+BpL, c[4], c[5], c[8]); +#define PIXEL20_31 Interp3(pOut+BpL+BpL, c[5], c[8]); +#define PIXEL20_50 Interp5(pOut+BpL+BpL, c[4], c[5]); +#define PIXEL20_60 Interp6(pOut+BpL+BpL, c[5], c[4], c[8]); +#define PIXEL20_61 Interp6(pOut+BpL+BpL, c[5], c[4], c[7]); +#define PIXEL20_82 Interp8(pOut+BpL+BpL, c[5], c[4]); +#define PIXEL20_83 Interp8(pOut+BpL+BpL, c[4], c[8]); +#define PIXEL21_0 *((int*)(pOut+BpL+BpL+4)) = c[5]; +#define PIXEL21_30 Interp3(pOut+BpL+BpL+4, c[5], c[7]); +#define PIXEL21_31 Interp3(pOut+BpL+BpL+4, c[5], c[8]); +#define PIXEL21_32 Interp3(pOut+BpL+BpL+4, c[5], c[4]); +#define PIXEL21_70 Interp7(pOut+BpL+BpL+4, c[5], c[4], c[8]); +#define PIXEL22_0 *((int*)(pOut+BpL+BpL+8)) = c[5]; +#define PIXEL22_30 Interp3(pOut+BpL+BpL+8, c[5], c[9]); +#define PIXEL22_31 Interp3(pOut+BpL+BpL+8, c[5], c[6]); +#define PIXEL22_32 Interp3(pOut+BpL+BpL+8, c[5], c[8]); +#define PIXEL22_70 Interp7(pOut+BpL+BpL+8, c[5], c[6], c[8]); +#define PIXEL23_0 *((int*)(pOut+BpL+BpL+12)) = c[5]; +#define PIXEL23_10 Interp1(pOut+BpL+BpL+12, c[5], c[9]); +#define PIXEL23_11 Interp1(pOut+BpL+BpL+12, c[5], c[6]); +#define PIXEL23_13 Interp1(pOut+BpL+BpL+12, c[6], c[5]); +#define PIXEL23_21 Interp2(pOut+BpL+BpL+12, c[6], c[5], c[8]); +#define PIXEL23_32 Interp3(pOut+BpL+BpL+12, c[5], c[8]); +#define PIXEL23_50 Interp5(pOut+BpL+BpL+12, c[6], c[5]); +#define PIXEL23_60 Interp6(pOut+BpL+BpL+12, c[5], c[6], c[8]); +#define PIXEL23_61 Interp6(pOut+BpL+BpL+12, c[5], c[6], c[9]); +#define PIXEL23_81 Interp8(pOut+BpL+BpL+12, c[5], c[6]); +#define PIXEL23_83 Interp8(pOut+BpL+BpL+12, c[6], c[8]); +#define PIXEL30_0 *((int*)(pOut+BpL+BpL+BpL)) = c[5]; +#define PIXEL30_11 Interp1(pOut+BpL+BpL+BpL, c[5], c[8]); +#define PIXEL30_12 Interp1(pOut+BpL+BpL+BpL, c[5], c[4]); +#define PIXEL30_20 Interp2(pOut+BpL+BpL+BpL, c[5], c[8], c[4]); +#define PIXEL30_50 Interp5(pOut+BpL+BpL+BpL, c[8], c[4]); +#define PIXEL30_80 Interp8(pOut+BpL+BpL+BpL, c[5], c[7]); +#define PIXEL30_81 Interp8(pOut+BpL+BpL+BpL, c[5], c[8]); +#define PIXEL30_82 Interp8(pOut+BpL+BpL+BpL, c[5], c[4]); +#define PIXEL31_0 *((int*)(pOut+BpL+BpL+BpL+4)) = c[5]; +#define PIXEL31_10 Interp1(pOut+BpL+BpL+BpL+4, c[5], c[7]); +#define PIXEL31_11 Interp1(pOut+BpL+BpL+BpL+4, c[5], c[8]); +#define PIXEL31_13 Interp1(pOut+BpL+BpL+BpL+4, c[8], c[5]); +#define PIXEL31_21 Interp2(pOut+BpL+BpL+BpL+4, c[8], c[5], c[4]); +#define PIXEL31_32 Interp3(pOut+BpL+BpL+BpL+4, c[5], c[4]); +#define PIXEL31_50 Interp5(pOut+BpL+BpL+BpL+4, c[8], c[5]); +#define PIXEL31_60 Interp6(pOut+BpL+BpL+BpL+4, c[5], c[8], c[4]); +#define PIXEL31_61 Interp6(pOut+BpL+BpL+BpL+4, c[5], c[8], c[7]); +#define PIXEL31_81 Interp8(pOut+BpL+BpL+BpL+4, c[5], c[8]); +#define PIXEL31_83 Interp8(pOut+BpL+BpL+BpL+4, c[8], c[4]); +#define PIXEL32_0 *((int*)(pOut+BpL+BpL+BpL+8)) = c[5]; +#define PIXEL32_10 Interp1(pOut+BpL+BpL+BpL+8, c[5], c[9]); +#define PIXEL32_12 Interp1(pOut+BpL+BpL+BpL+8, c[5], c[8]); +#define PIXEL32_14 Interp1(pOut+BpL+BpL+BpL+8, c[8], c[5]); +#define PIXEL32_21 Interp2(pOut+BpL+BpL+BpL+8, c[8], c[5], c[6]); +#define PIXEL32_31 Interp3(pOut+BpL+BpL+BpL+8, c[5], c[6]); +#define PIXEL32_50 Interp5(pOut+BpL+BpL+BpL+8, c[8], c[5]); +#define PIXEL32_60 Interp6(pOut+BpL+BpL+BpL+8, c[5], c[8], c[6]); +#define PIXEL32_61 Interp6(pOut+BpL+BpL+BpL+8, c[5], c[8], c[9]); +#define PIXEL32_82 Interp8(pOut+BpL+BpL+BpL+8, c[5], c[8]); +#define PIXEL32_83 Interp8(pOut+BpL+BpL+BpL+8, c[8], c[6]); +#define PIXEL33_0 *((int*)(pOut+BpL+BpL+BpL+12)) = c[5]; +#define PIXEL33_11 Interp1(pOut+BpL+BpL+BpL+12, c[5], c[6]); +#define PIXEL33_12 Interp1(pOut+BpL+BpL+BpL+12, c[5], c[8]); +#define PIXEL33_20 Interp2(pOut+BpL+BpL+BpL+12, c[5], c[8], c[6]); +#define PIXEL33_50 Interp5(pOut+BpL+BpL+BpL+12, c[8], c[6]); +#define PIXEL33_80 Interp8(pOut+BpL+BpL+BpL+12, c[5], c[9]); +#define PIXEL33_81 Interp8(pOut+BpL+BpL+BpL+12, c[5], c[6]); +#define PIXEL33_82 Interp8(pOut+BpL+BpL+BpL+12, c[5], c[8]); + + +#pragma warning(disable: 4035) + +int Diff(unsigned int w5, unsigned int w1) +{ + __asm + { + xor eax,eax + mov ebx,w5 + mov edx,w1 + cmp ebx,edx + je FIN + mov ecx,offset RGBtoYUV + movd mm1,[ecx + ebx*4] + movq mm5,mm1 + movd mm2,[ecx + edx*4] + psubusb mm1,mm2 + psubusb mm2,mm5 + por mm1,mm2 + psubusb mm1,treshold + movd eax,mm1 +FIN: + } +} +// returns result in eax register + +#pragma warning(default: 4035) + +void DLL hq4x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ) +{ + int i, j, k; + int w[10]; + int c[10]; + + // +----+----+----+ + // | | | | + // | w1 | w2 | w3 | + // +----+----+----+ + // | | | | + // | w4 | w5 | w6 | + // +----+----+----+ + // | | | | + // | w7 | w8 | w9 | + // +----+----+----+ + + for (j = 0; j < Yres; j++) + { + for (i = 0; i < Xres; i++) + { + if (j == 0) + { + w[1] = 0; + w[2] = 0; + w[3] = 0; + } + else + { + if (i > 0) + w[1] = *(pIn - Xres - 1); + else + w[1] = 0; + + w[2] = *(pIn - Xres); + + if (i < Xres - 1) + w[3] = *(pIn - Xres + 1); + else + w[3] = 0; + } + + if (i > 0) + w[4] = *(pIn - 1); + else + w[4] = 0; + + w[5] = *(pIn); + + if (i < Xres - 1) + w[6] = *(pIn + 1); + else + w[6] = 0; + + if (j == Yres - 1) + { + w[7] = 0; + w[8] = 0; + w[9] = 0; + } + else + { + if (i > 0) + w[7] = *(pIn + Xres - 1); + else + w[7] = 0; + + w[8] = *(pIn + Xres); + + if (i < Xres-1) + w[9] = *(pIn + Xres + 1); + else + w[9] = 0; + } + + int pattern = 0; + + if ( Diff(w[5],w[1]) ) pattern |= 0x0001; + if ( Diff(w[5],w[2]) ) pattern |= 0x0002; + if ( Diff(w[5],w[3]) ) pattern |= 0x0004; + if ( Diff(w[5],w[4]) ) pattern |= 0x0008; + if ( Diff(w[5],w[6]) ) pattern |= 0x0010; + if ( Diff(w[5],w[7]) ) pattern |= 0x0020; + if ( Diff(w[5],w[8]) ) pattern |= 0x0040; + if ( Diff(w[5],w[9]) ) pattern |= 0x0080; + + for (k=1; k<=9; k++) + c[k] = LUT16to32[w[k]]; + + switch (pattern) + { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_60 + PIXEL03_20 + PIXEL10_60 + PIXEL11_70 + PIXEL12_70 + PIXEL13_60 + PIXEL20_60 + PIXEL21_70 + PIXEL22_70 + PIXEL23_60 + PIXEL30_20 + PIXEL31_60 + PIXEL32_60 + PIXEL33_20 + break; + } + case 2: + case 34: + case 130: + case 162: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_61 + PIXEL11_30 + PIXEL12_30 + PIXEL13_61 + PIXEL20_60 + PIXEL21_70 + PIXEL22_70 + PIXEL23_60 + PIXEL30_20 + PIXEL31_60 + PIXEL32_60 + PIXEL33_20 + break; + } + case 16: + case 17: + case 48: + case 49: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_61 + PIXEL03_80 + PIXEL10_60 + PIXEL11_70 + PIXEL12_30 + PIXEL13_10 + PIXEL20_60 + PIXEL21_70 + PIXEL22_30 + PIXEL23_10 + PIXEL30_20 + PIXEL31_60 + PIXEL32_61 + PIXEL33_80 + break; + } + case 64: + case 65: + case 68: + case 69: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_60 + PIXEL03_20 + PIXEL10_60 + PIXEL11_70 + PIXEL12_70 + PIXEL13_60 + PIXEL20_61 + PIXEL21_30 + PIXEL22_30 + PIXEL23_61 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 8: + case 12: + case 136: + case 140: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_60 + PIXEL03_20 + PIXEL10_10 + PIXEL11_30 + PIXEL12_70 + PIXEL13_60 + PIXEL20_10 + PIXEL21_30 + PIXEL22_70 + PIXEL23_60 + PIXEL30_80 + PIXEL31_61 + PIXEL32_60 + PIXEL33_20 + break; + } + case 3: + case 35: + case 131: + case 163: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_61 + PIXEL20_60 + PIXEL21_70 + PIXEL22_70 + PIXEL23_60 + PIXEL30_20 + PIXEL31_60 + PIXEL32_60 + PIXEL33_20 + break; + } + case 6: + case 38: + case 134: + case 166: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_61 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + PIXEL20_60 + PIXEL21_70 + PIXEL22_70 + PIXEL23_60 + PIXEL30_20 + PIXEL31_60 + PIXEL32_60 + PIXEL33_20 + break; + } + case 20: + case 21: + case 52: + case 53: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + PIXEL03_81 + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL13_31 + PIXEL20_60 + PIXEL21_70 + PIXEL22_30 + PIXEL23_10 + PIXEL30_20 + PIXEL31_60 + PIXEL32_61 + PIXEL33_80 + break; + } + case 144: + case 145: + case 176: + case 177: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_61 + PIXEL03_80 + PIXEL10_60 + PIXEL11_70 + PIXEL12_30 + PIXEL13_10 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL23_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + PIXEL33_82 + break; + } + case 192: + case 193: + case 196: + case 197: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_60 + PIXEL03_20 + PIXEL10_60 + PIXEL11_70 + PIXEL12_70 + PIXEL13_60 + PIXEL20_61 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 96: + case 97: + case 100: + case 101: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_60 + PIXEL03_20 + PIXEL10_60 + PIXEL11_70 + PIXEL12_70 + PIXEL13_60 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_61 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 40: + case 44: + case 168: + case 172: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_60 + PIXEL03_20 + PIXEL10_10 + PIXEL11_30 + PIXEL12_70 + PIXEL13_60 + PIXEL20_31 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL30_81 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 9: + case 13: + case 137: + case 141: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL10_32 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + PIXEL20_10 + PIXEL21_30 + PIXEL22_70 + PIXEL23_60 + PIXEL30_80 + PIXEL31_61 + PIXEL32_60 + PIXEL33_20 + break; + } + case 18: + case 50: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL12_0 + PIXEL13_50 + } + PIXEL10_61 + PIXEL11_30 + PIXEL20_60 + PIXEL21_70 + PIXEL22_30 + PIXEL23_10 + PIXEL30_20 + PIXEL31_60 + PIXEL32_61 + PIXEL33_80 + break; + } + case 80: + case 81: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_61 + PIXEL03_80 + PIXEL10_60 + PIXEL11_70 + PIXEL12_30 + PIXEL13_10 + PIXEL20_61 + PIXEL21_30 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 72: + case 76: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_60 + PIXEL03_20 + PIXEL10_10 + PIXEL11_30 + PIXEL12_70 + PIXEL13_60 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_50 + PIXEL21_0 + PIXEL30_50 + PIXEL31_50 + } + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 10: + case 138: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + PIXEL11_0 + } + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_61 + PIXEL20_10 + PIXEL21_30 + PIXEL22_70 + PIXEL23_60 + PIXEL30_80 + PIXEL31_61 + PIXEL32_60 + PIXEL33_20 + break; + } + case 66: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_61 + PIXEL11_30 + PIXEL12_30 + PIXEL13_61 + PIXEL20_61 + PIXEL21_30 + PIXEL22_30 + PIXEL23_61 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 24: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 7: + case 39: + case 135: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_32 + PIXEL03_82 + PIXEL10_81 + PIXEL11_31 + PIXEL12_32 + PIXEL13_82 + PIXEL20_60 + PIXEL21_70 + PIXEL22_70 + PIXEL23_60 + PIXEL30_20 + PIXEL31_60 + PIXEL32_60 + PIXEL33_20 + break; + } + case 148: + case 149: + case 180: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + PIXEL03_81 + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL13_31 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL23_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + PIXEL33_82 + break; + } + case 224: + case 228: + case 225: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_60 + PIXEL03_20 + PIXEL10_60 + PIXEL11_70 + PIXEL12_70 + PIXEL13_60 + PIXEL20_82 + PIXEL21_32 + PIXEL22_31 + PIXEL23_81 + PIXEL30_82 + PIXEL31_32 + PIXEL32_31 + PIXEL33_81 + break; + } + case 41: + case 169: + case 45: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL10_32 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + PIXEL20_31 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL30_81 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 22: + case 54: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_61 + PIXEL11_30 + PIXEL12_0 + PIXEL20_60 + PIXEL21_70 + PIXEL22_30 + PIXEL23_10 + PIXEL30_20 + PIXEL31_60 + PIXEL32_61 + PIXEL33_80 + break; + } + case 208: + case 209: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_61 + PIXEL03_80 + PIXEL10_60 + PIXEL11_70 + PIXEL12_30 + PIXEL13_10 + PIXEL20_61 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 104: + case 108: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_60 + PIXEL03_20 + PIXEL10_10 + PIXEL11_30 + PIXEL12_70 + PIXEL13_60 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 11: + case 139: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_61 + PIXEL20_10 + PIXEL21_30 + PIXEL22_70 + PIXEL23_60 + PIXEL30_80 + PIXEL31_61 + PIXEL32_60 + PIXEL33_20 + break; + } + case 19: + case 51: + { + if (Diff(w[2], w[6])) + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL00_12 + PIXEL01_14 + PIXEL02_83 + PIXEL03_50 + PIXEL12_70 + PIXEL13_21 + } + PIXEL10_81 + PIXEL11_31 + PIXEL20_60 + PIXEL21_70 + PIXEL22_30 + PIXEL23_10 + PIXEL30_20 + PIXEL31_60 + PIXEL32_61 + PIXEL33_80 + break; + } + case 146: + case 178: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + PIXEL23_32 + PIXEL33_82 + } + else + { + PIXEL02_21 + PIXEL03_50 + PIXEL12_70 + PIXEL13_83 + PIXEL23_13 + PIXEL33_11 + } + PIXEL10_61 + PIXEL11_30 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + break; + } + case 84: + case 85: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + if (Diff(w[6], w[8])) + { + PIXEL03_81 + PIXEL13_31 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL03_12 + PIXEL13_14 + PIXEL22_70 + PIXEL23_83 + PIXEL32_21 + PIXEL33_50 + } + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL20_61 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + break; + } + case 112: + case 113: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_61 + PIXEL03_80 + PIXEL10_60 + PIXEL11_70 + PIXEL12_30 + PIXEL13_10 + PIXEL20_82 + PIXEL21_32 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_70 + PIXEL23_21 + PIXEL30_11 + PIXEL31_13 + PIXEL32_83 + PIXEL33_50 + } + break; + } + case 200: + case 204: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_60 + PIXEL03_20 + PIXEL10_10 + PIXEL11_30 + PIXEL12_70 + PIXEL13_60 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + } + else + { + PIXEL20_21 + PIXEL21_70 + PIXEL30_50 + PIXEL31_83 + PIXEL32_14 + PIXEL33_12 + } + PIXEL22_31 + PIXEL23_81 + break; + } + case 73: + case 77: + { + if (Diff(w[8], w[4])) + { + PIXEL00_82 + PIXEL10_32 + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL00_11 + PIXEL10_13 + PIXEL20_83 + PIXEL21_70 + PIXEL30_50 + PIXEL31_21 + } + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 42: + case 170: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + PIXEL20_31 + PIXEL30_81 + } + else + { + PIXEL00_50 + PIXEL01_21 + PIXEL10_83 + PIXEL11_70 + PIXEL20_14 + PIXEL30_12 + } + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_61 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 14: + case 142: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_50 + PIXEL01_83 + PIXEL02_13 + PIXEL03_11 + PIXEL10_21 + PIXEL11_70 + } + PIXEL12_32 + PIXEL13_82 + PIXEL20_10 + PIXEL21_30 + PIXEL22_70 + PIXEL23_60 + PIXEL30_80 + PIXEL31_61 + PIXEL32_60 + PIXEL33_20 + break; + } + case 67: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_61 + PIXEL20_61 + PIXEL21_30 + PIXEL22_30 + PIXEL23_61 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 70: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_61 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + PIXEL20_61 + PIXEL21_30 + PIXEL22_30 + PIXEL23_61 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 28: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 152: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 194: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_61 + PIXEL11_30 + PIXEL12_30 + PIXEL13_61 + PIXEL20_61 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 98: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_61 + PIXEL11_30 + PIXEL12_30 + PIXEL13_61 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_61 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 56: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 25: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 26: + case 31: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL11_0 + PIXEL12_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 82: + case 214: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_61 + PIXEL11_30 + PIXEL12_0 + PIXEL20_61 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 88: + case 248: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + break; + } + case 74: + case 107: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_61 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 27: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 86: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_61 + PIXEL11_30 + PIXEL12_0 + PIXEL20_61 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 216: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 106: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_61 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 30: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_10 + PIXEL11_30 + PIXEL12_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 210: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_61 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + PIXEL20_61 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 120: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 75: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_61 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_61 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 29: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_61 + PIXEL32_61 + PIXEL33_80 + break; + } + case 198: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_61 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + PIXEL20_61 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 184: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_61 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 99: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_61 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_61 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 57: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 71: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_32 + PIXEL03_82 + PIXEL10_81 + PIXEL11_31 + PIXEL12_32 + PIXEL13_82 + PIXEL20_61 + PIXEL21_30 + PIXEL22_30 + PIXEL23_61 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 156: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 226: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_61 + PIXEL11_30 + PIXEL12_30 + PIXEL13_61 + PIXEL20_82 + PIXEL21_32 + PIXEL22_31 + PIXEL23_81 + PIXEL30_82 + PIXEL31_32 + PIXEL32_31 + PIXEL33_81 + break; + } + case 60: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 195: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_61 + PIXEL20_61 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 102: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_61 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_61 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 153: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 58: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 83: + { + PIXEL00_81 + PIXEL01_31 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL10_81 + PIXEL11_31 + PIXEL20_61 + PIXEL21_30 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 92: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 202: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_61 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_31 + PIXEL23_81 + PIXEL32_31 + PIXEL33_81 + break; + } + case 78: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + PIXEL02_32 + PIXEL03_82 + PIXEL12_32 + PIXEL13_82 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 154: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 114: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL10_61 + PIXEL11_30 + PIXEL20_82 + PIXEL21_32 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + PIXEL30_82 + PIXEL31_32 + break; + } + case 89: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 90: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 55: + case 23: + { + if (Diff(w[2], w[6])) + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_0 + PIXEL03_0 + PIXEL12_0 + PIXEL13_0 + } + else + { + PIXEL00_12 + PIXEL01_14 + PIXEL02_83 + PIXEL03_50 + PIXEL12_70 + PIXEL13_21 + } + PIXEL10_81 + PIXEL11_31 + PIXEL20_60 + PIXEL21_70 + PIXEL22_30 + PIXEL23_10 + PIXEL30_20 + PIXEL31_60 + PIXEL32_61 + PIXEL33_80 + break; + } + case 182: + case 150: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL12_0 + PIXEL13_0 + PIXEL23_32 + PIXEL33_82 + } + else + { + PIXEL02_21 + PIXEL03_50 + PIXEL12_70 + PIXEL13_83 + PIXEL23_13 + PIXEL33_11 + } + PIXEL10_61 + PIXEL11_30 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + break; + } + case 213: + case 212: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + if (Diff(w[6], w[8])) + { + PIXEL03_81 + PIXEL13_31 + PIXEL22_0 + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL03_12 + PIXEL13_14 + PIXEL22_70 + PIXEL23_83 + PIXEL32_21 + PIXEL33_50 + } + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL20_61 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + break; + } + case 241: + case 240: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_61 + PIXEL03_80 + PIXEL10_60 + PIXEL11_70 + PIXEL12_30 + PIXEL13_10 + PIXEL20_82 + PIXEL21_32 + if (Diff(w[6], w[8])) + { + PIXEL22_0 + PIXEL23_0 + PIXEL30_82 + PIXEL31_32 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL22_70 + PIXEL23_21 + PIXEL30_11 + PIXEL31_13 + PIXEL32_83 + PIXEL33_50 + } + break; + } + case 236: + case 232: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_60 + PIXEL03_20 + PIXEL10_10 + PIXEL11_30 + PIXEL12_70 + PIXEL13_60 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL21_0 + PIXEL30_0 + PIXEL31_0 + PIXEL32_31 + PIXEL33_81 + } + else + { + PIXEL20_21 + PIXEL21_70 + PIXEL30_50 + PIXEL31_83 + PIXEL32_14 + PIXEL33_12 + } + PIXEL22_31 + PIXEL23_81 + break; + } + case 109: + case 105: + { + if (Diff(w[8], w[4])) + { + PIXEL00_82 + PIXEL10_32 + PIXEL20_0 + PIXEL21_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL00_11 + PIXEL10_13 + PIXEL20_83 + PIXEL21_70 + PIXEL30_50 + PIXEL31_21 + } + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 171: + case 43: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + PIXEL11_0 + PIXEL20_31 + PIXEL30_81 + } + else + { + PIXEL00_50 + PIXEL01_21 + PIXEL10_83 + PIXEL11_70 + PIXEL20_14 + PIXEL30_12 + } + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_61 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 143: + case 15: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL02_32 + PIXEL03_82 + PIXEL10_0 + PIXEL11_0 + } + else + { + PIXEL00_50 + PIXEL01_83 + PIXEL02_13 + PIXEL03_11 + PIXEL10_21 + PIXEL11_70 + } + PIXEL12_32 + PIXEL13_82 + PIXEL20_10 + PIXEL21_30 + PIXEL22_70 + PIXEL23_60 + PIXEL30_80 + PIXEL31_61 + PIXEL32_60 + PIXEL33_20 + break; + } + case 124: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 203: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_61 + PIXEL20_10 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 62: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_10 + PIXEL11_30 + PIXEL12_0 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 211: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_10 + PIXEL20_61 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 118: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_61 + PIXEL11_30 + PIXEL12_0 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_10 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 217: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 110: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_10 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 155: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 188: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 185: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 61: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 157: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 103: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_32 + PIXEL03_82 + PIXEL10_81 + PIXEL11_31 + PIXEL12_32 + PIXEL13_82 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_61 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 227: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_61 + PIXEL20_82 + PIXEL21_32 + PIXEL22_31 + PIXEL23_81 + PIXEL30_82 + PIXEL31_32 + PIXEL32_31 + PIXEL33_81 + break; + } + case 230: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_61 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + PIXEL20_82 + PIXEL21_32 + PIXEL22_31 + PIXEL23_81 + PIXEL30_82 + PIXEL31_32 + PIXEL32_31 + PIXEL33_81 + break; + } + case 199: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_32 + PIXEL03_82 + PIXEL10_81 + PIXEL11_31 + PIXEL12_32 + PIXEL13_82 + PIXEL20_61 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 220: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + break; + } + case 158: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL12_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 234: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_61 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_31 + PIXEL23_81 + PIXEL32_31 + PIXEL33_81 + break; + } + case 242: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL10_61 + PIXEL11_30 + PIXEL20_82 + PIXEL21_32 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_82 + PIXEL31_32 + break; + } + case 59: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL11_0 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 121: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 87: + { + PIXEL00_81 + PIXEL01_31 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_81 + PIXEL11_31 + PIXEL12_0 + PIXEL20_61 + PIXEL21_30 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 79: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_32 + PIXEL03_82 + PIXEL11_0 + PIXEL12_32 + PIXEL13_82 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 122: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 94: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL12_0 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 218: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + break; + } + case 91: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL11_0 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 229: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_60 + PIXEL03_20 + PIXEL10_60 + PIXEL11_70 + PIXEL12_70 + PIXEL13_60 + PIXEL20_82 + PIXEL21_32 + PIXEL22_31 + PIXEL23_81 + PIXEL30_82 + PIXEL31_32 + PIXEL32_31 + PIXEL33_81 + break; + } + case 167: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_32 + PIXEL03_82 + PIXEL10_81 + PIXEL11_31 + PIXEL12_32 + PIXEL13_82 + PIXEL20_60 + PIXEL21_70 + PIXEL22_70 + PIXEL23_60 + PIXEL30_20 + PIXEL31_60 + PIXEL32_60 + PIXEL33_20 + break; + } + case 173: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL10_32 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + PIXEL20_31 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL30_81 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 181: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + PIXEL03_81 + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL13_31 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL23_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + PIXEL33_82 + break; + } + case 186: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 115: + { + PIXEL00_81 + PIXEL01_31 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL10_81 + PIXEL11_31 + PIXEL20_82 + PIXEL21_32 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + PIXEL30_82 + PIXEL31_32 + break; + } + case 93: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + break; + } + case 206: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + PIXEL02_32 + PIXEL03_82 + PIXEL12_32 + PIXEL13_82 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_31 + PIXEL23_81 + PIXEL32_31 + PIXEL33_81 + break; + } + case 205: + case 201: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL10_32 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + if (Diff(w[8], w[4])) + { + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + } + else + { + PIXEL20_12 + PIXEL21_0 + PIXEL30_20 + PIXEL31_11 + } + PIXEL22_31 + PIXEL23_81 + PIXEL32_31 + PIXEL33_81 + break; + } + case 174: + case 46: + { + if (Diff(w[4], w[2])) + { + PIXEL00_80 + PIXEL01_10 + PIXEL10_10 + PIXEL11_30 + } + else + { + PIXEL00_20 + PIXEL01_12 + PIXEL10_11 + PIXEL11_0 + } + PIXEL02_32 + PIXEL03_82 + PIXEL12_32 + PIXEL13_82 + PIXEL20_31 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL30_81 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 179: + case 147: + { + PIXEL00_81 + PIXEL01_31 + if (Diff(w[2], w[6])) + { + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + } + else + { + PIXEL02_11 + PIXEL03_20 + PIXEL12_0 + PIXEL13_12 + } + PIXEL10_81 + PIXEL11_31 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL23_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + PIXEL33_82 + break; + } + case 117: + case 116: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + PIXEL03_81 + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL13_31 + PIXEL20_82 + PIXEL21_32 + if (Diff(w[6], w[8])) + { + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + } + else + { + PIXEL22_0 + PIXEL23_11 + PIXEL32_12 + PIXEL33_20 + } + PIXEL30_82 + PIXEL31_32 + break; + } + case 189: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 231: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_32 + PIXEL03_82 + PIXEL10_81 + PIXEL11_31 + PIXEL12_32 + PIXEL13_82 + PIXEL20_82 + PIXEL21_32 + PIXEL22_31 + PIXEL23_81 + PIXEL30_82 + PIXEL31_32 + PIXEL32_31 + PIXEL33_81 + break; + } + case 126: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_10 + PIXEL11_30 + PIXEL12_0 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 219: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_10 + PIXEL20_10 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 125: + { + if (Diff(w[8], w[4])) + { + PIXEL00_82 + PIXEL10_32 + PIXEL20_0 + PIXEL21_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL00_11 + PIXEL10_13 + PIXEL20_83 + PIXEL21_70 + PIXEL30_50 + PIXEL31_21 + } + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 221: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + if (Diff(w[6], w[8])) + { + PIXEL03_81 + PIXEL13_31 + PIXEL22_0 + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL03_12 + PIXEL13_14 + PIXEL22_70 + PIXEL23_83 + PIXEL32_21 + PIXEL33_50 + } + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL20_10 + PIXEL21_30 + PIXEL30_80 + PIXEL31_10 + break; + } + case 207: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL02_32 + PIXEL03_82 + PIXEL10_0 + PIXEL11_0 + } + else + { + PIXEL00_50 + PIXEL01_83 + PIXEL02_13 + PIXEL03_11 + PIXEL10_21 + PIXEL11_70 + } + PIXEL12_32 + PIXEL13_82 + PIXEL20_10 + PIXEL21_30 + PIXEL22_31 + PIXEL23_81 + PIXEL30_80 + PIXEL31_10 + PIXEL32_31 + PIXEL33_81 + break; + } + case 238: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_32 + PIXEL03_82 + PIXEL10_10 + PIXEL11_30 + PIXEL12_32 + PIXEL13_82 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL21_0 + PIXEL30_0 + PIXEL31_0 + PIXEL32_31 + PIXEL33_81 + } + else + { + PIXEL20_21 + PIXEL21_70 + PIXEL30_50 + PIXEL31_83 + PIXEL32_14 + PIXEL33_12 + } + PIXEL22_31 + PIXEL23_81 + break; + } + case 190: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL12_0 + PIXEL13_0 + PIXEL23_32 + PIXEL33_82 + } + else + { + PIXEL02_21 + PIXEL03_50 + PIXEL12_70 + PIXEL13_83 + PIXEL23_13 + PIXEL33_11 + } + PIXEL10_10 + PIXEL11_30 + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + break; + } + case 187: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + PIXEL11_0 + PIXEL20_31 + PIXEL30_81 + } + else + { + PIXEL00_50 + PIXEL01_21 + PIXEL10_83 + PIXEL11_70 + PIXEL20_14 + PIXEL30_12 + } + PIXEL02_10 + PIXEL03_80 + PIXEL12_30 + PIXEL13_10 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 243: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_10 + PIXEL03_80 + PIXEL10_81 + PIXEL11_31 + PIXEL12_30 + PIXEL13_10 + PIXEL20_82 + PIXEL21_32 + if (Diff(w[6], w[8])) + { + PIXEL22_0 + PIXEL23_0 + PIXEL30_82 + PIXEL31_32 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL22_70 + PIXEL23_21 + PIXEL30_11 + PIXEL31_13 + PIXEL32_83 + PIXEL33_50 + } + break; + } + case 119: + { + if (Diff(w[2], w[6])) + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_0 + PIXEL03_0 + PIXEL12_0 + PIXEL13_0 + } + else + { + PIXEL00_12 + PIXEL01_14 + PIXEL02_83 + PIXEL03_50 + PIXEL12_70 + PIXEL13_21 + } + PIXEL10_81 + PIXEL11_31 + PIXEL20_82 + PIXEL21_32 + PIXEL22_30 + PIXEL23_10 + PIXEL30_82 + PIXEL31_32 + PIXEL32_10 + PIXEL33_80 + break; + } + case 237: + case 233: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_60 + PIXEL03_20 + PIXEL10_32 + PIXEL11_32 + PIXEL12_70 + PIXEL13_60 + PIXEL20_0 + PIXEL21_0 + PIXEL22_31 + PIXEL23_81 + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + PIXEL32_31 + PIXEL33_81 + break; + } + case 175: + case 47: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + PIXEL02_32 + PIXEL03_82 + PIXEL10_0 + PIXEL11_0 + PIXEL12_32 + PIXEL13_82 + PIXEL20_31 + PIXEL21_31 + PIXEL22_70 + PIXEL23_60 + PIXEL30_81 + PIXEL31_81 + PIXEL32_60 + PIXEL33_20 + break; + } + case 183: + case 151: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL10_81 + PIXEL11_31 + PIXEL12_0 + PIXEL13_0 + PIXEL20_60 + PIXEL21_70 + PIXEL22_32 + PIXEL23_32 + PIXEL30_20 + PIXEL31_60 + PIXEL32_82 + PIXEL33_82 + break; + } + case 245: + case 244: + { + PIXEL00_20 + PIXEL01_60 + PIXEL02_81 + PIXEL03_81 + PIXEL10_60 + PIXEL11_70 + PIXEL12_31 + PIXEL13_31 + PIXEL20_82 + PIXEL21_32 + PIXEL22_0 + PIXEL23_0 + PIXEL30_82 + PIXEL31_32 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + case 250: + { + PIXEL00_80 + PIXEL01_10 + PIXEL02_10 + PIXEL03_80 + PIXEL10_10 + PIXEL11_30 + PIXEL12_30 + PIXEL13_10 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + break; + } + case 123: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_10 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 95: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL11_0 + PIXEL12_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_30 + PIXEL23_10 + PIXEL30_80 + PIXEL31_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 222: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_10 + PIXEL11_30 + PIXEL12_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 252: + { + PIXEL00_80 + PIXEL01_61 + PIXEL02_81 + PIXEL03_81 + PIXEL10_10 + PIXEL11_30 + PIXEL12_31 + PIXEL13_31 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_0 + PIXEL23_0 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + case 249: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_61 + PIXEL03_80 + PIXEL10_32 + PIXEL11_32 + PIXEL12_30 + PIXEL13_10 + PIXEL20_0 + PIXEL21_0 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + break; + } + case 235: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_61 + PIXEL20_0 + PIXEL21_0 + PIXEL22_31 + PIXEL23_81 + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + PIXEL32_31 + PIXEL33_81 + break; + } + case 111: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + PIXEL02_32 + PIXEL03_82 + PIXEL10_0 + PIXEL11_0 + PIXEL12_32 + PIXEL13_82 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_61 + PIXEL32_10 + PIXEL33_80 + break; + } + case 63: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_0 + PIXEL11_0 + PIXEL12_0 + PIXEL20_31 + PIXEL21_31 + PIXEL22_30 + PIXEL23_10 + PIXEL30_81 + PIXEL31_81 + PIXEL32_61 + PIXEL33_80 + break; + } + case 159: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL11_0 + PIXEL12_0 + PIXEL13_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_32 + PIXEL23_32 + PIXEL30_80 + PIXEL31_61 + PIXEL32_82 + PIXEL33_82 + break; + } + case 215: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL10_81 + PIXEL11_31 + PIXEL12_0 + PIXEL13_0 + PIXEL20_61 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 246: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_61 + PIXEL11_30 + PIXEL12_0 + PIXEL20_82 + PIXEL21_32 + PIXEL22_0 + PIXEL23_0 + PIXEL30_82 + PIXEL31_32 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + case 254: + { + PIXEL00_80 + PIXEL01_10 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_10 + PIXEL11_30 + PIXEL12_0 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_0 + PIXEL23_0 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + case 253: + { + PIXEL00_82 + PIXEL01_82 + PIXEL02_81 + PIXEL03_81 + PIXEL10_32 + PIXEL11_32 + PIXEL12_31 + PIXEL13_31 + PIXEL20_0 + PIXEL21_0 + PIXEL22_0 + PIXEL23_0 + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + case 251: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_10 + PIXEL03_80 + PIXEL11_0 + PIXEL12_30 + PIXEL13_10 + PIXEL20_0 + PIXEL21_0 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + break; + } + case 239: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + PIXEL02_32 + PIXEL03_82 + PIXEL10_0 + PIXEL11_0 + PIXEL12_32 + PIXEL13_82 + PIXEL20_0 + PIXEL21_0 + PIXEL22_31 + PIXEL23_81 + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + PIXEL32_31 + PIXEL33_81 + break; + } + case 127: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + if (Diff(w[2], w[6])) + { + PIXEL02_0 + PIXEL03_0 + PIXEL13_0 + } + else + { + PIXEL02_50 + PIXEL03_50 + PIXEL13_50 + } + PIXEL10_0 + PIXEL11_0 + PIXEL12_0 + if (Diff(w[8], w[4])) + { + PIXEL20_0 + PIXEL30_0 + PIXEL31_0 + } + else + { + PIXEL20_50 + PIXEL30_50 + PIXEL31_50 + } + PIXEL21_0 + PIXEL22_30 + PIXEL23_10 + PIXEL32_10 + PIXEL33_80 + break; + } + case 191: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL10_0 + PIXEL11_0 + PIXEL12_0 + PIXEL13_0 + PIXEL20_31 + PIXEL21_31 + PIXEL22_32 + PIXEL23_32 + PIXEL30_81 + PIXEL31_81 + PIXEL32_82 + PIXEL33_82 + break; + } + case 223: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_0 + PIXEL10_0 + } + else + { + PIXEL00_50 + PIXEL01_50 + PIXEL10_50 + } + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL11_0 + PIXEL12_0 + PIXEL13_0 + PIXEL20_10 + PIXEL21_30 + PIXEL22_0 + if (Diff(w[6], w[8])) + { + PIXEL23_0 + PIXEL32_0 + PIXEL33_0 + } + else + { + PIXEL23_50 + PIXEL32_50 + PIXEL33_50 + } + PIXEL30_80 + PIXEL31_10 + break; + } + case 247: + { + PIXEL00_81 + PIXEL01_31 + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL10_81 + PIXEL11_31 + PIXEL12_0 + PIXEL13_0 + PIXEL20_82 + PIXEL21_32 + PIXEL22_0 + PIXEL23_0 + PIXEL30_82 + PIXEL31_32 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + case 255: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_0 + PIXEL02_0 + if (Diff(w[2], w[6])) + { + PIXEL03_0 + } + else + { + PIXEL03_20 + } + PIXEL10_0 + PIXEL11_0 + PIXEL12_0 + PIXEL13_0 + PIXEL20_0 + PIXEL21_0 + PIXEL22_0 + PIXEL23_0 + if (Diff(w[8], w[4])) + { + PIXEL30_0 + } + else + { + PIXEL30_20 + } + PIXEL31_0 + PIXEL32_0 + if (Diff(w[6], w[8])) + { + PIXEL33_0 + } + else + { + PIXEL33_20 + } + break; + } + } + pIn++; // next source pixel (just increment since it's an int*) + pOut += 16; // skip 4 pixels (4 bytes * 4 pixels) + } + pOut += BpL; // skip next 3 rows + pOut += BpL; + pOut += BpL; + } + __asm emms +} + +void DLL InitLUTs() +{ + int i, j, k, r, g, b, Y, u, v; + +#if 0 // colorOutlines() after hqresize + for (i=0; i<65536; i++) + LUT16to32[i] = 0x00404040; + for (i=0; i<65536; i++) + LUT16to32[i+65536] = 0xFF000000 + ((i & 0xF800) << 8) + ((i & 0x07E0) << 5) + ((i & 0x001F) << 3); +#else // colorOutlines() before hqresize + for (i=0; i<65536; i++) + LUT16to32[i] = ((i & 0xF800) << 8) + ((i & 0x07E0) << 5) + ((i & 0x001F) << 3); + for (i=0; i<65536; i++) + LUT16to32[i+65536] = 0xFF000000 + LUT16to32[i]; +#endif + + for (i=0; i<65536; i++) + RGBtoYUV[i] = 0xFF000000; + + for (i=0; i<32; i++) + for (j=0; j<64; j++) + for (k=0; k<32; k++) + { + r = i << 3; + g = j << 2; + b = k << 3; + Y = (r + g + b) >> 2; + u = 128 + ((r - b) >> 2); + v = 128 + ((-r + 2*g -b)>>3); + RGBtoYUV[ 65536 + (i << 11) + (j << 5) + k ] = (Y<<16) + (u<<8) + v; + } +} + +/* +int DLL hq4x_32 ( CImage &ImageIn, CImage &ImageOut ) +{ + if ( ImageIn.Convert32To17() != 0 ) + { + printf( "ERROR: conversion to 17 bit failed\n" ); + return 1; + } + + if ( ImageOut.Init( ImageIn.m_Xres*4, ImageIn.m_Yres*4, 32 ) != 0 ) + { + printf( "ERROR: ImageOut.Init()\n" ); + return 1; + }; + + InitLUTs(); + hq4x_32( (int*)ImageIn.m_pBitmap, ImageOut.m_pBitmap, ImageIn.m_Xres, ImageIn.m_Yres, ImageOut.m_Xres*4 ); + + printf( "\nOK\n" ); + return 0; +} +*/ + +} \ No newline at end of file diff --git a/src/gl/hqnx_asm/hqnx_asm.h b/src/gl/hqnx_asm/hqnx_asm.h new file mode 100644 index 000000000..341e2dad3 --- /dev/null +++ b/src/gl/hqnx_asm/hqnx_asm.h @@ -0,0 +1,39 @@ +//hqnx filter library +//---------------------------------------------------------- +//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) +//Copyright (C) 2009 Benjamin Berkels +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 2.1 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser General Public +//License along with this program; if not, write to the Free Software +//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef __HQNX_H__ +#define __HQNX_H__ + +#pragma warning(disable:4799) + +#include "hqnx_asm_Image.h" + +namespace HQnX_asm +{ +void DLL hq2x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); +void DLL hq3x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); +void DLL hq4x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); +int DLL hq4x_32 ( CImage &ImageIn, CImage &ImageOut ); + +void DLL InitLUTs(); + +} + + +#endif //__HQNX_H__ \ No newline at end of file diff --git a/src/gl/hqnx_asm/hqnx_asm_Image.cpp b/src/gl/hqnx_asm/hqnx_asm_Image.cpp new file mode 100644 index 000000000..be7d1b350 --- /dev/null +++ b/src/gl/hqnx_asm/hqnx_asm_Image.cpp @@ -0,0 +1,1179 @@ +//CImage class - loading and saving BMP and TGA files +//---------------------------------------------------------- +//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 2.1 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser General Public +//License along with this program; if not, write to the Free Software +//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include +#include +#include "hqnx_asm_Image.h" + +namespace HQnX_asm +{ + +DLL CImage::CImage() +{ + m_Xres = m_Yres = m_NumPixel = 0; + m_pBitmap = NULL; +} + +DLL CImage::~CImage() +{ + Destroy(); +} + +int DLL CImage::Init( int X, int Y, unsigned short BitPerPixel ) +{ + if (m_pBitmap != NULL) + free(m_pBitmap); + + m_Xres = X; + m_Yres = Y; + m_BitPerPixel = BitPerPixel<=8 ? 8 : BitPerPixel<=16 ? 16 : BitPerPixel<=24 ? 24 : 32; + m_BytePerPixel = m_BitPerPixel >> 3; + m_NumPixel = m_Xres*m_Yres; + int size = m_NumPixel*((m_BitPerPixel+7)/8); + m_pBitmap=(unsigned char *)malloc(size); + return (m_pBitmap != NULL) ? 0 : 1; +} + +int DLL CImage::SetImage(unsigned char *img, int width, int height, int bpp) +{ + Init(width, height, bpp); + + memcpy(m_pBitmap, img, m_NumPixel * m_BytePerPixel); + + return 0; +} + +int DLL CImage::Destroy() +{ + if (m_pBitmap) + { + free(m_pBitmap); + m_pBitmap = NULL; + } + m_Xres = 0; + m_Yres = 0; + m_NumPixel = 0; + m_BitPerPixel = 0; + return 0; +} + +int DLL CImage::Convert32To17( void ) +{ + int nRes = eConvUnknownFormat; + + if ( m_BitPerPixel == 32 ) + { + if ( m_pBitmap != NULL ) + { + unsigned char * pTemp8 = m_pBitmap; + unsigned int * pTemp32 = (unsigned int *)m_pBitmap; + unsigned int a, r, g, b; + for ( int i=0; i> 3; + g = (*(pTemp8++)) >> 2; + r = (*(pTemp8++)) >> 3; + a = *(pTemp8++); + *pTemp32 = (r << 11) + (g << 5) + b + (a > 127 ? 0x10000 : 0); + pTemp32++; + } + } + else + nRes = eConvSourceMemory; + + nRes = 0; + } + + return nRes; +} + +int DLL CImage::ConvertTo32( void ) +{ + int nRes = eConvUnknownFormat; + + if ( m_pBitmap == NULL ) + return eConvSourceMemory; + + switch ( m_BitPerPixel ) + { + case 8: + { + nRes = 0; + m_BitPerPixel = 32; + unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*4); + if ( pNewBitmap != NULL ) + { + unsigned char * pTemp8 = m_pBitmap; + unsigned char * pTemp32 = pNewBitmap; + unsigned char c; + for ( int i=0; i> 3); + *(pTemp24++) = ((rgb & 0xF800) >> 8); + } + free(m_pBitmap); + m_pBitmap = pNewBitmap; + } + else + nRes = eConvDestMemory; + + break; + } + case 32: + { + nRes = 0; + m_BitPerPixel = 24; + unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*3); + if ( pNewBitmap != NULL ) + { + unsigned char * pTemp32 = m_pBitmap; + unsigned char * pTemp24 = pNewBitmap; + for ( int i=0; i> 3; + g = m_Pal[c].g >> 2; + b = m_Pal[c].b >> 3; + *(pTemp16++) = (r << 11) + (g << 5) + b; + } + free(m_pBitmap); + m_pBitmap = pNewBitmap; + } + else + nRes = eConvDestMemory; + + break; + } + case 24: + { + nRes = 0; + m_BitPerPixel = 16; + unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*2); + if ( pNewBitmap != NULL ) + { + unsigned char * pTemp24 = m_pBitmap; + unsigned short * pTemp16 = (unsigned short *)pNewBitmap; + unsigned short r, g, b; + for ( int i=0; i> 3; + g = (*(pTemp24++)) >> 2; + r = (*(pTemp24++)) >> 3; + *(pTemp16++) = (r << 11) + (g << 5) + b; + } + free(m_pBitmap); + m_pBitmap = pNewBitmap; + } + else + nRes = eConvDestMemory; + + break; + } + case 32: + { + nRes = 0; + m_BitPerPixel = 16; + unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*2); + if ( pNewBitmap != NULL ) + { + unsigned char * pTemp32 = m_pBitmap; + unsigned short * pTemp16 = (unsigned short *)pNewBitmap; + unsigned short r, g, b; + for ( int i=0; i> 3; + g = (*(pTemp32++)) >> 2; + r = (*(pTemp32++)) >> 3; + pTemp32++; + *(pTemp16++) = (r << 11) + (g << 5) + b; + } + free(m_pBitmap); + m_pBitmap = pNewBitmap; + } + else + nRes = eConvDestMemory; + + break; + } + } + + return nRes; +} + +int CImage::Convert8To17( int transindex ) +{ + int nRes = eConvUnknownFormat; + + if ( m_BitPerPixel == 8 ) + { + m_BitPerPixel = 32; + unsigned char * pNewBitmap = (unsigned char *)malloc(m_NumPixel*4); + if ( pNewBitmap != NULL ) + { + unsigned char * pTemp8 = m_pBitmap; + unsigned int * pTemp32 = (unsigned int *)pNewBitmap; + unsigned int r, g, b; + unsigned char c; + for ( int i=0; i> 3; + g = m_Pal[c].g >> 2; + b = m_Pal[c].b >> 3; + *(pTemp32++) = (r << 11) + (g << 5) + b + (transindex != c ? 0x10000 : 0); + } + free(m_pBitmap); + m_pBitmap = pNewBitmap; + } + else + nRes = eConvDestMemory; + + nRes = 0; + } + + return nRes; +} + +int CImage::SaveBmp(char *szFilename) +{ + _BMPFILEHEADER fh; + _BMPIMAGEHEADER ih; + unsigned char BmpPal[256][4]; + long int SuffLen; + long int Dummy = 0; + unsigned char * pBuf; + short i; + + if (!(f = fopen(szFilename, "wb"))) return eSaveBmpFileOpen; + if ( m_pBitmap == NULL ) return eSaveBmpSourceMemory; + + fh.bfType=0x4D42; + if (m_BitPerPixel==8) + { + SuffLen=((m_Xres+3)/4)*4-m_Xres; + ih.biSize=0x28; + ih.biWidth=m_Xres; + ih.biHeight=m_Yres; + ih.biPlanes=1; + ih.biBitCount=8; + ih.biCompression=0; + ih.biSizeImage=(m_Xres+SuffLen)*m_Yres; + ih.biXPelsPerMeter=ih.biYPelsPerMeter=0x2E23; // 300dpi (pixels per meter) + ih.biClrUsed=ih.biClrImportant=0; + fh.bfSize=(ih.biSizeImage)+0x0436; + fh.bfRes1=0; + fh.bfOffBits=0x0436; + if (fwrite(&fh, 14, 1, f) != 1) return eSaveBmpFileWrite; + if (fwrite(&ih, 40, 1, f) != 1) return eSaveBmpFileWrite; + for (i=0; i<256; i++) + { + BmpPal[i][0]=m_Pal[i].b; + BmpPal[i][1]=m_Pal[i].g; + BmpPal[i][2]=m_Pal[i].r; + BmpPal[i][3]=0; + } + if (fwrite(&BmpPal, 1024, 1, f) != 1) return eSaveBmpFileWrite; + pBuf=m_pBitmap; + pBuf+=m_NumPixel; + for (i=0; i0) + { + if (fwrite(&Dummy, SuffLen, 1, f) != 1) return eSaveBmpFileWrite; + } + } + } + else + if (m_BitPerPixel==24) + { + SuffLen=((m_Xres*3+3)/4)*4-m_Xres*3; + ih.biSize=0x28; + ih.biWidth=m_Xres; + ih.biHeight=m_Yres; + ih.biPlanes=1; + ih.biBitCount=24; + ih.biCompression=0; + ih.biSizeImage=(m_Xres*3+SuffLen)*m_Yres; + ih.biXPelsPerMeter=ih.biYPelsPerMeter=0x2E23; // 300dpi (pixels per meter) + ih.biClrUsed=ih.biClrImportant=0; + fh.bfSize=(ih.biSizeImage)+0x0036; + fh.bfRes1=0; + fh.bfOffBits=0x0036; + if (fwrite(&fh, 14, 1, f) != 1) return eSaveBmpFileWrite; + if (fwrite(&ih, 40, 1, f) != 1) return eSaveBmpFileWrite; + pBuf=m_pBitmap; + pBuf+=m_NumPixel*3; + for (i=0; i0) + { + if (fwrite(&Dummy, SuffLen, 1, f) != 1) return eSaveBmpFileWrite; + } + } + } + else + return eSaveBmpColorDepth; + + fclose(f); + + return 0; +} + +int CImage::LoadBmp(char *szFilename) +{ + _BMPFILEHEADER fh; + _BMPIMAGEHEADEROLD ih_old; + _BMPIMAGEHEADER ih; + unsigned char BmpPal[256][4]; + long int biSize; + long int SuffLen; + long int Dummy = 0; + unsigned char * pBuf; + short i; + long int xres, yres; + unsigned short bits; + + if (!(f = fopen(szFilename, "rb"))) return eLoadBmpFileOpen; + if (fread(&fh, 14, 1, f) != 1) return eLoadBmpFileRead; + if (fh.bfType != 0x4D42) return eLoadBmpBadFormat; + if (fread(&biSize, 4, 1, f) != 1) return eLoadBmpFileRead; + if (biSize > 12) + { + fseek( f, -4, SEEK_CUR ); + if (fread(&ih, biSize, 1, f) != 1) return eLoadBmpFileRead; + xres = ih.biWidth; + yres = ih.biHeight; + bits = ih.biBitCount; + } + else + { + fseek( f, -4, SEEK_CUR ); + if (fread(&ih_old, biSize, 1, f) != 1) return eLoadBmpFileRead; + xres = ih_old.biWidth; + yres = ih_old.biHeight; + bits = ih_old.biBitCount; + } + + if ( Init( xres, yres, bits ) != 0 ) return eLoadBmpInit; + if (m_BitPerPixel==8) + { + SuffLen=((m_Xres+3)/4)*4-m_Xres; + if (fread(&BmpPal, 1024, 1, f) != 1) return eLoadBmpFileRead; + for (i=0; i<256; i++) + { + m_Pal[i].b=BmpPal[i][0]; + m_Pal[i].g=BmpPal[i][1]; + m_Pal[i].r=BmpPal[i][2]; + } + pBuf=m_pBitmap; + pBuf+=m_NumPixel; + for (i=0; i0) + { + if (fread(&Dummy, SuffLen, 1, f) != 1) return eLoadBmpFileRead; + } + } + } + else + if (m_BitPerPixel==24) + { + SuffLen=((m_Xres*3+3)/4)*4-(m_Xres*3); + pBuf=m_pBitmap; + pBuf+=m_NumPixel*3; + for (i=0; i0) + { + if (fread(&Dummy, SuffLen, 1, f) != 1) return eLoadBmpFileRead; + } + } + } + else + return eLoadBmpColorDepth; + + fclose(f); + + return 0; +} + +void CImage::Output( void ) +{ + fwrite(m_cBuf, m_nCount, 1, f); + m_nCount=0; +} + +void CImage::Output( char c ) +{ + if ( m_nCount == sizeof(m_cBuf) ) + { + fwrite(m_cBuf, m_nCount, 1, f); + m_nCount=0; + } + m_cBuf[m_nCount++] = c; +} + +void CImage::Output( char * pcData, int nSize ) +{ + for ( int i=0; i 0 ) + { + Output( nDif-1 ); + Output( (char*)(pcolBuf+i-nDif-nRep), nDif ); + } + nDif = 1; + } + } + else + { + if ( bEqual && (nRep<127) ) + nRep++; + else + { + Output( nRep+128 ); + Output( (char*)&colOld, 1 ); + nRep = 0; + nDif = 1; + } + } + } + + if ( nRep == 0 ) + { + Output( nDif-1 ); + Output( (char*)(pcolBuf+m_Xres-nDif), nDif ); + } + else + { + Output( nRep+128 ); + Output( (char*)&colOld, 1 ); + } + Output(); + } + } + } + else + if (m_BitPerPixel==24) + { + fh.tiImageType = bCompressed ? 10 : 2; + if (fwrite(&fh, sizeof(fh), 1, f) != 1) return eSaveTgaFileWrite; + + _BGR * pcolBuf = (_BGR *)m_pBitmap; + pcolBuf += m_NumPixel; + + if ( !bCompressed ) + { + for (j=0; j 0 ) + { + Output( nDif-1 ); + Output( (char*)(pcolBuf+i-nDif-nRep), sizeof(_BGR)*nDif ); + } + nDif = 1; + } + } + else + { + if ( bEqual && (nRep<127) ) + nRep++; + else + { + Output( nRep+128 ); + Output( (char*)&colOld, sizeof(_BGR) ); + nRep = 0; + nDif = 1; + } + } + } + + if ( nRep == 0 ) + { + Output( nDif-1 ); + Output( (char*)(pcolBuf+m_Xres-nDif), sizeof(_BGR)*nDif ); + } + else + { + Output( nRep+128 ); + Output( (char*)&colOld, sizeof(_BGR) ); + } + Output(); + } + } + } + else + if (m_BitPerPixel==32) + { + fh.tiImageType = bCompressed ? 10 : 2; + fh.tiAttrBits = 8; + if (fwrite(&fh, sizeof(fh), 1, f) != 1) return eSaveTgaFileWrite; + + _BGRA * pcolBuf = (_BGRA *)m_pBitmap; + pcolBuf += m_NumPixel; + + if ( !bCompressed ) + { + for (j=0; j 0 ) + { + Output( nDif-1 ); + Output( (char*)(pcolBuf+i-nDif-nRep), sizeof(_BGRA)*nDif ); + } + nDif = 1; + } + } + else + { + if ( bEqual && (nRep<127) ) + nRep++; + else + { + Output( nRep+128 ); + Output( (char*)&colOld, sizeof(_BGRA) ); + nRep = 0; + nDif = 1; + } + } + } + + if ( nRep == 0 ) + { + Output( nDif-1 ); + Output( (char*)(pcolBuf+m_Xres-nDif), sizeof(_BGRA)*nDif ); + } + else + { + Output( nRep+128 ); + Output( (char*)&colOld, sizeof(_BGRA) ); + } + Output(); + } + } + } + else + return eSaveTgaColorDepth; + + fclose(f); + + return 0; +} + +int CImage::LoadTga(char *szFilename) +{ + _TGAHEADER fh; + int i, j, k; + unsigned char nCount; + + if (!(f = fopen(szFilename, "rb"))) return eLoadTgaFileOpen; + if (fread(&fh, sizeof(fh), 1, f) != 1) return eLoadTgaFileRead; + bool bCompressed = (( fh.tiImageType & 8 ) != 0); + if ((fh.tiBitPerPixel<=0) || (fh.tiBitPerPixel>32)) + return eLoadTgaBadFormat; + + if ( Init( fh.tiXres, fh.tiYres, fh.tiBitPerPixel ) != 0 ) + return eLoadTgaInit; + + if ( m_BitPerPixel == 8 ) + { + if ( fh.tiPaletteIncluded == 1 ) + { + if ( fh.tiPaletteBpp == 24) + { + if (fread(&m_Pal, 3, fh.tiPaletteSize, f) != fh.tiPaletteSize) + return eLoadTgaFileRead; + } + else + if ( fh.tiPaletteBpp == 32) + { + unsigned char BmpPal[256][4]; + + if (fread(&BmpPal, 4, fh.tiPaletteSize, f) != fh.tiPaletteSize) + return eLoadTgaFileRead; + + for (i=0; i= m_pBitmap ) + { + nCount = Input(); + if ((nCount & 128)==0) + { + for (k=0; k<=nCount; k++) + { + colCur = Input(); + *(pcolBuf+i) = colCur; + if ( (++i) == m_Xres ) + { + i=0; + pcolBuf -= m_Xres; + break; + } + } + } + else + { + colCur = Input(); + for (k=0; k<=nCount-128; k++) + { + *(pcolBuf+i) = colCur; + if ( (++i) == m_Xres ) + { + i=0; + pcolBuf -= m_Xres; + break; + } + } + } + } + } + } + else + if ( m_BitPerPixel == 24 ) + { + _BGR * pcolBuf = (_BGR *)m_pBitmap; + pcolBuf += m_NumPixel; + + if ( !bCompressed ) + { + for (j=0; j= (_BGR *)m_pBitmap ) + { + nCount = Input(); + if ((nCount & 128)==0) + { + for (k=0; k<=nCount; k++) + { + colCur.b = Input(); + colCur.g = Input(); + colCur.r = Input(); + *(pcolBuf+i) = colCur; + if ( (++i) == m_Xres ) + { + i=0; + pcolBuf -= m_Xres; + break; + } + } + } + else + { + colCur.b = Input(); + colCur.g = Input(); + colCur.r = Input(); + for (k=0; k<=nCount-128; k++) + { + *(pcolBuf+i) = colCur; + if ( (++i) == m_Xres ) + { + i=0; + pcolBuf -= m_Xres; + break; + } + } + } + } + } + } + else + if ( m_BitPerPixel == 32 ) + { + _BGRA * pcolBuf = (_BGRA *)m_pBitmap; + pcolBuf += m_NumPixel; + + if ( !bCompressed ) + { + for (j=0; j= (_BGRA *)m_pBitmap ) + { + nCount = Input(); + if ((nCount & 128)==0) + { + for (k=0; k<=nCount; k++) + { + colCur.b = Input(); + colCur.g = Input(); + colCur.r = Input(); + colCur.a = Input(); + *(pcolBuf+i) = colCur; + if ( (++i) == m_Xres ) + { + i=0; + pcolBuf -= m_Xres; + break; + } + } + } + else + { + colCur.b = Input(); + colCur.g = Input(); + colCur.r = Input(); + colCur.a = Input(); + for (k=0; k<=nCount-128; k++) + { + *(pcolBuf+i) = colCur; + if ( (++i) == m_Xres ) + { + i=0; + pcolBuf -= m_Xres; + break; + } + } + } + } + } + } + else + return eLoadTgaColorDepth; + + fclose(f); + + return 0; +} + +int DLL CImage::Load(char *szFilename) +{ + int nRes = 0; + + if ( szFilename != NULL ) + { + char * szExt = strrchr( szFilename, '.' ); + int nNotTGA = 1; + + if ( szExt != NULL ) + nNotTGA = _stricmp( szExt, ".tga" ); + + if ( nNotTGA != 0 ) + nRes = LoadBmp( szFilename ); + else + nRes = LoadTga( szFilename ); + } + else + nRes = eLoadFilename; + + return nRes; +} + +int DLL CImage::Save(char *szFilename) +{ + int nRes = 0; + int nNotTGA = 1; + + if ( szFilename != NULL ) + { + char * szExt = strrchr( szFilename, '.' ); + + if ( szExt != NULL ) + nNotTGA = _stricmp( szExt, ".tga" ); + + if ( nNotTGA != 0 ) + { + if (( m_BitPerPixel == 16 ) || ( m_BitPerPixel == 32 )) + nRes = ConvertTo24(); + + if (nRes == 0) + nRes = SaveBmp( szFilename ); + } + else + { + if ( m_BitPerPixel == 16 ) + nRes = ConvertTo24(); + + if (nRes == 0) + nRes = SaveTga( szFilename, true ); + } + } + else + nRes = eSaveFilename; + + return nRes; +} + +} \ No newline at end of file diff --git a/src/gl/hqnx_asm/hqnx_asm_Image.h b/src/gl/hqnx_asm/hqnx_asm_Image.h new file mode 100644 index 000000000..8f57d7865 --- /dev/null +++ b/src/gl/hqnx_asm/hqnx_asm_Image.h @@ -0,0 +1,150 @@ +//CImage class - loading and saving BMP and TGA files +//---------------------------------------------------------- +//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) +// +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 2.1 of the License, or (at your option) any later version. +// +//This program is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser General Public +//License along with this program; if not, write to the Free Software +//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +//#ifdef WIN32 +//#define DLL __declspec(dllexport) +//#else +#define DLL +//#endif + +#include +#pragma once +#pragma warning(disable: 4103) +#pragma pack(1) + +namespace HQnX_asm +{ + +typedef struct { unsigned char b, g, r; } _BGR; +typedef struct { unsigned char b, g, r, a; } _BGRA; + +class CImage +{ + public: + DLL CImage(); + DLL ~CImage(); + + enum CImageErrors + { + eConvUnknownFormat = 10, + eConvSourceMemory = 11, + eConvDestMemory = 12, + + eSaveBmpFileOpen = 20, + eSaveBmpFileWrite = 21, + eSaveBmpSourceMemory = 22, + eSaveBmpColorDepth = 23, + + eLoadBmpFileOpen = 30, + eLoadBmpFileRead = 31, + eLoadBmpBadFormat = 32, + eLoadBmpInit = 33, + eLoadBmpColorDepth = 34, + + eSaveTgaFileOpen = 40, + eSaveTgaFileWrite = 41, + eSaveTgaSourceMemory = 42, + eSaveTgaColorDepth = 43, + + eLoadTgaFileOpen = 50, + eLoadTgaFileRead = 51, + eLoadTgaBadFormat = 52, + eLoadTgaInit = 53, + eLoadTgaColorDepth = 54, + + eLoadFilename = 60, + eSaveFilename = 61, + }; + + struct _BMPFILEHEADER + { + unsigned short bfType; + long int bfSize, bfRes1, bfOffBits; + }; + + struct _BMPIMAGEHEADEROLD + { + long int biSize; + unsigned short biWidth, biHeight; + unsigned short biPlanes, biBitCount; + }; + + struct _BMPIMAGEHEADER + { + long int biSize, biWidth, biHeight; + unsigned short biPlanes, biBitCount; + long int biCompression, biSizeImage; + long int biXPelsPerMeter, biYPelsPerMeter; + long int biClrUsed, biClrImportant; + }; + + struct _TGAHEADER + { + unsigned char tiIdentSize; + unsigned char tiPaletteIncluded; + unsigned char tiImageType; + unsigned short tiPaletteStart; + unsigned short tiPaletteSize; + unsigned char tiPaletteBpp; + unsigned short tiX0; + unsigned short tiY0; + unsigned short tiXres; + unsigned short tiYres; + unsigned char tiBitPerPixel; + unsigned char tiAttrBits; + }; + + public: + int DLL Init( int Xres, int Yres, unsigned short BitPerPixel ); + int DLL SetImage(unsigned char *img, int width, int height, int bpp); + int DLL Destroy(); + int DLL ConvertTo32( void ); + int DLL ConvertTo24( void ); + int DLL ConvertTo16( void ); + int DLL Convert8To17( int transindex ); + int DLL Convert32To17( void ); + int SaveBmp(char *szFilename); + int LoadBmp(char *szFilename); + int SaveTga(char *szFilename, bool bCompressed ); + int LoadTga(char *szFilename); + int DLL Load(char *szFilename); + int DLL Save(char *szFilename); + + private: + void Output( char * pcData, int nSize ); + void Output( char c ); + void Output( void ); + unsigned char Input( void ); + + public: + int m_Xres, m_Yres; + unsigned short m_BitPerPixel; + unsigned short m_BytePerPixel; + unsigned char * m_pBitmap; + _BGR m_Pal[256]; + + private: + int m_NumPixel; + FILE * f; + int m_nCount; + char m_cBuf[32768]; +}; + +#pragma pack(8) + +} \ No newline at end of file diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index fac9bd5bb..babab5050 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -59,6 +59,7 @@ #include "gl/utility/gl_geometric.h" #include "gl/utility/gl_convert.h" #include "gl/renderer/gl_renderstate.h" +#include "gl/shaders/gl_shader.h" static inline float GetTimeFloat() { @@ -68,7 +69,6 @@ static inline float GetTimeFloat() CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE) CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE) EXTERN_CVAR(Int, gl_fogmode) -EXTERN_CVAR(Bool, gl_dynlight_shader) extern TDeletingArray Voxels; extern TDeletingArray VoxelDefs; @@ -92,6 +92,65 @@ public: DeletingModelArray Models; + +//=========================================================================== +// +// +// +//=========================================================================== + +FModelVertexBuffer::FModelVertexBuffer() +{ + ibo_id = 0; + glGenBuffers(1, &ibo_id); + //for (unsigned i = 1; i < Models.Size(); i++) + for (int i = Models.Size() - 1; i >= 0; i--) + { + Models[i]->BuildVertexBuffer(this); + } + + glBindVertexArray(vao_id); + + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER,vbo_shadowdata.Size() * sizeof(FModelVertex), &vbo_shadowdata[0], GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER,ibo_shadowdata.Size() * sizeof(unsigned int), &ibo_shadowdata[0], GL_STATIC_DRAW); + + glEnableVertexAttribArray(VATTR_VERTEX); + glEnableVertexAttribArray(VATTR_TEXCOORD); + glEnableVertexAttribArray(VATTR_VERTEX2); + glBindVertexArray(0); +} + +FModelVertexBuffer::~FModelVertexBuffer() +{ + if (ibo_id != 0) + { + glDeleteBuffers(1, &ibo_id); + } +} + + +//=========================================================================== +// +// Sets up the buffer starts for frame interpolation +// This must be called after gl_RenderState.Apply! +// +//=========================================================================== + +unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int frame2, float factor) +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); + glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u); + glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x); + return frame1; +} + + + + + static TArray SpriteModelFrames; static int * SpriteModelHash; //TArray StateModelFrames; @@ -619,7 +678,6 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, - int cm, Matrix3x4 *normaltransform, int translation) { @@ -676,15 +734,19 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, if (mdl!=NULL) { + gl_RenderState.SetVertexBuffer(GLRenderer->mModelVBO); + if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) - mdl->RenderFrameInterpolated(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, cm, translation); + mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, translation); else - mdl->RenderFrame(smf->skins[i], smf->modelframes[i], cm, translation); + mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smf->modelframes[i], 0.f, translation); + + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } } } -void gl_RenderModel(GLSprite * spr, int cm) +void gl_RenderModel(GLSprite * spr) { FSpriteModelFrame * smf = spr->modelframe; @@ -745,81 +807,41 @@ void gl_RenderModel(GLSprite * spr, int cm) // This is rather crappy way to transfer fixet_t type into angle in degrees, but its works! if(smf->flags & MDL_INHERITACTORPITCH) pitch += float(static_cast(spr->actor->pitch >> 16) / (1 << 13) * 45 + static_cast(spr->actor->pitch & 0x0000FFFF) / (1 << 29) * 45); if(smf->flags & MDL_INHERITACTORROLL) roll += float(static_cast(spr->actor->roll >> 16) / (1 << 13) * 45 + static_cast(spr->actor->roll & 0x0000FFFF) / (1 << 29) * 45); - - if (gl.shadermodel < 4) - { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - } - else - { - glActiveTexture(GL_TEXTURE7); // Hijack the otherwise unused seventh texture matrix for the model to world transformation. - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - } + + gl_RenderState.mModelMatrix.loadIdentity(); // Model space => World space - glTranslatef(spr->x, spr->z, spr->y ); + gl_RenderState.mModelMatrix.translate(spr->x, spr->z, spr->y ); // Applying model transformations: // 1) Applying actor angle, pitch and roll to the model - glRotatef(-angle, 0, 1, 0); - glRotatef(pitch, 0, 0, 1); - glRotatef(-roll, 1, 0, 0); + gl_RenderState.mModelMatrix.rotate(-angle, 0, 1, 0); + gl_RenderState.mModelMatrix.rotate(pitch, 0, 0, 1); + gl_RenderState.mModelMatrix.rotate(-roll, 1, 0, 0); // 2) Applying Doomsday like rotation of the weapon pickup models // The rotation angle is based on the elapsed time. if( smf->flags & MDL_ROTATING ) { - glTranslatef(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ); - glRotatef(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate); - glTranslatef(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ); + gl_RenderState.mModelMatrix.translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ); + gl_RenderState.mModelMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate); + gl_RenderState.mModelMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ); } // 3) Scaling model. - glScalef(scaleFactorX, scaleFactorZ, scaleFactorY); + gl_RenderState.mModelMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY); // 4) Aplying model offsets (model offsets do not depend on model scalings). - glTranslatef(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); + gl_RenderState.mModelMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); // 5) Applying model rotations. - glRotatef(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0); - glRotatef(smf->pitchoffset, 0, 0, 1); - glRotatef(-smf->rolloffset, 1, 0, 0); - - if (gl.shadermodel >= 4) glActiveTexture(GL_TEXTURE0); - -#if 0 - if (gl_light_models) - { - // The normal transform matrix only contains the inverse rotations and scalings but not the translations - NormalTransform.MakeIdentity(); - - NormalTransform.Scale(1.f/scaleFactorX, 1.f/scaleFactorZ, 1.f/scaleFactorY); - if( smf->flags & MDL_ROTATING ) NormalTransform.Rotate(smf->xrotate, smf->yrotate, smf->zrotate, -rotateOffset); - if (pitch != 0) NormalTransform.Rotate(0,0,1,-pitch); - if (angle != 0) NormalTransform.Rotate(0,1,0, angle); - - gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, &ModelToWorld, &NormalTransform, translation ); - } -#endif - - gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, NULL, translation ); - - if (gl.shadermodel < 4) - { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - else - { - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glActiveTexture(GL_TEXTURE0); - glMatrixMode(GL_MODELVIEW); - } + gl_RenderState.mModelMatrix.rotate(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0); + gl_RenderState.mModelMatrix.rotate(smf->pitchoffset, 0, 0, 1); + gl_RenderState.mModelMatrix.rotate(-smf->rolloffset, 1, 0, 0); + gl_RenderState.EnableModelMatrix(true); + gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), NULL, translation ); + gl_RenderState.EnableModelMatrix(false); glDepthFunc(GL_LESS); if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] )) @@ -833,7 +855,7 @@ void gl_RenderModel(GLSprite * spr, int cm) // //=========================================================================== -void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm) +void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy) { AActor * playermo=players[consoleplayer].camera; FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->state->sprite, psp->state->GetFrame(), false); @@ -842,11 +864,6 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm) if ( smf == NULL ) return; - // [BB] The model has to be drawn independtly from the position of the player, - // so we have to reset the GL_MODELVIEW matrix. - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); glDepthFunc(GL_LEQUAL); // [BB] In case the model should be rendered translucent, do back face culling. @@ -858,28 +875,31 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm) glFrontFace(GL_CCW); } + // [BB] The model has to be drawn independently from the position of the player, + // so we have to reset the view matrix. + gl_RenderState.mViewMatrix.loadIdentity(); + // Scaling model (y scale for a sprite means height, i.e. z in the world!). - glScalef(smf->xscale, smf->zscale, smf->yscale); + gl_RenderState.mViewMatrix.scale(smf->xscale, smf->zscale, smf->yscale); // Aplying model offsets (model offsets do not depend on model scalings). - glTranslatef(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); + gl_RenderState.mViewMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); // [BB] Weapon bob, very similar to the normal Doom weapon bob. - glRotatef(FIXED2FLOAT(ofsx)/4, 0, 1, 0); - glRotatef(-FIXED2FLOAT(ofsy-WEAPONTOP)/4, 1, 0, 0); + gl_RenderState.mViewMatrix.rotate(FIXED2FLOAT(ofsx)/4, 0, 1, 0); + gl_RenderState.mViewMatrix.rotate(-FIXED2FLOAT(ofsy-WEAPONTOP)/4, 1, 0, 0); // [BB] For some reason the jDoom models need to be rotated. - glRotatef(90., 0, 1, 0); + gl_RenderState.mViewMatrix.rotate(90.f, 0, 1, 0); // Applying angleoffset, pitchoffset, rolloffset. - glRotatef(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0); - glRotatef(smf->pitchoffset, 0, 0, 1); - glRotatef(-smf->rolloffset, 1, 0, 0); + gl_RenderState.mViewMatrix.rotate(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0); + gl_RenderState.mViewMatrix.rotate(smf->pitchoffset, 0, 0, 1); + gl_RenderState.mViewMatrix.rotate(-smf->rolloffset, 1, 0, 0); + gl_RenderState.ApplyMatrices(); - gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), cm, NULL, 0 ); + gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), NULL, 0 ); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); glDepthFunc(GL_LESS); if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] )) glDisable(GL_CULL_FACE); @@ -901,16 +921,3 @@ bool gl_IsHUDModelForPlayerAvailable (player_t * player) return ( smf != NULL ); } -//=========================================================================== -// -// gl_CleanModelData -// -//=========================================================================== - -void gl_CleanModelData() -{ - for (unsigned i=0;iCleanGLData(); - } -} diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 5d474dd8d..d608f9874 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -2,9 +2,11 @@ #define __GL_MODELS_H_ #include "gl/utility/gl_geometric.h" +#include "gl/data/gl_vertexbuffer.h" #include "p_pspr.h" #include "r_data/voxels.h" + #define MAX_LODS 4 enum { VX, VZ, VY }; @@ -27,11 +29,8 @@ public: virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0; virtual int FindFrame(const char * name) = 0; - virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0) = 0; - // [BB] Added RenderFrameInterpolated - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0) = 0; - virtual void MakeGLData() {} - virtual void CleanGLData() {} + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; + virtual void BuildVertexBuffer(FModelVertexBuffer *buf) = 0; @@ -56,7 +55,7 @@ protected: int flags; }; - struct FModelVertex + struct DMDModelVertex { float xyz[3]; }; @@ -92,8 +91,9 @@ protected: struct ModelFrame { char name[16]; - FModelVertex *vertices; - FModelVertex *normals; + DMDModelVertex *vertices; + DMDModelVertex *normals; + unsigned int vindex; }; struct DMDLoDInfo @@ -107,7 +107,6 @@ protected: struct DMDLoD { FTriangle * triangles; - int * glCommands; }; @@ -120,26 +119,27 @@ protected: ModelFrame * frames; DMDLoDInfo lodInfo[MAX_LODS]; DMDLoD lods[MAX_LODS]; - char *vertexUsage; // Bitfield for each vertex. bool allowTexComp; // Allow texture compression with this. - static void RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices); - public: FDMDModel() { loaded = false; frames = NULL; skins = NULL; - lods[0].glCommands = NULL; + for (int i = 0; i < MAX_LODS; i++) + { + lods[i].triangles = NULL; + } info.numLODs = 0; + texCoords = NULL; } virtual ~FDMDModel(); virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); virtual int FindFrame(const char * name); - virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0); - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0); + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void BuildVertexBuffer(FModelVertexBuffer *buf); }; @@ -189,11 +189,15 @@ class FMD3Model : public FModel MD3TexCoord * texcoords; MD3Vertex * vertices; + unsigned int vindex; // contains numframes arrays of vertices + unsigned int iindex; + MD3Surface() { tris=NULL; vertices=NULL; texcoords=NULL; + vindex = iindex = UINT_MAX; } ~MD3Surface() @@ -220,30 +224,20 @@ class FMD3Model : public FModel MD3Frame * frames; MD3Surface * surfaces; - void RenderTriangles(MD3Surface * surf, MD3Vertex * vert); - public: FMD3Model() { } virtual ~FMD3Model(); virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); virtual int FindFrame(const char * name); - virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0); - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0); -}; - -class FVoxelVertexBuffer; - -struct FVoxelVertex -{ - float x,y,z; - float u,v; + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void BuildVertexBuffer(FModelVertexBuffer *buf); }; struct FVoxelVertexHash { // Returns the hash value for a key. - hash_t Hash(const FVoxelVertex &key) + hash_t Hash(const FModelVertex &key) { int ix = xs_RoundToInt(key.x); int iy = xs_RoundToInt(key.y); @@ -252,7 +246,7 @@ struct FVoxelVertexHash } // Compares two keys, returning zero if they are the same. - int Compare(const FVoxelVertex &left, const FVoxelVertex &right) + int Compare(const FModelVertex &left, const FModelVertex &right) { return left.x != right.x || left.y != right.y || left.z != right.z || left.u != right.u || left.v != right.v; } @@ -266,7 +260,7 @@ struct FIndexInit } }; -typedef TMap FVoxelMap; +typedef TMap FVoxelMap; class FVoxelModel : public FModel @@ -274,26 +268,25 @@ class FVoxelModel : public FModel protected: FVoxel *mVoxel; bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object - TArray mVertices; + TArray mVertices; TArray mIndices; - FVoxelVertexBuffer *mVBO; FTexture *mPalette; + unsigned int vindex; + unsigned int iindex; void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check); void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, BYTE color, FVoxelMap &check); - void AddVertex(FVoxelVertex &vert, FVoxelMap &check); + unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check); public: FVoxelModel(FVoxel *voxel, bool owned); ~FVoxelModel(); bool Load(const char * fn, int lumpnum, const char * buffer, int length); void Initialize(); - void MakeGLData(); - void CleanGLData(); virtual int FindFrame(const char * name); - virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0); - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0); + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); FTexture *GetPaletteTexture() const { return mPalette; } + void BuildVertexBuffer(FModelVertexBuffer *buf); }; @@ -341,13 +334,11 @@ struct FSpriteModelFrame class GLSprite; -void gl_InitModels(); FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); -void gl_RenderModel(GLSprite * spr, int cm); +void gl_RenderModel(GLSprite * spr); // [BB] HUD weapon model rendering functions. -void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm); +void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy); bool gl_IsHUDModelForPlayerAvailable (player_t * player); -void gl_CleanModelData(); #endif diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index 244ec064d..3d0fad8aa 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -43,11 +43,13 @@ #include "sc_man.h" #include "m_crc32.h" +#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/scene/gl_drawinfo.h" #include "gl/models/gl_models.h" #include "gl/textures/gl_material.h" #include "gl/shaders/gl_shader.h" +#include "gl/data/gl_vertexbuffer.h" static float avertexnormals[NUMVERTEXNORMALS][3] = { #include "tab_anorms.h" @@ -160,6 +162,8 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length) skins[i] = LoadSkin(path, buffer + info.offsetSkins + i*64); } + texCoords = new FTexCoord[info.numTexCoords]; + memcpy(texCoords, (byte*)buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord)); temp = (char*)buffer + info.offsetFrames; frames = new ModelFrame[info.numFrames]; @@ -170,8 +174,9 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length) dmd_packedVertex_t *pVtx; memcpy(frame->name, pfr->name, sizeof(pfr->name)); - frame->vertices = new FModelVertex[info.numVertices]; - frame->normals = new FModelVertex[info.numVertices]; + frame->vertices = new DMDModelVertex[info.numVertices]; + frame->normals = new DMDModelVertex[info.numVertices]; + frame->vindex = UINT_MAX; // Translate each vertex. for(k = 0, pVtx = pfr->vertices; k < info.numVertices; k++, pVtx++) @@ -191,25 +196,11 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length) for(i = 0; i < info.numLODs; i++) { lodInfo[i].numTriangles = LittleLong(lodInfo[i].numTriangles); - lodInfo[i].numGlCommands = LittleLong(lodInfo[i].numGlCommands); lodInfo[i].offsetTriangles = LittleLong(lodInfo[i].offsetTriangles); - lodInfo[i].offsetGlCommands = LittleLong(lodInfo[i].offsetGlCommands); - triangles[i] = (FTriangle*)(buffer + lodInfo[i].offsetTriangles); - - lods[i].glCommands = new int[lodInfo[i].numGlCommands]; - memcpy(lods[i].glCommands, buffer + lodInfo[i].offsetGlCommands, sizeof(int) * lodInfo[i].numGlCommands); + lods[i].triangles = triangles[i] = (FTriangle*)(buffer + lodInfo[i].offsetTriangles); } - // Determine vertex usage at each LOD level. - vertexUsage = new char[info.numVertices]; - memset(vertexUsage, 0, info.numVertices); - - for(i = 0; i < info.numLODs; i++) - for(k = 0; k < lodInfo[i].numTriangles; k++) - for(c = 0; c < 3; c++) - vertexUsage[short(triangles[i][k].vertexIndices[c])] |= 1 << i; - loaded=true; return true; } @@ -238,12 +229,47 @@ FDMDModel::~FDMDModel() for(i = 0; i < info.numLODs; i++) { - delete [] lods[i].glCommands; + if (lods[i].triangles != NULL) delete[] lods[i].triangles; } - if (vertexUsage != NULL) delete [] vertexUsage; + if (texCoords != NULL) delete[] texCoords; } + +void FDMDModel::BuildVertexBuffer(FModelVertexBuffer *buf) +{ + for (int i = 0; i < info.numFrames; i++) + { + ModelFrame *frame = &frames[i]; + DMDModelVertex *vert = frame->vertices; + DMDModelVertex *norm = frame->normals; + + frame->vindex = buf->vbo_shadowdata.Size(); + + + FTriangle *tri = lods[0].triangles; + + for (int i = 0; i < lodInfo[0].numTriangles; i++) + { + for (int j = 0; j < 3; j++) + { + FModelVertex bvert; + + int ti = tri->textureIndices[j]; + int vi = tri->vertexIndices[j]; + + bvert.Set(vert[vi].xyz[0], vert[vi].xyz[1], vert[vi].xyz[2], (float)texCoords[ti].s /info.skinWidth, (float)texCoords[ti].t/info.skinHeight); + bvert.SetNormal(norm[vi].xyz[0], norm[vi].xyz[1], norm[vi].xyz[2]); + buf->vbo_shadowdata.Push(bvert); + } + tri++; + } + + } +} + + + //=========================================================================== // // FDMDModel::FindFrame @@ -260,115 +286,28 @@ int FDMDModel::FindFrame(const char * name) //=========================================================================== // -// Render a set of GL commands using the given data. +// // //=========================================================================== -void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices) + +void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation) { - char *pos; - FGLCommandVertex * v; - int count; + if (frameno >= info.numFrames || frameno2 >= info.numFrames) return; + + if (!skin) + { + if (info.numSkins == 0) return; + skin = skins[0]; + if (!skin) return; + } + + FMaterial * tex = FMaterial::ValidateTexture(skin, false); + + gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false); gl_RenderState.Apply(); - for(pos = (char*)glCommands; *pos;) - { - count = *(int *) pos; - pos += 4; - - // The type of primitive depends on the sign. - glBegin(count > 0 ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN); - count = abs(count); - - while(count--) - { - v = (FGLCommandVertex *) pos; - pos += sizeof(FGLCommandVertex); - - glTexCoord2fv(&v->s); - glVertex3fv((float*)&vertices[v->index]); - } - - glEnd(); - } -} - - -void FDMDModel::RenderFrame(FTexture * skin, int frameno, int cm, int translation) -{ - int activeLod; - - if (frameno>=info.numFrames) return; - - ModelFrame * frame = &frames[frameno]; - //int mainFlags = mf->flags; - - if (!skin) - { - if (info.numSkins==0) return; - skin = skins[0]; - if (!skin) return; - } - - FMaterial * tex = FMaterial::ValidateTexture(skin); - - tex->Bind(cm, 0, translation); - - int numVerts = info.numVertices; - - // Determine the suitable LOD. - /* - if(info.numLODs > 1 && rend_model_lod != 0) - { - float lodFactor = rend_model_lod * screen->Width() / 640.0f / (GLRenderer->mCurrentFoV / 90.0f); - if(lodFactor) lodFactor = 1 / lodFactor; - - // Determine the LOD we will be using. - activeLod = (int) (lodFactor * spr->distance); - if(activeLod < 0) activeLod = 0; - if(activeLod >= mdl->info.numLODs) activeLod = mdl->info.numLODs - 1; - vertexUsage = mdl->vertexUsage; - } - else - */ - { - activeLod = 0; - } - - RenderGLCommands(lods[activeLod].glCommands, numVerts, frame->vertices/*, modelColors, NULL*/); -} - -void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, int translation) -{ - int activeLod = 0; - - if (frameno>=info.numFrames || frameno2>=info.numFrames) return; - - FModelVertex *vertices1 = frames[frameno].vertices; - FModelVertex *vertices2 = frames[frameno2].vertices; - - if (!skin) - { - if (info.numSkins==0) return; - skin = skins[0]; - if (!skin) return; - } - - FMaterial * tex = FMaterial::ValidateTexture(skin); - - tex->Bind(cm, 0, translation); - - int numVerts = info.numVertices; - - // [BB] Calculate the interpolated vertices by linear interpolation. - FModelVertex *verticesInterpolated = new FModelVertex[numVerts]; - for( int k = 0; k < numVerts; k++ ) - { - for ( int i = 0; i < 3; i++ ) - verticesInterpolated[k].xyz[i] = (1-inter)*vertices1[k].xyz[i]+ (inter)*vertices2[k].xyz[i]; - } - - RenderGLCommands(lods[activeLod].glCommands, numVerts, verticesInterpolated/*, modelColors, NULL*/); - delete[] verticesInterpolated; + GLRenderer->mModelVBO->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, inter); + glDrawArrays(GL_TRIANGLES, 0, lodInfo[0].numTriangles * 3); } @@ -426,7 +365,6 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length) header.magic = MD2_MAGIC; header.version = 8; header.flags = 0; - vertexUsage = NULL; info.skinWidth = LittleLong(md2header->skinWidth); info.skinHeight = LittleLong(md2header->skinHeight); info.frameSize = LittleLong(md2header->frameSize); @@ -458,17 +396,21 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length) // The frames need to be unpacked. md2_frames = (byte*)buffer + info.offsetFrames; - frames = new ModelFrame[info.numFrames]; + texCoords = new FTexCoord[info.numTexCoords]; + memcpy(texCoords, (byte*)buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord)); + + for(i = 0, frame = frames; i < info.numFrames; i++, frame++) { md2_packedFrame_t *pfr = (md2_packedFrame_t *) (md2_frames + info.frameSize * i); md2_triangleVertex_t *pVtx; memcpy(frame->name, pfr->name, sizeof(pfr->name)); - frame->vertices = new FModelVertex[info.numVertices]; - frame->normals = new FModelVertex[info.numVertices]; + frame->vertices = new DMDModelVertex[info.numVertices]; + frame->normals = new DMDModelVertex[info.numVertices]; + frame->vindex = UINT_MAX; // Translate each vertex. for(k = 0, pVtx = pfr->vertices; k < info.numVertices; k++, pVtx++) @@ -487,8 +429,9 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length) } - lods[0].glCommands = new int[lodInfo[0].numGlCommands]; - memcpy(lods[0].glCommands, buffer + lodInfo[0].offsetGlCommands, sizeof(int) * lodInfo[0].numGlCommands); + lods[0].triangles = new FTriangle[lodInfo[0].numTriangles]; + + memcpy(lods[0].triangles, buffer + lodInfo[0].offsetTriangles, sizeof(FTriangle) * lodInfo[0].numTriangles); skins = new FTexture *[info.numSkins]; diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 12509b769..4b1788306 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -42,6 +42,7 @@ #include "m_crc32.h" #include "gl/renderer/gl_renderstate.h" +#include "gl/renderer/gl_renderer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/models/gl_models.h" #include "gl/textures/gl_material.h" @@ -206,6 +207,37 @@ bool FMD3Model::Load(const char * path, int, const char * buffer, int length) return true; } +void FMD3Model::BuildVertexBuffer(FModelVertexBuffer *buf) +{ + for (int i = 0; i < numSurfaces; i++) + { + MD3Surface * surf = &surfaces[i]; + + surf->vindex = buf->vbo_shadowdata.Size(); + surf->iindex = buf->ibo_shadowdata.Size(); + for (int j = 0; j < numFrames * surf->numVertices; j++) + { + MD3Vertex* vert = surf->vertices + j; + + FModelVertex bvert; + + int tc = j % surf->numVertices; + bvert.Set(vert->x, vert->z, vert->y, surf->texcoords[tc].s, surf->texcoords[tc].t); + bvert.SetNormal(vert->nx, vert->nz, vert->ny); + buf->vbo_shadowdata.Push(bvert); + } + + for (int k = 0; k < surf->numTriangles; k++) + { + for (int l = 0; l < 3; l++) + { + buf->ibo_shadowdata.Push(surf->tris[k].VertIndex[l]); + } + } + } +} + + int FMD3Model::FindFrame(const char * name) { for (int i=0;inumTriangles;i++) - { - for(int j=0;j<3;j++) - { - int x = surf->tris[i].VertIndex[j]; - - glTexCoord2fv(&surf->texcoords[x].s); - glVertex3f(vert[x].x, vert[x].z, vert[x].y); - } - } - glEnd(); -} - -void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, int translation) -{ - if (frameno>=numFrames) return; - - MD3Frame * frame = &frames[frameno]; - - // I can't confirm correctness of this because no model I have tested uses this information - // glMatrixMode(GL_MODELVIEW); - // glTranslatef(frame->origin[0], frame->origin[1], frame->origin[2]); - - for(int i=0;inumSkins==0) return; - surfaceSkin = surf->skins[0]; - if (!surfaceSkin) return; - } - - FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin); - - tex->Bind(cm, 0, translation); - RenderTriangles(surf, surf->vertices + frameno * surf->numVertices); - } -} - -void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, int translation) +void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation) { if (frameno>=numFrames || frameno2>=numFrames) return; @@ -281,26 +265,13 @@ void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int framen if (!surfaceSkin) return; } - FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin); + FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin, false); - tex->Bind(cm, 0, translation); + gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false); - MD3Vertex* verticesInterpolated = new MD3Vertex[surfaces[i].numVertices]; - MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices; - MD3Vertex* vertices2 = surf->vertices + frameno2 * surf->numVertices; - - // [BB] Calculate the interpolated vertices by linear interpolation. - for( int k = 0; k < surf->numVertices; k++ ) - { - verticesInterpolated[k].x = (1-inter)*vertices1[k].x+ (inter)*vertices2[k].x; - verticesInterpolated[k].y = (1-inter)*vertices1[k].y+ (inter)*vertices2[k].y; - verticesInterpolated[k].z = (1-inter)*vertices1[k].z+ (inter)*vertices2[k].z; - // [BB] Apparently RenderTriangles doesn't use nx, ny, nz, so don't interpolate them. - } - - RenderTriangles(surf, verticesInterpolated); - - delete[] verticesInterpolated; + gl_RenderState.Apply(); + GLRenderer->mModelVBO->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, inter); + glDrawElements(GL_TRIANGLES, surf->numTriangles * 3, GL_UNSIGNED_INT, (void*)(intptr_t)(surf->iindex * sizeof(unsigned int))); } } diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index f47685216..b1bb4de5a 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -203,92 +203,6 @@ int FVoxelTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, F return 0; } -//=========================================================================== -// -// -// -//=========================================================================== - - -class FVoxelVertexBuffer : public FVertexBuffer -{ - unsigned int ibo_id; - bool isint; - -public: - FVoxelVertexBuffer(TArray &verts, TArray &indices); - ~FVoxelVertexBuffer(); - void BindVBO(); - bool IsInt() const { return isint; } -}; - - -//=========================================================================== -// -// -// -//=========================================================================== - -FVoxelVertexBuffer::FVoxelVertexBuffer(TArray &verts, TArray &indices) -{ - ibo_id = 0; - glGenBuffers(1, &ibo_id); - - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, verts.Size() * sizeof(FVoxelVertex), &verts[0], GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); - if (verts.Size() > 65535) - { - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); - isint = true; - } - else - { - unsigned short *sbuffer = new unsigned short[indices.Size()]; - for(unsigned i=0;ix); - glTexCoordPointer(2,GL_FLOAT, sizeof(FVoxelVertex), &VVO->u); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_INDEX_ARRAY); -} - - - //=========================================================================== // // @@ -299,9 +213,9 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) { mVoxel = voxel; mOwningVoxel = owned; - mVBO = NULL; mPalette = new FVoxelTexture(voxel); Initialize(); + iindex = vindex = UINT_MAX; } //=========================================================================== @@ -312,25 +226,43 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) FVoxelModel::~FVoxelModel() { - CleanGLData(); delete mPalette; if (mOwningVoxel) delete mVoxel; } + +//=========================================================================== +// +// +// +//=========================================================================== + +void FVoxelModel::BuildVertexBuffer(FModelVertexBuffer *buf) +{ + vindex = buf->vbo_shadowdata.Size(); + iindex = buf->ibo_shadowdata.Size(); + + FModelVertex *mv = &buf->vbo_shadowdata[buf->vbo_shadowdata.Reserve(mVertices.Size())]; + unsigned int *mi = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(mIndices.Size())]; + + memcpy(mv, &mVertices[0], sizeof(FModelVertex)* mVertices.Size()); + memcpy(mi, &mIndices[0], sizeof(unsigned int)* mIndices.Size()); +} + //=========================================================================== // // // //=========================================================================== -void FVoxelModel::AddVertex(FVoxelVertex &vert, FVoxelMap &check) +unsigned int FVoxelModel::AddVertex(FModelVertex &vert, FVoxelMap &check) { unsigned int index = check[vert]; if (index == 0xffffffff) { index = check[vert] =mVertices.Push(vert); } - mIndices.Push(index); + return index; } //=========================================================================== @@ -345,8 +277,8 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 float PivotY = mVoxel->Mips[0].PivotY / 256.f; float PivotZ = mVoxel->Mips[0].PivotZ / 256.f; int h = mVoxel->Mips[0].SizeZ; - FVoxelVertex vert; - + FModelVertex vert; + unsigned int indx[4]; vert.u = (((col & 15) * 255 / 16) + 7) / 255.f; vert.v = (((col / 16) * 255 / 16) + 7) / 255.f; @@ -354,23 +286,29 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 vert.x = x1 - PivotX; vert.z = -y1 + PivotY; vert.y = -z1 + PivotZ; - AddVertex(vert, check); + indx[0] = AddVertex(vert, check); vert.x = x2 - PivotX; vert.z = -y2 + PivotY; vert.y = -z2 + PivotZ; - AddVertex(vert, check); + indx[1] = AddVertex(vert, check); vert.x = x4 - PivotX; vert.z = -y4 + PivotY; vert.y = -z4 + PivotZ; - AddVertex(vert, check); + indx[2] = AddVertex(vert, check); vert.x = x3 - PivotX; vert.z = -y3 + PivotY; vert.y = -z3 + PivotZ; - AddVertex(vert, check); + indx[3] = AddVertex(vert, check); + mIndices.Push(indx[0]); + mIndices.Push(indx[1]); + mIndices.Push(indx[3]); + mIndices.Push(indx[1]); + mIndices.Push(indx[3]); + mIndices.Push(indx[2]); } //=========================================================================== @@ -459,32 +397,6 @@ bool FVoxelModel::Load(const char * fn, int lumpnum, const char * buffer, int le return false; // not needed } -//=========================================================================== -// -// -// -//=========================================================================== - -void FVoxelModel::MakeGLData() -{ - mVBO = new FVoxelVertexBuffer(mVertices, mIndices); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FVoxelModel::CleanGLData() -{ - if (mVBO != NULL) - { - delete mVBO; - mVBO = NULL; - } -} - //=========================================================================== // // Voxels don't have frames so always return 0 @@ -498,43 +410,17 @@ int FVoxelModel::FindFrame(const char * name) //=========================================================================== // -// +// Voxels never interpolate between frames, they only have one. // //=========================================================================== -void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translation) +void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation) { - FMaterial * tex = FMaterial::ValidateTexture(skin); - tex->Bind(cm, 0, translation); + FMaterial * tex = FMaterial::ValidateTexture(skin, false); + gl_RenderState.SetMaterial(tex, CLAMP_NOFILTER, translation, -1, false); + gl_RenderState.Apply(); - - if (mVBO == NULL) MakeGLData(); - if (mVBO != NULL) - { - mVBO->BindVBO(); - glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt()? GL_UNSIGNED_INT:GL_UNSIGNED_SHORT, 0); - GLRenderer->mVBO->BindVBO(); - return; - } - - glBegin(GL_QUADS); - for(unsigned i=0;i < mIndices.Size(); i++) - { - FVoxelVertex *vert = &mVertices[mIndices[i]]; - glTexCoord2fv(&vert->u); - glVertex3fv(&vert->x); - } - glEnd(); -} - -//=========================================================================== -// -// Voxels never interpolate between frames -// -//=========================================================================== - -void FVoxelModel::RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation) -{ - RenderFrame(skin, frame, cm, translation); + GLRenderer->mModelVBO->SetupFrame(vindex, vindex, 0.f); + glDrawElements(GL_TRIANGLES, mIndices.Size(), GL_UNSIGNED_INT, (void*)(intptr_t)(iindex * sizeof(unsigned int))); } diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 7c9921108..8126cb5d4 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -13,18 +13,13 @@ enum EColorManipulation CM_INVALID=-1, CM_DEFAULT=0, // untranslated - CM_DESAT0=CM_DEFAULT, - CM_DESAT1, // minimum desaturation - CM_DESAT31=CM_DESAT1+30, // maximum desaturation = grayscale CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap - // special internal values for texture creation - CM_SHADE= 0x10000002, // alpha channel texture + CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer // These are not to be passed to the texture manager CM_LITE = 0x20000000, // special values to handle these items without excessive hacking CM_TORCH= 0x20000010, // These are not real color manipulations - CM_FOGLAYER= 0x20000020, // Sprite shaped fog layer - this is only used as a parameter to FMaterial::BindPatch }; #define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()) @@ -34,14 +29,14 @@ struct FColormap { PalEntry LightColor; // a is saturation (0 full, 31=b/w, other=custom colormap) PalEntry FadeColor; // a is fadedensity>>1 - int colormap; + int desaturation; int blendfactor; void Clear() { LightColor=0xffffff; FadeColor=0; - colormap = CM_DEFAULT; + desaturation = 0; blendfactor=0; } @@ -49,19 +44,14 @@ struct FColormap { LightColor.r=LightColor.g=LightColor.b=0xff; blendfactor=0; + desaturation = 0; } - void GetFixedColormap() - { - Clear(); - colormap = gl_fixedcolormap >= (int)CM_LITE? (int)CM_DEFAULT : gl_fixedcolormap; - } - FColormap & operator=(FDynamicColormap * from) { LightColor = from->Color; - colormap = from->Desaturate>>3; + desaturation = from->Desaturate; FadeColor = from->Fade; blendfactor = from->Color.a; return * this; @@ -70,9 +60,15 @@ struct FColormap void CopyLightColor(FDynamicColormap * from) { LightColor = from->Color; - colormap = from->Desaturate>>3; + desaturation = from->Desaturate; blendfactor = from->Color.a; } + + void Decolorize() // this for 'nocoloredspritelighting' and not the same as desaturation. The normal formula results in a value that's too dark. + { + int v = (LightColor.r + LightColor.g + LightColor.b) / 3; + LightColor.r = LightColor.g = LightColor.b = (255 + v + v) / 3; + } }; diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 9292c765e..a02762eb8 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -72,22 +72,6 @@ CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE); -//========================================================================== -// -// -// -//========================================================================== - -bool gl_BrightmapsActive() -{ - return gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_brightmap_shader); -} - -bool gl_GlowActive() -{ - return gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_glow_shader); -} - //========================================================================== // // Sets up the fog tables @@ -125,7 +109,6 @@ CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL) { if (self>2) self=2; if (self<0) self=0; - if (self == 2 && gl.shadermodel < 4) self = 1; } CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL) @@ -133,7 +116,6 @@ CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL) int newself = self; if (newself > 4) newself=8; // use 8 for software lighting to avoid conflicts with the bit mask if (newself < 0) newself=0; - if ((newself == 2 || newself == 8) && gl.shadermodel < 4) newself = 3; if (self != newself) self = newself; glset.lightmode = newself; } @@ -160,13 +142,18 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend int blendequation = renderops[style.BlendOp&15]; int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE; - if (style.Flags & STYLEF_ColorIsFixed) + if (style.Flags & STYLEF_RedIsAlpha) + { + texturemode = TM_REDTOALPHA; + } + else if (style.Flags & STYLEF_ColorIsFixed) { texturemode = TM_MASK; } else if (style.Flags & STYLEF_InvertSource) { - texturemode = drawopaque? TM_INVERTOPAQUE : TM_INVERT; + // The only place where InvertSource is used is for inverted sprites with the infrared powerup. + texturemode = TM_INVERSE; } if (blendequation == -1) @@ -240,11 +227,11 @@ int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon) // //========================================================================== -PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force) +static PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor) { int r,g,b; - if (glset.lightmode == 8 && !force) + if (glset.lightmode == 8) { return pe; } @@ -256,52 +243,15 @@ PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force) } else { + // This is what Legacy does with colored light in 3D volumes. No, it doesn't really make sense... + // It also doesn't translate well to software style lighting. int mixlight = light * (255 - blendfactor); r = (mixlight + pe.r * blendfactor) / 255; g = (mixlight + pe.g * blendfactor) / 255; b = (mixlight + pe.b * blendfactor) / 255; } - return PalEntry(BYTE(r), BYTE(g), BYTE(b)); -} - -//========================================================================== -// -// Get current light color -// -//========================================================================== -void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float * pred, float * pgreen, float * pblue, bool weapon) -{ - float & r=*pred,& g=*pgreen,& b=*pblue; - int torch=0; - - if (gl_fixedcolormap) - { - if (gl_fixedcolormap==CM_LITE) - { - if (gl_enhanced_nightvision) r=0.375f, g=1.0f, b=0.375f; - else r=g=b=1.0f; - } - else if (gl_fixedcolormap>=CM_TORCH) - { - int flicker=gl_fixedcolormap-CM_TORCH; - r=(0.8f+(7-flicker)/70.0f); - if (r>1.0f) r=1.0f; - b=g=r; - if (gl_enhanced_nightvision) b*=0.75f; - } - else r=g=b=1.0f; - return; - } - - PalEntry lightcolor = cm? cm->LightColor : PalEntry(255,255,255); - int blendfactor = cm? cm->blendfactor : 0; - - lightlevel = gl_CalcLightLevel(lightlevel, rellight, weapon); - PalEntry pe = gl_CalcLightColor(lightlevel, lightcolor, blendfactor); - r = pe.r/255.f; - g = pe.g/255.f; - b = pe.b/255.f; + return PalEntry(255, BYTE(r), BYTE(g), BYTE(b)); } //========================================================================== @@ -309,44 +259,19 @@ void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float // set current light color // //========================================================================== -void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, PalEntry ThingColor, bool weapon) +void gl_SetColor(int sectorlightlevel, int rellight, const FColormap &cm, float alpha, bool weapon) { - float r,g,b; - gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon); - - *red = r * ThingColor.r/255.0f; - *green = g * ThingColor.g/255.0f; - *blue = b * ThingColor.b/255.0f; -} - -//========================================================================== -// -// set current light color -// -//========================================================================== -void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor, bool weapon) -{ - float r,g,b; - - gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon); - - if (glset.lightmode != 8) + if (gl_fixedcolormap != CM_DEFAULT) { - glColor4f(r * ThingColor.r/255.0f, g * ThingColor.g/255.0f, b * ThingColor.b/255.0f, alpha); + gl_RenderState.SetColorAlpha(0xffffff, alpha, 0); + gl_RenderState.SetSoftLightLevel(255); } else - { - glColor4f(r, g, b, alpha); - - if (gl_fixedcolormap) - { - glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); - } - else - { - float lightlevel = gl_CalcLightLevel(light, rellight, weapon) / 255.0f; - glVertexAttrib1f(VATTR_LIGHTLEVEL, lightlevel); - } + { + int hwlightlevel = gl_CalcLightLevel(sectorlightlevel, rellight, weapon); + PalEntry pe = gl_CalcLightColor(hwlightlevel, cm.LightColor, cm.blendfactor); + gl_RenderState.SetColorAlpha(pe, alpha, cm.desaturation); + gl_RenderState.SetSoftLightLevel(gl_ClampLight(sectorlightlevel + rellight)); } } @@ -450,60 +375,61 @@ bool gl_CheckFog(FColormap *cm, int lightlevel) // // Check if the current linedef is a candidate for a fog boundary // +// Requirements for a fog boundary: +// - front sector has no fog +// - back sector has fog +// - at least one of both does not have a sky ceiling. +// //========================================================================== bool gl_CheckFog(sector_t *frontsector, sector_t *backsector) { + if (gl_fixedcolormap) return false; + if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector. + // Check for fog boundaries. This needs a few more checks for the sectors - bool frontfog, backfog; PalEntry fogcolor = frontsector->ColorMap->Fade; if ((fogcolor.d & 0xffffff) == 0) { - frontfog = false; + return false; } else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) { - frontfog = true; } else if (fogdensity!=0 || (glset.lightmode & 4)) { // case 3: level has fog density set - frontfog = true; } else { // case 4: use light level - frontfog = frontsector->lightlevel < 248; + if (frontsector->lightlevel >= 248) return false; } - if (backsector == NULL) return frontfog; - fogcolor = backsector->ColorMap->Fade; if ((fogcolor.d & 0xffffff) == 0) { - backfog = false; } else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) { - backfog = true; + return false; } else if (fogdensity!=0 || (glset.lightmode & 4)) { // case 3: level has fog density set - backfog = true; + return false; } else { // case 4: use light level - backfog = backsector->lightlevel < 248; + if (backsector->lightlevel < 248) return false; } // in all other cases this might create more problems than it solves. - return (frontfog && !backfog && !gl_fixedcolormap && - (frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || + return ((frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || backsector->GetTexture(sector_t::ceiling)!=skyflatnum)); } @@ -515,15 +441,9 @@ bool gl_CheckFog(sector_t *frontsector, sector_t *backsector) void gl_SetShaderLight(float level, float olight) { -#if 1 //ndef _DEBUG const float MAXDIST = 256.f; const float THRESHOLD = 96.f; const float FACTOR = 0.75f; -#else - const float MAXDIST = 256.f; - const float THRESHOLD = 96.f; - const float FACTOR = 2.75f; -#endif if (level > 0) { @@ -603,42 +523,18 @@ void gl_SetFog(int lightlevel, int rellight, const FColormap *cmap, bool isaddit { fogcolor=0; } - // Handle desaturation - if (cmap->colormap != CM_DEFAULT) - gl_ModifyColor(fogcolor.r, fogcolor.g, fogcolor.b, cmap->colormap); gl_RenderState.EnableFog(true); gl_RenderState.SetFog(fogcolor, fogdensity); // Korshun: fullbright fog like in software renderer. if (glset.lightmode == 8 && glset.brightfog && fogdensity != 0 && fogcolor != 0) - glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); + { + gl_RenderState.SetSoftLightLevel(255); + } } } -//========================================================================== -// -// Modifies a color according to a specified colormap -// -//========================================================================== - -void gl_ModifyColor(BYTE & red, BYTE & green, BYTE & blue, int cm) -{ - int gray = (red*77 + green*143 + blue*36)>>8; - if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_MAXCOLORMAP) - { - PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[gray]; - red = pe.r; - green = pe.g; - blue = pe.b; - } - else if (cm >= CM_DESAT1 && cm <= CM_DESAT31) - { - gl_Desaturate(gray, red, green, blue, red, green, blue, cm - CM_DESAT0); - } -} - - //========================================================================== // diff --git a/src/gl/renderer/gl_lightdata.h b/src/gl/renderer/gl_lightdata.h index 33d179b27..f76f732af 100644 --- a/src/gl/renderer/gl_lightdata.h +++ b/src/gl/renderer/gl_lightdata.h @@ -5,9 +5,6 @@ #include "r_data/renderstyle.h" #include "gl/renderer/gl_colormap.h" -bool gl_BrightmapsActive(); -bool gl_GlowActive(); - inline int gl_ClampLight(int lightlevel) { return clamp(lightlevel, 0, 255); @@ -18,10 +15,7 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend void gl_SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefogdensity, int _skyfog); int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon); -PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force = false); -void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float * pred, float * pgreen, float * pblue, bool weapon=false); -void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor = 0xffffff, bool weapon=false); -void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, PalEntry ThingColor=0xffffff, bool weapon=false); +void gl_SetColor(int light, int rellight, const FColormap &cm, float alpha, bool weapon=false); float gl_GetFogDensity(int lightlevel, PalEntry fogcolor); struct sector_t; @@ -47,14 +41,6 @@ inline bool gl_isFullbright(PalEntry color, int lightlevel) return gl_fixedcolormap || (gl_isWhite(color) && lightlevel==255); } -__forceinline void gl_Desaturate(int gray, int ired, int igreen, int iblue, BYTE & red, BYTE & green, BYTE & blue, int fac) -{ - red = (ired*(31-fac) + gray*fac)/31; - green = (igreen*(31-fac) + gray*fac)/31; - blue = (iblue*(31-fac) + gray*fac)/31; -} - -void gl_ModifyColor(BYTE & red, BYTE & green, BYTE & blue, int cm); void gl_DeleteAllAttachedLights(); void gl_RecreateAllAttachedLights(); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 3ce805351..dbf0c10c8 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -52,21 +52,22 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" -#include "gl/system/gl_threads.h" +#include "gl/system/gl_cvars.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/shaders/gl_shader.h" #include "gl/textures/gl_texture.h" #include "gl/textures/gl_translate.h" #include "gl/textures/gl_material.h" +#include "gl/textures/gl_samplers.h" #include "gl/utility/gl_clock.h" #include "gl/utility/gl_templates.h" #include "gl/models/gl_models.h" +#include "gl/dynlights/gl_lightbuffer.h" //=========================================================================== // @@ -74,8 +75,6 @@ // //=========================================================================== -EXTERN_CVAR(Bool, gl_render_segs) - //----------------------------------------------------------------------------- // // Initialize @@ -93,9 +92,11 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mViewVector = FVector2(0,0); mCameraPos = FVector3(0,0,0); mVBO = NULL; + mSkyVBO = NULL; gl_spriteindex = 0; mShaderManager = NULL; - glpart2 = glpart = gllight = mirrortexture = NULL; + glpart2 = glpart = mirrortexture = NULL; + mLights = NULL; } void FGLRenderer::Initialize() @@ -103,27 +104,31 @@ void FGLRenderer::Initialize() glpart2 = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart2.png"), FTexture::TEX_MiscPatch); glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch); mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch); - gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch); mVBO = new FFlatVertexBuffer; + mSkyVBO = new FSkyVertexBuffer; + mModelVBO = new FModelVertexBuffer; + mLights = new FLightBuffer(); + gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; SetupLevel(); mShaderManager = new FShaderManager; - //mThreadManager = new FGLThreadManager; + mSamplerManager = new FSamplerManager; } FGLRenderer::~FGLRenderer() { - gl_CleanModelData(); gl_DeleteAllAttachedLights(); FMaterial::FlushAll(); - //if (mThreadManager != NULL) delete mThreadManager; if (mShaderManager != NULL) delete mShaderManager; + if (mSamplerManager != NULL) delete mSamplerManager; if (mVBO != NULL) delete mVBO; + if (mModelVBO) delete mModelVBO; + if (mSkyVBO != NULL) delete mSkyVBO; + if (mLights != NULL) delete mLights; if (glpart2) delete glpart2; if (glpart) delete glpart; if (mirrortexture) delete mirrortexture; - if (gllight) delete gllight; if (mFBID != 0) glDeleteFramebuffers(1, &mFBID); } @@ -212,13 +217,9 @@ void FGLRenderer::FlushTextures() bool FGLRenderer::StartOffscreen() { - if (gl.flags & RFL_FRAMEBUFFER) - { - if (mFBID == 0) glGenFramebuffers(1, &mFBID); - glBindFramebuffer(GL_FRAMEBUFFER, mFBID); - return true; - } - return false; + if (mFBID == 0) glGenFramebuffers(1, &mFBID); + glBindFramebuffer(GL_FRAMEBUFFER, mFBID); + return true; } //=========================================================================== @@ -229,10 +230,7 @@ bool FGLRenderer::StartOffscreen() void FGLRenderer::EndOffscreen() { - if (gl.flags & RFL_FRAMEBUFFER) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + glBindFramebuffer(GL_FRAMEBUFFER, 0); } //=========================================================================== @@ -243,10 +241,10 @@ void FGLRenderer::EndOffscreen() unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h) { - FMaterial * gltex = FMaterial::ValidateTexture(tex); + FMaterial * gltex = FMaterial::ValidateTexture(tex, false); if (gltex) { - return gltex->CreateTexBuffer(CM_DEFAULT, 0, w, h); + return gltex->CreateTexBuffer(0, w, h); } return NULL; } @@ -269,29 +267,25 @@ void FGLRenderer::ClearBorders() int borderHeight = (trueHeight - height) / 2; glViewport(0, 0, width, trueHeight); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0, width * 1.0, 0.0, trueHeight, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - glColor3f(0.f, 0.f, 0.f); + gl_RenderState.mProjectionMatrix.loadIdentity(); + gl_RenderState.mProjectionMatrix.ortho(0.0f, width * 1.0f, 0.0f, trueHeight, -1.0f, 1.0f); + gl_RenderState.SetColor(0.f ,0.f ,0.f ,1.f); gl_RenderState.Set2DMode(true); gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(true); - - glBegin(GL_QUADS); - // upper quad - glVertex2i(0, borderHeight); - glVertex2i(0, 0); - glVertex2i(width, 0); - glVertex2i(width, borderHeight); - - // lower quad - glVertex2i(0, trueHeight); - glVertex2i(0, trueHeight - borderHeight); - glVertex2i(width, trueHeight - borderHeight); - glVertex2i(width, trueHeight); - glEnd(); + gl_RenderState.Apply(); + gl_RenderState.ApplyMatrices(); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(0, borderHeight, 0, 0, 0); ptr++; + ptr->Set(0, 0, 0, 0, 0); ptr++; + ptr->Set(width, 0, 0, 0, 0); ptr++; + ptr->Set(width, borderHeight, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + ptr->Set(0, trueHeight, 0, 0, 0); ptr++; + ptr->Set(0, trueHeight - borderHeight, 0, 0, 0); ptr++; + ptr->Set(width, trueHeight - borderHeight, 0, 0, 0); ptr++; + ptr->Set(width, trueHeight, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); gl_RenderState.EnableTexture(true); glViewport(0, (trueHeight - height) / 2, width, height); @@ -311,47 +305,45 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) double y = parms.y - parms.top * yscale; double w = parms.destwidth; double h = parms.destheight; - float u1, v1, u2, v2, r, g, b; - float light = 1.f; + float u1, v1, u2, v2; + int light = 255; - FMaterial * gltex = FMaterial::ValidateTexture(img); + FMaterial * gltex = FMaterial::ValidateTexture(img, false); if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0) { // Right now there's only black. Should be implemented properly later - light = 1.f - APART(parms.colorOverlay)/255.f; + light = 255 - APART(parms.colorOverlay); parms.colorOverlay = 0; } if (!img->bHasCanvas) { - if (!parms.alphaChannel) + int translation = 0; + if (!parms.alphaChannel) { - int translation = 0; if (parms.remap != NULL && !parms.remap->Inactive) { GLTranslationPalette * pal = static_cast(parms.remap->GetNative()); if (pal) translation = -pal->GetIndex(); } - gltex->BindPatch(CM_DEFAULT, translation); - } - else - { - // This is an alpha texture - gltex->BindPatch(CM_SHADE, 0); } + gl_SetRenderStyle(parms.style, !parms.masked, false); + gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha)); u1 = gltex->GetUL(); v1 = gltex->GetVT(); u2 = gltex->GetUR(); v2 = gltex->GetVB(); + } else { - gltex->Bind(CM_DEFAULT, 0, 0); - u2=1.f; - v2=-1.f; - u1 = v1 = 0.f; + gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, 0, -1, false); + u1 = 0.f; + v1 = 1.f; + u2 = 1.f; + v2 = 0.f; gl_RenderState.SetTextureMode(TM_OPAQUE); } @@ -372,17 +364,17 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) u2 = float(u2 - (parms.texwidth - parms.windowright) / parms.texwidth); } + PalEntry color; if (parms.style.Flags & STYLEF_ColorIsFixed) { - r = RPART(parms.fillcolor)/255.0f; - g = GPART(parms.fillcolor)/255.0f; - b = BPART(parms.fillcolor)/255.0f; + color = parms.fillcolor; } else { - r = g = b = light; + color = PalEntry(light, light, light); } - + color.a = Scale(parms.alpha, 255, FRACUNIT); + // scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates int btm = (SCREENHEIGHT - screen->GetHeight()) / 2; btm = SCREENHEIGHT - btm; @@ -391,48 +383,33 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) int space = (static_cast(screen)->GetTrueHeight()-screen->GetHeight())/2; glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip); - gl_SetRenderStyle(parms.style, !parms.masked, false); - if (img->bHasCanvas) - { - gl_RenderState.SetTextureMode(TM_OPAQUE); - } - - glColor4f(r, g, b, FIXED2FLOAT(parms.alpha)); - - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.SetColor(color); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(u1, v1); - glVertex2d(x, y); - glTexCoord2f(u1, v2); - glVertex2d(x, y + h); - glTexCoord2f(u2, v1); - glVertex2d(x + w, y); - glTexCoord2f(u2, v2); - glVertex2d(x + w, y + h); - glEnd(); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x, y, 0, u1, v1); ptr++; + ptr->Set(x, y + h, 0, u1, v2); ptr++; + ptr->Set(x + w, y, 0, u2, v1); ptr++; + ptr->Set(x + w, y + h, 0, u2, v2); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); if (parms.colorOverlay) { gl_RenderState.SetTextureMode(TM_MASK); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendEquation(GL_FUNC_ADD); + gl_RenderState.SetColor(PalEntry(parms.colorOverlay)); gl_RenderState.Apply(); - glColor4ub(RPART(parms.colorOverlay),GPART(parms.colorOverlay),BPART(parms.colorOverlay),APART(parms.colorOverlay)); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(u1, v1); - glVertex2d(x, y); - glTexCoord2f(u1, v2); - glVertex2d(x, y + h); - glTexCoord2f(u2, v1); - glVertex2d(x + w, y); - glTexCoord2f(u2, v2); - glVertex2d(x + w, y + h); - glEnd(); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x, y, 0, u1, v1); ptr++; + ptr->Set(x, y + h, 0, u1, v2); ptr++; + ptr->Set(x + w, y, 0, u2, v1); ptr++; + ptr->Set(x + w, y + h, 0, u2, v2); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } - gl_RenderState.EnableAlphaTest(true); - glScissor(0, 0, screen->GetWidth(), screen->GetHeight()); glDisable(GL_SCISSOR_TEST); gl_RenderState.SetTextureMode(TM_MODULATE); @@ -449,12 +426,14 @@ void FGLRenderer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32 { PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor]; gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(true); - glColor3ub(p.r, p.g, p.b); - glBegin(GL_LINES); - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glEnd(); + gl_RenderState.SetColorAlpha(p, 1.f); + gl_RenderState.Apply(); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x1, y1, 0, 0, 0); ptr++; + ptr->Set(x2, y2, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_LINES); + gl_RenderState.EnableTexture(true); } @@ -467,11 +446,13 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color) { PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor]; gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(true); - glColor3ub(p.r, p.g, p.b); - glBegin(GL_POINTS); - glVertex2i(x1, y1); - glEnd(); + gl_RenderState.SetColorAlpha(p, 1.f); + gl_RenderState.Apply(); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x1, y1, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS); + gl_RenderState.EnableTexture(true); } @@ -483,25 +464,19 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color) void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h) { - float r, g, b; - gl_RenderState.EnableTexture(false); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.AlphaFunc(GL_GREATER,0); - gl_RenderState.Apply(true); - - r = color.r/255.0f; - g = color.g/255.0f; - b = color.b/255.0f; - - glBegin(GL_TRIANGLE_FAN); - glColor4f(r, g, b, damount); - glVertex2i(x1, y1); - glVertex2i(x1, y1 + h); - glVertex2i(x1 + w, y1 + h); - glVertex2i(x1 + w, y1); - glEnd(); + gl_RenderState.SetColorAlpha(color, damount); + gl_RenderState.Apply(); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x1, y1, 0, 0, 0); ptr++; + ptr->Set(x1, y1+h, 0, 0, 0); ptr++; + ptr->Set(x1+w, y1+h, 0, 0, 0); ptr++; + ptr->Set(x1+w, y1, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + gl_RenderState.EnableTexture(true); } @@ -514,11 +489,11 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture * { float fU1,fU2,fV1,fV2; - FMaterial *gltexture=FMaterial::ValidateTexture(src); + FMaterial *gltexture=FMaterial::ValidateTexture(src, false); if (!gltexture) return; - gltexture->Bind(CM_DEFAULT, 0, 0); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); // scaling is not used here. if (!local_origin) @@ -535,14 +510,15 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture * fU2 = float(right-left) / src->GetWidth(); fV2 = float(bottom-top) / src->GetHeight(); } + gl_RenderState.ResetColor(); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_STRIP); - glColor4f(1, 1, 1, 1); - glTexCoord2f(fU1, fV1); glVertex2f(left, top); - glTexCoord2f(fU1, fV2); glVertex2f(left, bottom); - glTexCoord2f(fU2, fV1); glVertex2f(right, top); - glTexCoord2f(fU2, fV2); glVertex2f(right, bottom); - glEnd(); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(left, top, 0, fU1, fV1); ptr++; + ptr->Set(left, bottom, 0, fU1, fV2); ptr++; + ptr->Set(right, top, 0, fU2, fV1); ptr++; + ptr->Set(right, bottom, 0, fU2, fV2); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } //========================================================================== @@ -598,7 +574,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint return; } - FMaterial *gltexture = FMaterial::ValidateTexture(texture); + FMaterial *gltexture = FMaterial::ValidateTexture(texture, false); if (gltexture == NULL) { @@ -608,11 +584,9 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint FColormap cm; cm = colormap; - lightlevel = gl_CalcLightLevel(lightlevel, 0, true); - PalEntry pe = gl_CalcLightColor(lightlevel, cm.LightColor, cm.blendfactor, true); - glColor3ub(pe.r, pe.g, pe.b); + gl_SetColor(lightlevel, 0, cm, 1.f); - gltexture->Bind(cm.colormap); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); int i; float rot = float(rotation * M_PI / float(1u << 31)); @@ -632,7 +606,8 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint float oy = float(originy); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); for (i = 0; i < npoints; ++i) { float u = points[i].X - 0.5f - ox; @@ -643,9 +618,9 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint u = t * cosrot - v * sinrot; v = v * cosrot + t * sinrot; } - glTexCoord2f(u * uscale, v * vscale); - glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0); + ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale); + ptr++; } - glEnd(); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 8db9cb195..90f2c4a46 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -9,12 +9,15 @@ struct particle_t; class FCanvasTexture; class FFlatVertexBuffer; +class FSkyVertexBuffer; +class FModelVertexBuffer; class OpenGLFrameBuffer; struct FDrawInfo; struct pspdef_t; class FShaderManager; class GLPortal; -class FGLThreadManager; +class FLightBuffer; +class FSamplerManager; enum SectorRenderFlags { @@ -53,15 +56,14 @@ public: float mCurrentFoV; AActor *mViewActor; FShaderManager *mShaderManager; - FGLThreadManager *mThreadManager; + FSamplerManager *mSamplerManager; int gl_spriteindex; unsigned int mFBID; FTexture *glpart2; FTexture *glpart; FTexture *mirrortexture; - FTexture *gllight; - + float mSky1Pos, mSky2Pos; FRotator mAngles; @@ -69,6 +71,9 @@ public: FVector3 mCameraPos; FFlatVertexBuffer *mVBO; + FSkyVertexBuffer *mSkyVBO; + FModelVertexBuffer *mModelVBO; + FLightBuffer *mLights; FGLRenderer(OpenGLFrameBuffer *fb); @@ -91,7 +96,7 @@ public: void DrawScene(bool toscreen = false); void DrawBlend(sector_t * viewsector); - void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep, int OverrideShader); + void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, bool hudModelStep, int OverrideShader, bool alphatexture); void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep); void DrawTargeterSprites(); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 8c31e191d..bdd0867b9 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -38,23 +38,28 @@ ** */ +#include "templates.h" #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_shader.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_colormap.h" +#include "gl/dynlights//gl_lightbuffer.h" void gl_SetTextureMode(int type); FRenderState gl_RenderState; -int FStateAttr::ChangeCounter; CVAR(Bool, gl_direct_state_change, true, 0) +static VSMatrix identityMatrix(1); +TArray gl_MatrixStack; + //========================================================================== // // @@ -64,78 +69,29 @@ CVAR(Bool, gl_direct_state_change, true, 0) void FRenderState::Reset() { mTextureEnabled = true; - mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false; - ffTextureEnabled = ffFogEnabled = false; - mSpecialEffect = ffSpecialEffect = EFF_NONE; - mFogColor.d = ffFogColor.d = -1; - mFogDensity = ffFogDensity = 0; - mTextureMode = ffTextureMode = -1; + mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; + mFogColor.d = -1; + mTextureMode = -1; + mLightIndex = -1; + mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA; - glSrcBlend = glDstBlend = -1; - glAlphaFunc = -1; - mAlphaFunc = GL_GEQUAL; mAlphaThreshold = 0.5f; mBlendEquation = GL_FUNC_ADD; - glBlendEquation = -1; + mObjectColor = 0xffffffff; m2D = true; + mVertexBuffer = mCurrentVertexBuffer = NULL; + mColormapState = CM_DEFAULT; + mLightParms[3] = -1.f; + mSpecialEffect = EFF_NONE; + mClipHeightTop = 65536.f; + mClipHeightBottom = -65536.f; + + stSrcBlend = stDstBlend = -1; + stBlendEquation = -1; + stAlphaThreshold = -1.f; } - -//========================================================================== -// -// Set texture shader info -// -//========================================================================== - -int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime) -{ - bool usecmshader; - int softwarewarp = 0; - - if (shaderindex == 3) - { - // Brightmap should not be used. - if (!mBrightmapEnabled || cm >= CM_FIRSTSPECIALCOLORMAP) - { - shaderindex = 0; - } - } - - if (gl.shadermodel == 4) - { - usecmshader = cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK; - } - else if (gl.shadermodel == 3) - { - usecmshader = (cameratexture || gl_colormap_shader) && - cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK; - - if (!gl_brightmap_shader && shaderindex == 3) - { - shaderindex = 0; - } - else if (!gl_warp_shader && shaderindex !=3) - { - if (shaderindex <= 2) softwarewarp = shaderindex; - shaderindex = 0; - } - } - else - { - usecmshader = cameratexture; - softwarewarp = shaderindex > 0 && shaderindex < 3? shaderindex : 0; - shaderindex = 0; - } - - mEffectState = shaderindex; - mColormapState = usecmshader? cm : CM_DEFAULT; - if (usecmshader) cm = CM_DEFAULT; - mWarpTime = warptime; - return softwarewarp; -} - - //========================================================================== // // Apply shader settings @@ -144,124 +100,134 @@ int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, flo bool FRenderState::ApplyShader() { - bool useshaders = false; - FShader *activeShader = NULL; - - if (mSpecialEffect > 0 && gl.shadermodel > 2) + if (mSpecialEffect > EFF_NONE) { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); } else { - switch (gl.shadermodel) + activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f); + activeShader->Bind(); + } + + int fogset = 0; + + if (mFogEnabled) + { + if ((mFogColor & 0xffffff) == 0) { - case 2: - useshaders = (mTextureEnabled && mColormapState != CM_DEFAULT); - break; - - case 3: - useshaders = ( - mEffectState != 0 || // special shaders - (mFogEnabled && (gl_fogmode == 2 || gl_fog_shader) && gl_fogmode != 0) || // fog requires a shader - (mTextureEnabled && (mEffectState != 0 || mColormapState)) || // colormap - mGlowEnabled // glow requires a shader - ); - break; - - case 4: - useshaders = (!m2D || mEffectState != 0 || mColormapState); // all 3D rendering and 2D with texture effects. - break; - - default: - break; + fogset = gl_fogmode; } - - if (useshaders) + else { - FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4); - - if (shd != NULL) - { - activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); - } + fogset = -gl_fogmode; } } - if (activeShader) + glVertexAttrib4fv(VATTR_COLOR, mColor.vec); + + activeShader->muDesaturation.Set(mDesaturation / 255.f); + activeShader->muFogEnabled.Set(fogset); + activeShader->muTextureMode.Set(mTextureMode); + activeShader->muCameraPos.Set(mCameraPos.vec); + activeShader->muLightParms.Set(mLightParms); + activeShader->muFogColor.Set(mFogColor); + activeShader->muObjectColor.Set(mObjectColor); + activeShader->muDynLightColor.Set(mDynColor.vec); + activeShader->muInterpolationFactor.Set(mInterpolationFactor); + activeShader->muClipHeightTop.Set(mClipHeightTop); + activeShader->muClipHeightBottom.Set(mClipHeightBottom); + activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f); + activeShader->muAlphaThreshold.Set(mAlphaThreshold); + activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now + + if (mGlowEnabled) { - int fogset = 0; - if (mFogEnabled) + activeShader->muGlowTopColor.Set(mGlowTop.vec); + activeShader->muGlowBottomColor.Set(mGlowBottom.vec); + activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec); + activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec); + activeShader->currentglowstate = 1; + } + else if (activeShader->currentglowstate) + { + // if glowing is on, disable it. + static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f }; + activeShader->muGlowTopColor.Set(nulvec); + activeShader->muGlowBottomColor.Set(nulvec); + activeShader->muGlowTopPlane.Set(nulvec); + activeShader->muGlowBottomPlane.Set(nulvec); + activeShader->currentglowstate = 0; + } + + if (mColormapState != activeShader->currentfixedcolormap) + { + float r, g, b; + activeShader->currentfixedcolormap = mColormapState; + if (mColormapState == CM_DEFAULT) { - if ((mFogColor & 0xffffff) == 0) + activeShader->muFixedColormap.Set(0); + } + else if (mColormapState < CM_MAXCOLORMAP) + { + FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; + float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], + scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; + + activeShader->muFixedColormap.Set(1); + activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); + activeShader->muColormapRange.Set(m); + } + else if (mColormapState == CM_FOGLAYER) + { + activeShader->muFixedColormap.Set(3); + } + else if (mColormapState == CM_LITE) + { + if (gl_enhanced_nightvision) { - fogset = gl_fogmode; + r = 0.375f, g = 1.0f, b = 0.375f; } else { - fogset = -gl_fogmode; + r = g = b = 1.f; } + activeShader->muFixedColormap.Set(2); + activeShader->muColormapStart.Set(r, g, b, 1.f); } - - if (fogset != activeShader->currentfogenabled) + else if (mColormapState >= CM_TORCH) { - glUniform1i(activeShader->fogenabled_index, (activeShader->currentfogenabled = fogset)); + int flicker = mColormapState - CM_TORCH; + r = (0.8f + (7 - flicker) / 70.0f); + if (r > 1.0f) r = 1.0f; + b = g = r; + if (gl_enhanced_nightvision) b = g * 0.75f; + activeShader->muFixedColormap.Set(2); + activeShader->muColormapStart.Set(r, g, b, 1.f); } - if (mTextureMode != activeShader->currenttexturemode) - { - glUniform1i(activeShader->texturemode_index, (activeShader->currenttexturemode = mTextureMode)); - } - if (activeShader->currentcamerapos.Update(&mCameraPos)) - { - glUniform3fv(activeShader->camerapos_index, 1, mCameraPos.vec); - } - /*if (mLightParms[0] != activeShader->currentlightfactor || - mLightParms[1] != activeShader->currentlightdist || - mFogDensity != activeShader->currentfogdensity)*/ - { - const float LOG2E = 1.442692f; // = 1/log(2) - //activeShader->currentlightdist = mLightParms[1]; - //activeShader->currentlightfactor = mLightParms[0]; - //activeShader->currentfogdensity = mFogDensity; - // premultiply the density with as much as possible here to reduce shader - // execution time. - glVertexAttrib4f(VATTR_FOGPARAMS, mLightParms[0], mLightParms[1], mFogDensity * (-LOG2E / 64000.f), 0); - } - if (mFogColor != activeShader->currentfogcolor) - { - activeShader->currentfogcolor = mFogColor; - - glUniform4f (activeShader->fogcolor_index, mFogColor.r/255.f, mFogColor.g/255.f, - mFogColor.b/255.f, 0); - } - if (mGlowEnabled) - { - glUniform4fv(activeShader->glowtopcolor_index, 1, mGlowTop.vec); - glUniform4fv(activeShader->glowbottomcolor_index, 1, mGlowBottom.vec); - glUniform4fv(activeShader->glowtopplane_index, 1, mGlowTopPlane.vec); - glUniform4fv(activeShader->glowbottomplane_index, 1, mGlowBottomPlane.vec); - activeShader->currentglowstate = 1; - } - else if (activeShader->currentglowstate) - { - // if glowing is on, disable it. - glUniform4f(activeShader->glowtopcolor_index, 0.f, 0.f, 0.f, 0.f); - glUniform4f(activeShader->glowbottomcolor_index, 0.f, 0.f, 0.f, 0.f); - activeShader->currentglowstate = 0; - } - - if (mLightEnabled) - { - glUniform3iv(activeShader->lightrange_index, 1, mNumLights); - glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData); - } - if (glset.lightmode == 8) - { - glUniform3fv(activeShader->dlightcolor_index, 1, mDynLight); - } - - return true; } - return false; + if (mTextureMatrixEnabled) + { + mTextureMatrix.matrixToGL(activeShader->texturematrix_index); + activeShader->currentTextureMatrixState = true; + } + else if (activeShader->currentTextureMatrixState) + { + activeShader->currentTextureMatrixState = false; + identityMatrix.matrixToGL(activeShader->texturematrix_index); + } + + if (mModelMatrixEnabled) + { + mModelMatrix.matrixToGL(activeShader->modelmatrix_index); + activeShader->currentModelMatrixState = true; + } + else if (activeShader->currentModelMatrixState) + { + activeShader->currentModelMatrixState = false; + identityMatrix.matrixToGL(activeShader->modelmatrix_index); + } + return true; } @@ -271,96 +237,47 @@ bool FRenderState::ApplyShader() // //========================================================================== -void FRenderState::Apply(bool forcenoshader) +void FRenderState::Apply() { if (!gl_direct_state_change) { - if (mSrcBlend != glSrcBlend || mDstBlend != glDstBlend) + if (mSrcBlend != stSrcBlend || mDstBlend != stDstBlend) { - glSrcBlend = mSrcBlend; - glDstBlend = mDstBlend; + stSrcBlend = mSrcBlend; + stDstBlend = mDstBlend; glBlendFunc(mSrcBlend, mDstBlend); } - if (mAlphaFunc != glAlphaFunc || mAlphaThreshold != glAlphaThreshold) + if (mBlendEquation != stBlendEquation) { - glAlphaFunc = mAlphaFunc; - glAlphaThreshold = mAlphaThreshold; - ::glAlphaFunc(mAlphaFunc, mAlphaThreshold); - } - if (mAlphaTest != glAlphaTest) - { - glAlphaTest = mAlphaTest; - if (mAlphaTest) glEnable(GL_ALPHA_TEST); - else glDisable(GL_ALPHA_TEST); - } - if (mBlendEquation != glBlendEquation) - { - glBlendEquation = mBlendEquation; - ::glBlendEquation(mBlendEquation); + stBlendEquation = mBlendEquation; + glBlendEquation(mBlendEquation); } } - if (forcenoshader || !ApplyShader()) + if (mVertexBuffer != mCurrentVertexBuffer) { - GLRenderer->mShaderManager->SetActiveShader(NULL); - if (mTextureMode != ffTextureMode) - { - gl_SetTextureMode((ffTextureMode = mTextureMode)); - } - if (mTextureEnabled != ffTextureEnabled) - { - if ((ffTextureEnabled = mTextureEnabled)) glEnable(GL_TEXTURE_2D); - else glDisable(GL_TEXTURE_2D); - } - if (mFogEnabled != ffFogEnabled) - { - if ((ffFogEnabled = mFogEnabled)) - { - glEnable(GL_FOG); - } - else glDisable(GL_FOG); - } - if (mFogEnabled) - { - if (ffFogColor != mFogColor) - { - ffFogColor = mFogColor; - GLfloat FogColor[4]={mFogColor.r/255.0f,mFogColor.g/255.0f,mFogColor.b/255.0f,0.0f}; - glFogfv(GL_FOG_COLOR, FogColor); - } - if (ffFogDensity != mFogDensity) - { - glFogf(GL_FOG_DENSITY, mFogDensity/64000.f); - ffFogDensity=mFogDensity; - } - } - if (mSpecialEffect != ffSpecialEffect) - { - switch (ffSpecialEffect) - { - case EFF_SPHEREMAP: - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_S); - - default: - break; - } - switch (mSpecialEffect) - { - case EFF_SPHEREMAP: - // Use sphere mapping for this - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_S); - glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); - glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); - break; - - default: - break; - } - ffSpecialEffect = mSpecialEffect; - } + if (mVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0); + else mVertexBuffer->BindVBO(); + mCurrentVertexBuffer = mVertexBuffer; } - + ApplyShader(); } + + +void FRenderState::ApplyMatrices() +{ + if (GLRenderer->mShaderManager != NULL) + { + GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix); + } +} + +void FRenderState::ApplyLightIndex(int index) +{ + if (GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER && index > -1) + { + index = GLRenderer->mLights->BindUBO(index); + } + activeShader->muLightIndex.Set(index); +} \ No newline at end of file diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 061f5c2df..e0f5406dd 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -2,86 +2,43 @@ #define __GL_RENDERSTATE_H #include +#include "gl/system/gl_interface.h" +#include "gl/data/gl_data.h" +#include "gl/data/gl_matrix.h" +#include "gl/textures/gl_material.h" #include "c_cvars.h" #include "r_defs.h" +#include "r_data/r_translate.h" + +class FVertexBuffer; +class FShader; +extern TArray gl_MatrixStack; EXTERN_CVAR(Bool, gl_direct_state_change) -struct FStateAttr -{ - static int ChangeCounter; - int mLastChange; - - FStateAttr() - { - mLastChange = -1; - } - - bool operator == (const FStateAttr &other) - { - return mLastChange == other.mLastChange; - } - - bool operator != (const FStateAttr &other) - { - return mLastChange != other.mLastChange; - } - -}; - -struct FStateVec3 : public FStateAttr -{ - float vec[3]; - - bool Update(FStateVec3 *other) - { - if (mLastChange != other->mLastChange) - { - *this = *other; - return true; - } - return false; - } - - void Set(float x, float y, float z) - { - vec[0] = x; - vec[1] = z; - vec[2] = y; - mLastChange = ++ChangeCounter; - } -}; - -struct FStateVec4 : public FStateAttr +struct FStateVec4 { float vec[4]; - bool Update(FStateVec4 *other) - { - if (mLastChange != other->mLastChange) - { - *this = *other; - return true; - } - return false; - } - void Set(float r, float g, float b, float a) { vec[0] = r; vec[1] = g; vec[2] = b; vec[3] = a; - mLastChange = ++ChangeCounter; } }; enum EEffect { - EFF_NONE, + EFF_NONE=-1, EFF_FOGBOUNDARY, EFF_SPHEREMAP, + EFF_BURN, + EFF_STENCIL, + + MAX_EFFECTS }; class FRenderState @@ -89,47 +46,52 @@ class FRenderState bool mTextureEnabled; bool mFogEnabled; bool mGlowEnabled; - bool mLightEnabled; bool mBrightmapEnabled; + int mLightIndex; int mSpecialEffect; int mTextureMode; - float mDynLight[3]; - float mLightParms[2]; - int mNumLights[3]; - float *mLightData; + int mDesaturation; + int mSoftLight; + float mLightParms[4]; int mSrcBlend, mDstBlend; - int mAlphaFunc; float mAlphaThreshold; - bool mAlphaTest; int mBlendEquation; + bool mAlphaTest; bool m2D; + bool mModelMatrixEnabled; + bool mTextureMatrixEnabled; + float mInterpolationFactor; + float mClipHeightTop, mClipHeightBottom; + float mShaderTimer; - FStateVec3 mCameraPos; + FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; + FStateVec4 mColor; + FStateVec4 mCameraPos; FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTopPlane, mGlowBottomPlane; PalEntry mFogColor; - float mFogDensity; + PalEntry mObjectColor; + FStateVec4 mDynColor; int mEffectState; int mColormapState; - float mWarpTime; - int glSrcBlend, glDstBlend; - int glAlphaFunc; - float glAlphaThreshold; - bool glAlphaTest; - int glBlendEquation; + float stAlphaThreshold; + int stSrcBlend, stDstBlend; + bool stAlphaTest; + int stBlendEquation; - bool ffTextureEnabled; - bool ffFogEnabled; - int ffTextureMode; - int ffSpecialEffect; - PalEntry ffFogColor; - float ffFogDensity; + FShader *activeShader; bool ApplyShader(); public: + + VSMatrix mProjectionMatrix; + VSMatrix mViewMatrix; + VSMatrix mModelMatrix; + VSMatrix mTextureMatrix; + FRenderState() { Reset(); @@ -137,8 +99,78 @@ public: void Reset(); - int SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime); - void Apply(bool forcenoshader = false); + void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) + { + // textures without their own palette are a special case for use as an alpha texture: + // They use the color index directly as an alpha value instead of using the palette's red. + // To handle this case, we need to set a special translation for such textures. + if (alphatexture) + { + if (mat->tex->UseBasePalette()) translation = TRANSLATION(TRANSLATION_Standard, 8); + } + mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex; + mShaderTimer = mat->tex->gl_info.shaderspeed; + mat->Bind(clampmode, translation); + } + + void Apply(); + void ApplyMatrices(); + void ApplyLightIndex(int index); + + void SetVertexBuffer(FVertexBuffer *vb) + { + mVertexBuffer = vb; + } + + void ResetVertexBuffer() + { + // forces rebinding with the next 'apply' call. + mCurrentVertexBuffer = NULL; + } + + void SetClipHeightTop(float clip) + { + mClipHeightTop = clip; + } + + float GetClipHeightTop() + { + return mClipHeightTop; + } + + void SetClipHeightBottom(float clip) + { + mClipHeightBottom = clip; + } + + float GetClipHeightBottom() + { + return mClipHeightBottom; + } + + void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) + { + mColor.Set(r, g, b, a); + mDesaturation = desat; + } + + void SetColor(PalEntry pe, int desat = 0) + { + mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, pe.a/255.f); + mDesaturation = desat; + } + + void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0) + { + mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, alpha); + mDesaturation = desat; + } + + void ResetColor() + { + mColor.Set(1,1,1,1); + mDesaturation = 0; + } void SetTextureMode(int mode) { @@ -165,9 +197,9 @@ public: mGlowEnabled = on; } - void EnableLight(bool on) + void SetLightIndex(int n) { - mLightEnabled = on; + mLightIndex = n; } void EnableBrightmap(bool on) @@ -175,9 +207,19 @@ public: mBrightmapEnabled = on; } + void EnableModelMatrix(bool on) + { + mModelMatrixEnabled = on; + } + + void EnableTextureMatrix(bool on) + { + mTextureMatrixEnabled = on; + } + void SetCameraPos(float x, float y, float z) { - mCameraPos.Set(x,y,z); + mCameraPos.Set(x, z, y, 0); } void SetGlowParams(float *t, float *b) @@ -186,6 +228,12 @@ public: mGlowBottom.Set(b[0], b[1], b[2], b[3]); } + void SetSoftLightLevel(int level) + { + if (glset.lightmode == 8) mLightParms[3] = level / 255.f; + else mLightParms[3] = -1.f; + } + void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom) { mGlowTopPlane.Set(FIXED2FLOAT(top.a), FIXED2FLOAT(top.b), FIXED2FLOAT(top.ic), FIXED2FLOAT(top.d)); @@ -194,29 +242,25 @@ public: void SetDynLight(float r, float g, float b) { - mDynLight[0] = r; - mDynLight[1] = g; - mDynLight[2] = b; + mDynColor.Set(r, g, b, 0); + } + + void SetObjectColor(PalEntry pe) + { + mObjectColor = pe; } void SetFog(PalEntry c, float d) { + const float LOG2E = 1.442692f; // = 1/log(2) mFogColor = c; - if (d >= 0.0f) mFogDensity = d; + if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f); } void SetLightParms(float f, float d) { - mLightParms[0] = f; - mLightParms[1] = d; - } - - void SetLights(int *numlights, float *lightdata) - { - mNumLights[0] = numlights[0]; - mNumLights[1] = numlights[1]; - mNumLights[2] = numlights[2]; - mLightData = lightdata; // caution: the data must be preserved by the caller until the 'apply' call! + mLightParms[1] = f; + mLightParms[0] = d; } void SetFixedColormap(int cm) @@ -244,28 +288,8 @@ public: void AlphaFunc(int func, float thresh) { - if (!gl_direct_state_change) - { - mAlphaFunc = func; - mAlphaThreshold = thresh; - } - else - { - ::glAlphaFunc(func, thresh); - } - } - - void EnableAlphaTest(bool on) - { - if (!gl_direct_state_change) - { - mAlphaTest = on; - } - else - { - if (on) glEnable(GL_ALPHA_TEST); - else glDisable(GL_ALPHA_TEST); - } + if (func == GL_GREATER) mAlphaThreshold = thresh; + else mAlphaThreshold = thresh - 0.001f; } void BlendEquation(int eq) @@ -276,7 +300,7 @@ public: } else { - ::glBlendEquation(eq); + glBlendEquation(eq); } } @@ -284,6 +308,11 @@ public: { m2D = on; } + + void SetInterpolationFactor(float fac) + { + mInterpolationFactor = fac; + } }; extern FRenderState gl_RenderState; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 5bdb99b88..4de31bd61 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -186,20 +186,9 @@ static void AddLine (seg_t *seg) { SetupWall.Clock(); - //if (!gl_multithreading) - { - GLWall wall; - wall.sub = currentsubsector; - wall.Process(seg, currentsector, backsector); - } - /* - else - { - FJob *job = new FGLJobProcessWall(currentsubsector, seg, - currentsector->sectornum, backsector != NULL? backsector->sectornum : -1); - GLRenderer->mThreadManager->AddJob(job); - } - */ + GLWall wall; + wall.sub = currentsubsector; + wall.Process(seg, currentsector, backsector); rendered_lines++; SetupWall.Unclock(); @@ -341,21 +330,11 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector) sector_t * sec=sub->sector; if (sec->thinglist != NULL) { - //if (!gl_multithreading) + // Handle all things in sector. + for (AActor * thing = sec->thinglist; thing; thing = thing->snext) { - // Handle all things in sector. - for (AActor * thing = sec->thinglist; thing; thing = thing->snext) - { - GLRenderer->ProcessSprite(thing, sector); - } + GLRenderer->ProcessSprite(thing, sector); } - /* - else if (sec->thinglist != NULL) - { - FJob *job = new FGLJobProcessSprites(sector); - GLRenderer->mThreadManager->AddJob(job); - } - */ } SetupSprite.Unclock(); } @@ -416,20 +395,10 @@ static void DoSubsector(subsector_t * sub) { SetupSprite.Clock(); - //if (!gl_multithreading) + for (i = ParticlesInSubsec[DWORD(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext) { - for (i = ParticlesInSubsec[DWORD(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext) - { - GLRenderer->ProcessParticle(&Particles[i], fakesector); - } + GLRenderer->ProcessParticle(&Particles[i], fakesector); } - /* - else if (ParticlesInSubsec[DWORD(sub-subsectors)] != NO_PARTICLE) - { - FJob job = new FGLJobProcessParticles(sub); - GLRenderer->mThreadManager->AddJob(job); - } - */ SetupSprite.Unclock(); } @@ -476,17 +445,7 @@ static void DoSubsector(subsector_t * sub) srf |= SSRF_PROCESSED; SetupFlat.Clock(); - //if (!gl_multithreading) - { - GLRenderer->ProcessSector(fakesector); - } - /* - else - { - FJob *job = new FGLJobProcessFlats(sub); - GLRenderer->mThreadManager->AddJob(job); - } - */ + GLRenderer->ProcessSector(fakesector); SetupFlat.Unclock(); } // mark subsector as processed - but mark for rendering only if it has an actual area. diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index bd39f8008..c938e9043 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -45,6 +45,7 @@ #include "gl/system/gl_cvars.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" @@ -74,7 +75,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) int light; int rel; float a; - bool flipx, flipy, loadAlpha; + bool flipx, flipy; DecalVertex dv[4]; FTextureID decalTile; @@ -102,17 +103,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) FMaterial *tex; - if (texture->UseType == FTexture::TEX_MiscPatch) - { - // We need to create a clone of this texture where we can force the - // texture filtering offset in. - if (texture->gl_info.DecalTexture == NULL) - { - texture->gl_info.DecalTexture = new FCloneTexture(texture, FTexture::TEX_Decal); - } - tex = FMaterial::ValidateTexture(texture->gl_info.DecalTexture); - } - else tex = FMaterial::ValidateTexture(texture); + tex = FMaterial::ValidateTexture(texture, true); // the sectors are only used for their texture origin coordinates @@ -179,78 +170,22 @@ void GLWall::DrawDecal(DBaseDecal *decal) rel = rellight + getExtraLight(); } - int r = RPART(decal->AlphaColor); - int g = GPART(decal->AlphaColor); - int b = BPART(decal->AlphaColor); FColormap p = Colormap; if (glset.nocoloredspritelighting) { - int v = (Colormap.LightColor.r * 77 + Colormap.LightColor.g*143 + Colormap.LightColor.b*35)/255; - p.LightColor = PalEntry(p.colormap, v, v, v); + p.Decolorize(); } - float red, green, blue; - - if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha) - { - loadAlpha = true; - p.colormap=CM_SHADE; - - if (glset.lightmode != 8) - { - gl_GetLightColor(light, rel, &p, &red, &green, &blue); - } - else - { - gl_GetLightColor(lightlevel, rellight, &p, &red, &green, &blue); - } - - if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites) - { - float result[3]; - fixed_t x, y; - decal->GetXY(seg->sidedef, x, y); - gl_GetSpriteLight(NULL, x, y, zpos, sub, Colormap.colormap-CM_DESAT0, result, line, side == line->sidedef[0]? 0:1); - if (glset.lightmode != 8) - { - red = clamp(result[0]+red, 0, 1.0f); - green = clamp(result[1]+green, 0, 1.0f); - blue = clamp(result[2]+blue, 0, 1.0f); - } - else - { - gl_RenderState.SetDynLight(result[0], result[1], result[2]); - } - } - - BYTE R = xs_RoundToInt(r * red); - BYTE G = xs_RoundToInt(g * green); - BYTE B = xs_RoundToInt(b * blue); - - gl_ModifyColor(R,G,B, Colormap.colormap); - - red = R/255.f; - green = G/255.f; - blue = B/255.f; - } - else - { - loadAlpha = false; - - red = 1.f; - green = 1.f; - blue = 1.f; - } a = FIXED2FLOAT(decal->Alpha); // now clip the decal to the actual polygon - float decalwidth = tex->TextureWidth(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX); - float decalheight= tex->TextureHeight(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY); - float decallefto = tex->GetLeftOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX); - float decaltopo = tex->GetTopOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY); + float decalwidth = tex->TextureWidth() * FIXED2FLOAT(decal->ScaleX); + float decalheight= tex->TextureHeight() * FIXED2FLOAT(decal->ScaleY); + float decallefto = tex->GetLeftOffset() * FIXED2FLOAT(decal->ScaleX); + float decaltopo = tex->GetTopOffset() * FIXED2FLOAT(decal->ScaleY); float leftedge = glseg.fracleft * side->TexelLength; @@ -299,8 +234,6 @@ void GLWall::DrawDecal(DBaseDecal *decal) zpos+= FRACUNIT*(flipy? decalheight-decaltopo : decaltopo); - tex->BindPatch(p.colormap, decal->Translation); - dv[1].z=dv[2].z = FIXED2FLOAT(zpos); dv[0].z=dv[3].z = dv[1].z - decalheight; dv[1].v=dv[2].v = tex->GetVT(); @@ -359,32 +292,25 @@ void GLWall::DrawDecal(DBaseDecal *decal) float vb = tex->GetVB(); for(i=0;i<4;i++) dv[i].v=vb-dv[i].v; } - // fog is set once per wall in the calling function and not per decal! - if (loadAlpha) + // calculate dynamic light effect. + if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites) { - glColor4f(red, green, blue, a); - - if (glset.lightmode == 8) - { - if (gl_fixedcolormap) - glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); - else - glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(light, rel, false) / 255.0); - } - } - else - { - if (glset.lightmode == 8) - { - gl_SetColor(light, rel, &p, a, extralight); // Korshun. - } - else - { - gl_SetColor(light, rel, &p, a); - } + // Note: This should be replaced with proper shader based lighting. + fixed_t x, y; + decal->GetXY(seg->sidedef, x, y); + gl_SetDynSpriteLight(NULL, x, y, zpos, sub); } + // alpha color only has an effect when using an alpha texture. + if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha) + { + gl_RenderState.SetObjectColor(decal->AlphaColor); + } + + gl_SetColor(light, rel, p, a); + + // for additively drawn decals we must temporarily set the fog color to black. PalEntry fc = gl_RenderState.GetFogColor(); if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One) { @@ -393,20 +319,25 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_SetRenderStyle(decal->RenderStyle, false, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha)); + // If srcalpha is one it looks better with a higher alpha threshold - if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); else gl_RenderState.AlphaFunc(GL_GREATER, 0.f); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - for(i=0;i<4;i++) + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (i = 0; i < 4; i++) { - glTexCoord2f(dv[i].u,dv[i].v); - glVertex3f(dv[i].x,dv[i].z,dv[i].y); + ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); + ptr++; } - glEnd(); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + rendered_decals++; + gl_RenderState.SetTextureMode(TM_MODULATE); + gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetFog(fc,-1); gl_RenderState.SetDynLight(0,0,0); } @@ -418,11 +349,15 @@ void GLWall::DrawDecal(DBaseDecal *decal) //========================================================================== void GLWall::DoDrawDecals() { - DBaseDecal *decal = seg->sidedef->AttachedDecals; - while (decal) + if (seg->sidedef && seg->sidedef->AttachedDecals) { - DrawDecal(decal); - decal = decal->WallNext; + gl_SetFog(lightlevel, rellight + getExtraLight(), &Colormap, false); + DBaseDecal *decal = seg->sidedef->AttachedDecals; + while (decal) + { + DrawDecal(decal); + decal = decal->WallNext; + } } } diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index f078c52c9..b92a2c6cf 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -47,9 +47,9 @@ #include "gl/system/gl_cvars.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" -#include "gl/dynlights/gl_lightbuffer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/textures/gl_material.h" @@ -59,8 +59,6 @@ FDrawInfo * gl_drawinfo; -CVAR(Bool, gl_sort_textures, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - //========================================================================== // // @@ -644,7 +642,6 @@ SortNode * GLDrawList::DoSort(SortNode * head) case GLDIT_SPRITE: SortSpriteIntoPlane(head,node); break; - case GLDIT_POLY: break; } node=next; } @@ -670,7 +667,7 @@ SortNode * GLDrawList::DoSort(SortNode * head) case GLDIT_SPRITE: SortSpriteIntoWall(head,node); break; - case GLDIT_POLY: break; + case GLDIT_FLAT: break; } node=next; @@ -692,7 +689,7 @@ SortNode * GLDrawList::DoSort(SortNode * head) // // //========================================================================== -void GLDrawList::DoDraw(int pass, int i) +void GLDrawList::DoDraw(int pass, int i, bool trans) { switch(drawitems[i].rendertype) { @@ -700,7 +697,7 @@ void GLDrawList::DoDraw(int pass, int i) { GLFlat * f=&flats[drawitems[i].index]; RenderFlat.Clock(); - f->Draw(pass); + f->Draw(pass, trans); RenderFlat.Unclock(); } break; @@ -722,7 +719,6 @@ void GLDrawList::DoDraw(int pass, int i) RenderSprite.Unclock(); } break; - case GLDIT_POLY: break; } } @@ -739,13 +735,13 @@ void GLDrawList::DoDrawSorted(SortNode * head) { DoDrawSorted(head->left); } - DoDraw(GLPASS_TRANSLUCENT, head->itemindex); + DoDraw(GLPASS_TRANSLUCENT, head->itemindex, true); if (head->equal) { SortNode * ehead=head->equal; while (ehead) { - DoDraw(GLPASS_TRANSLUCENT, ehead->itemindex); + DoDraw(GLPASS_TRANSLUCENT, ehead->itemindex, true); ehead=ehead->equal; } } @@ -779,7 +775,50 @@ void GLDrawList::Draw(int pass) { for(unsigned i=0;iwalls[di1->index]; - for(int i=0;i<2;i++) - { - switch(di[i]->rendertype) - { - case GLDIT_FLAT: - { - GLFlat * f=&sortinfo->flats[di[i]->index]; - tx[i]=f->gltexture; - lights[i]=f->lightlevel; - clamp[i] = 0; - } - break; + const GLDrawItem * di2 = (const GLDrawItem *)b; + GLWall * w2=&sortinfo->walls[di2->index]; - case GLDIT_WALL: - { - GLWall * w=&sortinfo->walls[di[i]->index]; - tx[i]=w->gltexture; - lights[i]=w->lightlevel; - clamp[i] = w->flags & 3; - } - break; + if (w1->gltexture != w2->gltexture) return w1->gltexture - w2->gltexture; + return ((w1->flags & 3) - (w2->flags & 3)); +} - case GLDIT_SPRITE: - { - GLSprite * s=&sortinfo->sprites[di[i]->index]; - tx[i]=s->gltexture; - lights[i]=s->lightlevel; - clamp[i] = 4; - } - break; - case GLDIT_POLY: break; - } - } - if (tx[0]!=tx[1]) return tx[0]-tx[1]; - if (clamp[0]!=clamp[1]) return clamp[0]-clamp[1]; // clamping forces different textures. - return lights[0]-lights[1]; +static int __cdecl difcmp (const void *a, const void *b) +{ + const GLDrawItem * di1 = (const GLDrawItem *)a; + GLFlat * w1=&sortinfo->flats[di1->index]; + + const GLDrawItem * di2 = (const GLDrawItem *)b; + GLFlat* w2=&sortinfo->flats[di2->index]; + + return w1->gltexture - w2->gltexture; } -void GLDrawList::Sort() +void GLDrawList::SortWalls() { - if (drawitems.Size()!=0 && gl_sort_textures) + if (drawitems.Size() > 1) { sortinfo=this; - qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), dicmp); + qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp); + } +} + +void GLDrawList::SortFlats() +{ + if (drawitems.Size() > 1) + { + sortinfo=this; + qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp); } } @@ -982,17 +1005,22 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws) glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels glColorMask(0,0,0,0); // don't write to the graphics buffer gl_RenderState.EnableTexture(false); - glColor3f(1,1,1); + gl_RenderState.ResetColor(); glEnable(GL_DEPTH_TEST); glDepthMask(true); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glVertex3f(ws->x1, ws->z1, ws->y1); - glVertex3f(ws->x1, ws->z2, ws->y1); - glVertex3f(ws->x2, ws->z2, ws->y2); - glVertex3f(ws->x2, ws->z1, ws->y2); - glEnd(); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0); + ptr++; + ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0); + ptr++; + ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0); + ptr++; + ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil @@ -1010,15 +1038,19 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws) glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); gl_RenderState.EnableTexture(false); glColorMask(0,0,0,0); // don't write to the graphics buffer - glColor3f(1,1,1); + gl_RenderState.ResetColor(); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glVertex3f(ws->x1, ws->z1, ws->y1); - glVertex3f(ws->x1, ws->z2, ws->y1); - glVertex3f(ws->x2, ws->z2, ws->y2); - glVertex3f(ws->x2, ws->z1, ws->y2); - glEnd(); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0); + ptr++; + ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0); + ptr++; + ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0); + ptr++; + ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); // restore old stencil op. glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); @@ -1043,12 +1075,12 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo plane.GetFromSector(sec, ceiling); - gltexture=FMaterial::ValidateTexture(plane.texture, true); + gltexture=FMaterial::ValidateTexture(plane.texture, false, true); if (!gltexture) return; if (gl_fixedcolormap) { - Colormap.GetFixedColormap(); + Colormap.Clear(); lightlevel=255; } else @@ -1063,19 +1095,17 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo } int rel = getExtraLight(); - gl_SetColor(lightlevel, rel, &Colormap, 1.0f); + gl_SetColor(lightlevel, rel, Colormap, 1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gltexture->Bind(Colormap.colormap); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); float fviewx = FIXED2FLOAT(viewx); float fviewy = FIXED2FLOAT(viewy); float fviewz = FIXED2FLOAT(viewz); + gl_SetPlaneTextureRotation(&plane, gltexture); gl_RenderState.Apply(); - bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); - - glBegin(GL_TRIANGLE_FAN); float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz); float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz); @@ -1091,25 +1121,18 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo float px4 = fviewx + prj_fac1 * (ws->x2-fviewx); float py4 = fviewy + prj_fac1 * (ws->y2-fviewy); - glTexCoord2f(px1 / 64, -py1 / 64); - glVertex3f(px1, planez, py1); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64); + ptr++; + ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64); + ptr++; + ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64); + ptr++; + ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); - glTexCoord2f(px2 / 64, -py2 / 64); - glVertex3f(px2, planez, py2); - - glTexCoord2f(px3 / 64, -py3 / 64); - glVertex3f(px3, planez, py3); - - glTexCoord2f(px4 / 64, -py4 / 64); - glVertex3f(px4, planez, py4); - - glEnd(); - - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } + gl_RenderState.EnableTextureMatrix(false); } //========================================================================== diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 07735eb3f..67ed2099c 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -13,42 +13,26 @@ enum GLDrawItemType enum DrawListType { - // These are organized so that the various multipass rendering modes - // have to be set as few times as possible - GLDL_LIGHT, - GLDL_LIGHTBRIGHT, - GLDL_LIGHTMASKED, - GLDL_LIGHTFOG, - GLDL_LIGHTFOGMASKED, - - GLDL_PLAIN, - GLDL_MASKED, - GLDL_FOG, - GLDL_FOGMASKED, + GLDL_PLAINWALLS, + GLDL_PLAINFLATS, + GLDL_MASKEDWALLS, + GLDL_MASKEDFLATS, + GLDL_MASKEDWALLSOFS, + GLDL_MODELS, GLDL_TRANSLUCENT, GLDL_TRANSLUCENTBORDER, GLDL_TYPES, - - GLDL_FIRSTLIGHT = GLDL_LIGHT, - GLDL_LASTLIGHT = GLDL_LIGHTFOGMASKED, - GLDL_FIRSTNOLIGHT = GLDL_PLAIN, - GLDL_LASTNOLIGHT = GLDL_FOGMASKED, }; enum Drawpasses { - GLPASS_BASE, // Draws the untextured surface only - GLPASS_BASE_MASKED, // Draws an untextured surface that is masked by the texture - GLPASS_PLAIN, // Draws a texture that isn't affected by dynamic lights with sector light settings - GLPASS_LIGHT, // Draws dynamic lights - GLPASS_LIGHT_ADDITIVE, // Draws additive dynamic lights - GLPASS_TEXTURE, // Draws the texture to be modulated with the light information on the base surface + GLPASS_ALL, // Main pass with dynamic lights + GLPASS_LIGHTSONLY, // only collect dynamic lights + GLPASS_PLAIN, // Main pass without dynamic lights GLPASS_DECALS, // Draws a decal - GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer) GLPASS_TRANSLUCENT, // Draws translucent objects - GLPASS_ALL // Everything at once, using shaders for dynamic lights }; //========================================================================== @@ -114,11 +98,17 @@ public: Reset(); } + unsigned int Size() + { + return drawitems.Size(); + } + void AddWall(GLWall * wall); void AddFlat(GLFlat * flat); void AddSprite(GLSprite * sprite); void Reset(); - void Sort(); + void SortWalls(); + void SortFlats(); void MakeSortList(); @@ -133,10 +123,13 @@ public: SortNode * SortSpriteList(SortNode * head); SortNode * DoSort(SortNode * head); - void DoDraw(int pass, int index); + void DoDraw(int pass, int index, bool trans); void DoDrawSorted(SortNode * node); void DrawSorted(); void Draw(int pass); + void DrawWalls(int pass); + void DrawFlats(int pass); + void DrawDecals(); GLDrawList * next; } ; @@ -273,7 +266,7 @@ public: extern FDrawInfo * gl_drawinfo; -bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture); +void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture); void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending); #endif \ No newline at end of file diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 3efdcba8b..ac185aee9 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -70,18 +70,18 @@ // information // //========================================================================== - -bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture) +static float tics; +void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture) { // only manipulate the texture matrix if needed. if (secplane->xoffs != 0 || secplane->yoffs != 0 || secplane->xscale != FRACUNIT || secplane->yscale != FRACUNIT || secplane->angle != 0 || - gltexture->TextureWidth(GLUSE_TEXTURE) != 64 || - gltexture->TextureHeight(GLUSE_TEXTURE) != 64) + gltexture->TextureWidth() != 64 || + gltexture->TextureHeight() != 64) { - float uoffs=FIXED2FLOAT(secplane->xoffs)/gltexture->TextureWidth(GLUSE_TEXTURE); - float voffs=FIXED2FLOAT(secplane->yoffs)/gltexture->TextureHeight(GLUSE_TEXTURE); + float uoffs = FIXED2FLOAT(secplane->xoffs) / gltexture->TextureWidth(); + float voffs = FIXED2FLOAT(secplane->yoffs) / gltexture->TextureHeight(); float xscale1=FIXED2FLOAT(secplane->xscale); float yscale1=FIXED2FLOAT(secplane->yscale); @@ -91,41 +91,44 @@ bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte } float angle=-ANGLE_TO_FLOAT(secplane->angle); - float xscale2=64.f/gltexture->TextureWidth(GLUSE_TEXTURE); - float yscale2=64.f/gltexture->TextureHeight(GLUSE_TEXTURE); + float xscale2=64.f/gltexture->TextureWidth(); + float yscale2=64.f/gltexture->TextureHeight(); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glScalef(xscale1 ,yscale1,1.0f); - glTranslatef(uoffs,voffs,0.0f); - glScalef(xscale2 ,yscale2,1.0f); - glRotatef(angle,0.0f,0.0f,1.0f); - return true; + gl_RenderState.mTextureMatrix.loadIdentity(); + gl_RenderState.mTextureMatrix.scale(xscale1 ,yscale1,1.0f); + gl_RenderState.mTextureMatrix.translate(uoffs,voffs,0.0f); + gl_RenderState.mTextureMatrix.scale(xscale2 ,yscale2,1.0f); + gl_RenderState.mTextureMatrix.rotate(angle,0.0f,0.0f,1.0f); + gl_RenderState.EnableTextureMatrix(true); } - return false; } + //========================================================================== // // Flats // //========================================================================== +extern FDynLightData lightdata; -void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) +void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli) { Plane p; - Vector nearPt, up, right, t1; - float scale; - unsigned int k; - seg_t *v; - FLightNode * node = sub->lighthead[pass==GLPASS_LIGHT_ADDITIVE]; - gl_RenderState.Apply(); + if (dli != NULL && *dli != -1) + { + gl_RenderState.ApplyLightIndex(GLRenderer->mLights->GetIndex(*dli)); + (*dli)++; + return; + } + + lightdata.Clear(); + FLightNode * node = sub->lighthead; while (node) { ADynamicLight * light = node->lightsource; - + if (light->flags2&MF2_DORMANT) { node=node->nextLight; @@ -143,91 +146,19 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) } p.Set(plane.plane); - if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, false, foggy)) - { - node=node->nextLight; - continue; - } - draw_dlightf++; - - // Render the light - glBegin(GL_TRIANGLE_FAN); - for(k = 0, v = sub->firstline; k < sub->numlines; k++, v++) - { - vertex_t *vt = v->v1; - float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz; - - t1.Set(vt->fx, zc, vt->fy); - Vector nearToVert = t1 - nearPt; - glTexCoord2f( (nearToVert.Dot(right) * scale) + 0.5f, (nearToVert.Dot(up) * scale) + 0.5f); - - glVertex3f(vt->fx, zc, vt->fy); - } - - glEnd(); + gl_GetLight(p, light, false, false, lightdata); node = node->nextLight; } -} - -//========================================================================== -// -// Flats -// -//========================================================================== -extern FDynLightData lightdata; - -bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) -{ - Plane p; - - lightdata.Clear(); - for(int i=0;i<2;i++) + int d = GLRenderer->mLights->UploadLights(lightdata); + if (pass == GLPASS_LIGHTSONLY) { - FLightNode * node = sub->lighthead[i]; - while (node) - { - ADynamicLight * light = node->lightsource; - - if (light->flags2&MF2_DORMANT) - { - node=node->nextLight; - continue; - } - iter_dlightf++; - - // we must do the side check here because gl_SetupLight needs the correct plane orientation - // which we don't have for Legacy-style 3D-floors - fixed_t planeh = plane.plane.ZatPoint(light->x, light->y); - if (gl_lights_checkside && ((planehz && ceiling) || (planeh>light->z && !ceiling))) - { - node=node->nextLight; - continue; - } - - p.Set(plane.plane); - gl_GetLight(p, light, Colormap.colormap, false, false, lightdata); - node = node->nextLight; - } + GLRenderer->mLights->StoreIndex(d); } - - int numlights[3]; - - lightdata.Combine(numlights, gl.MaxLights()); - if (numlights[2] > 0) + else { - draw_dlightf+=numlights[2]/2; - gl_RenderState.EnableLight(true); - gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]); - gl_RenderState.Apply(); - return true; + gl_RenderState.ApplyLightIndex(d); } - if (lightsapplied) - { - gl_RenderState.EnableLight(false); - gl_RenderState.Apply(); - } - return false; } //========================================================================== @@ -238,52 +169,117 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) void GLFlat::DrawSubsector(subsector_t * sub) { - glBegin(GL_TRIANGLE_FAN); - - for(unsigned int k=0; knumlines; k++) + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + if (plane.plane.a | plane.plane.b) { - vertex_t *vt = sub->firstline[k].v1; - glTexCoord2f(vt->fx/64.f, -vt->fy/64.f); - float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz; - glVertex3f(vt->fx, zc, vt->fy); + for (unsigned int k = 0; k < sub->numlines; k++) + { + vertex_t *vt = sub->firstline[k].v1; + ptr->x = vt->fx; + ptr->y = vt->fy; + ptr->z = plane.plane.ZatPoint(vt->fx, vt->fy) + dz; + ptr->u = vt->fx / 64.f; + ptr->v = -vt->fy / 64.f; + ptr++; + } } - glEnd(); + else + { + float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz; + for (unsigned int k = 0; k < sub->numlines; k++) + { + vertex_t *vt = sub->firstline[k].v1; + ptr->x = vt->fx; + ptr->y = vt->fy; + ptr->z = zc; + ptr->u = vt->fx / 64.f; + ptr->v = -vt->fy / 64.f; + ptr++; + } + } + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); flatvertices += sub->numlines; flatprimitives++; } + //========================================================================== // // // //========================================================================== -void GLFlat::DrawSubsectors(int pass, bool istrans) +void GLFlat::ProcessLights(bool istrans) { - bool lightsapplied = false; + dynlightindex = GLRenderer->mLights->GetIndexPtr(); + + if (sub) + { + // This represents a single subsector + SetupSubsectorLights(GLPASS_LIGHTSONLY, sub); + } + else + { + // Draw the subsectors belonging to this sector + for (int i=0; isubsectorcount; i++) + { + subsector_t * sub = sector->subsectors[i]; + if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) + { + SetupSubsectorLights(GLPASS_LIGHTSONLY, sub); + } + } + + // Draw the subsectors assigned to it due to missing textures + if (!(renderflags&SSRF_RENDER3DPLANES)) + { + gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)? + gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : + gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); + + while (node) + { + SetupSubsectorLights(GLPASS_LIGHTSONLY, node->sub); + node = node->next; + } + } + } +} + + +//========================================================================== +// +// +// +//========================================================================== + +void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans) +{ + int dli = dynlightindex; gl_RenderState.Apply(); if (sub) { // This represents a single subsector - if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); DrawSubsector(sub); } else { if (vboindex >= 0) { - //glColor3f( 1.f,.5f,.5f); int index = vboindex; for (int i=0; isubsectorcount; i++) { subsector_t * sub = sector->subsectors[i]; - // This is just a quick hack to make translucent 3D floors and portals work. + if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { - if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); + drawcalls.Clock(); glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); + drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } @@ -292,14 +288,13 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) } else { - //glColor3f( .5f,1.f,.5f); // these are for testing the VBO stuff. // Draw the subsectors belonging to this sector for (int i=0; isubsectorcount; i++) { subsector_t * sub = sector->subsectors[i]; if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { - if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli); DrawSubsector(sub); } } @@ -314,13 +309,12 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) while (node) { - if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub); + if (processlights) SetupSubsectorLights(GLPASS_ALL, node->sub, &dli); DrawSubsector(node->sub); node = node->next; } } } - gl_RenderState.EnableLight(false); } @@ -329,13 +323,12 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) // // //========================================================================== -void GLFlat::Draw(int pass) +void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIGHTSONLY { - int i; int rel = getExtraLight(); #ifdef _DEBUG - if (sector->sectornum == 2) + if (sector->sectornum == 130) { int a = 0; } @@ -344,93 +337,40 @@ void GLFlat::Draw(int pass) switch (pass) { - case GLPASS_BASE: - gl_SetColor(lightlevel, rel, &Colormap,1.0f); - if (!foggy) gl_SetFog(lightlevel, rel, &Colormap, false); - DrawSubsectors(pass, false); - break; - case GLPASS_PLAIN: // Single-pass rendering case GLPASS_ALL: - case GLPASS_BASE_MASKED: - gl_SetColor(lightlevel, rel, &Colormap,1.0f); - if (!foggy || pass != GLPASS_BASE_MASKED) gl_SetFog(lightlevel, rel, &Colormap, false); - // fall through - case GLPASS_TEXTURE: - { - gltexture->Bind(Colormap.colormap); - bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); - DrawSubsectors(pass, false); - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } + gl_SetColor(lightlevel, rel, Colormap,1.0f); + gl_SetFog(lightlevel, rel, &Colormap, false); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); + gl_SetPlaneTextureRotation(&plane, gltexture); + DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false); + gl_RenderState.EnableTextureMatrix(false); break; - } - case GLPASS_LIGHT: - case GLPASS_LIGHT_ADDITIVE: - - if (!foggy) gl_SetFog((255+lightlevel)>>1, 0, &Colormap, false); - else gl_SetFog(lightlevel, 0, &Colormap, true); - - if (sub) + case GLPASS_LIGHTSONLY: + if (!trans || gltexture) { - DrawSubsectorLights(sub, pass); - } - else - { - // Draw the subsectors belonging to this sector - for (i=0; isubsectorcount; i++) - { - subsector_t * sub = sector->subsectors[i]; - - if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags) - { - DrawSubsectorLights(sub, pass); - } - } - - // Draw the subsectors assigned to it due to missing textures - if (!(renderflags&SSRF_RENDER3DPLANES)) - { - gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)? - gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum); - - while (node) - { - DrawSubsectorLights(node->sub, pass); - node = node->next; - } - } + ProcessLights(trans); } break; case GLPASS_TRANSLUCENT: if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE); - gl_SetColor(lightlevel, rel, &Colormap, alpha); + gl_SetColor(lightlevel, rel, Colormap, alpha); gl_SetFog(lightlevel, rel, &Colormap, false); - gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold*(alpha)); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); if (!gltexture) { gl_RenderState.EnableTexture(false); - DrawSubsectors(pass, true); + DrawSubsectors(pass, false, true); gl_RenderState.EnableTexture(true); } else { - if (foggy) gl_RenderState.EnableBrightmap(false); - gltexture->Bind(Colormap.colormap); - bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); - DrawSubsectors(pass, true); - gl_RenderState.EnableBrightmap(true); - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); + gl_SetPlaneTextureRotation(&plane, gltexture); + DrawSubsectors(pass, true, true); + gl_RenderState.EnableTextureMatrix(false); } if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; @@ -452,42 +392,19 @@ inline void GLFlat::PutFlat(bool fog) if (gl_fixedcolormap) { - Colormap.GetFixedColormap(); + Colormap.Clear(); } - if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog) + if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog || gltexture == NULL) { - int list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER; - gl_drawinfo->drawlists[list].AddFlat (this); + // translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list. + list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER; } - else if (gltexture != NULL) + else { - static DrawListType list_indices[2][2][2]={ - { { GLDL_PLAIN, GLDL_FOG }, { GLDL_MASKED, GLDL_FOGMASKED } }, - { { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } } - }; - - bool light = gl_forcemultipass; bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack); - - if (!gl_fixedcolormap) - { - foggy = gl_CheckFog(&Colormap, lightlevel) || level.flags&LEVEL_HASFADETABLE; - - if (gl_lights && !gl_dynlight_shader && GLRenderer->mLightCount) // Are lights touching this sector? - { - for(int i=0;isubsectorcount;i++) if (sector->subsectors[i]->lighthead[0] != NULL) - { - light=true; - } - } - } - else foggy = false; - - list = list_indices[light][masked][foggy]; - if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap && gl_BrightmapsActive()) list = GLDL_LIGHTBRIGHT; - - gl_drawinfo->drawlists[list].AddFlat (this); + list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS; } + gl_drawinfo->drawlists[list].AddFlat (this); } //========================================================================== @@ -507,7 +424,7 @@ void GLFlat::Process(sector_t * model, int whichplane, bool fog) { if (plane.texture==skyflatnum) return; - gltexture=FMaterial::ValidateTexture(plane.texture, true); + gltexture=FMaterial::ValidateTexture(plane.texture, false, true); if (!gltexture) return; if (gltexture->tex->isFullbright()) { @@ -583,6 +500,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) sector=§ors[frontsector->sectornum]; extsector_t::xfloor &x = sector->e->XFloor; this->sub=NULL; + dynlightindex = -1; byte &srf = gl_drawinfo->sectorrenderflags[sector->sectornum]; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index ee0d494a4..02e7747bc 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -50,9 +50,11 @@ #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_lightdata.h" +#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/dynlights/gl_glow.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_clipper.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -77,6 +79,7 @@ EXTERN_CVAR(Bool, gl_noquery) EXTERN_CVAR(Int, r_mirror_recursions) TArray GLPortal::portals; +TArray GLPortal::planestack; int GLPortal::recursion; int GLPortal::MirrorFlag; int GLPortal::PlaneMirrorFlag; @@ -114,17 +117,14 @@ void GLPortal::BeginScene() void GLPortal::ClearScreen() { bool multi = !!glIsEnabled(GL_MULTISAMPLE); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gl_MatrixStack.Push(gl_RenderState.mViewMatrix); + gl_MatrixStack.Push(gl_RenderState.mProjectionMatrix); screen->Begin2D(false); screen->Dim(0, 1.f, 0, 0, SCREENWIDTH, SCREENHEIGHT); glEnable(GL_DEPTH_TEST); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gl_MatrixStack.Pop(gl_RenderState.mProjectionMatrix); + gl_MatrixStack.Pop(gl_RenderState.mViewMatrix); + gl_RenderState.ApplyMatrices(); if (multi) glEnable(GL_MULTISAMPLE); gl_RenderState.Set2DMode(false); } @@ -137,33 +137,45 @@ void GLPortal::ClearScreen() //----------------------------------------------------------------------------- void GLPortal::DrawPortalStencil() { - for(unsigned int i=0;i 1; + mPrimIndices.Resize(2 * lines.Size() + 4 * cap); + for (unsigned int i = 0; imVBO->GetBuffer(); + ptr->Set(-32767.0f, 32767.0f, -32767.0f, 0, 0); + ptr->Set(-32767.0f, 32767.0f, 32767.0f, 0, 0); + ptr->Set(32767.0f, 32767.0f, 32767.0f, 0, 0); + ptr->Set(32767.0f, 32767.0f, -32767.0f, 0, 0); + mPrimIndices[n + 1] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n]); + ptr->Set(-32767.0f, -32767.0f, -32767.0f, 0, 0); + ptr->Set(-32767.0f, -32767.0f, 32767.0f, 0, 0); + ptr->Set(32767.0f, -32767.0f, 32767.0f, 0, 0); + ptr->Set(32767.0f, -32767.0f, -32767.0f, 0, 0); + mPrimIndices[n + 3] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n + 2]); + } } - - if (NeedCap() && lines.Size() > 1) + gl_RenderState.Apply(); + for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) { - // Cap the stencil at the top and bottom - // (cheap ass version) - glBegin(GL_TRIANGLE_FAN); - glVertex3f(-32767.0f,32767.0f,-32767.0f); - glVertex3f(-32767.0f,32767.0f, 32767.0f); - glVertex3f( 32767.0f,32767.0f, 32767.0f); - glVertex3f( 32767.0f,32767.0f,-32767.0f); - glEnd(); - glBegin(GL_TRIANGLE_FAN); - glVertex3f(-32767.0f,-32767.0f,-32767.0f); - glVertex3f(-32767.0f,-32767.0f, 32767.0f); - glVertex3f( 32767.0f,-32767.0f, 32767.0f); - glVertex3f( 32767.0f,-32767.0f,-32767.0f); - glEnd(); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]); } } + + + //----------------------------------------------------------------------------- // // Start @@ -186,8 +198,9 @@ bool GLPortal::Start(bool usestencil, bool doquery) glStencilFunc(GL_EQUAL,recursion,~0); // create stencil glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels glColorMask(0,0,0,0); // don't write to the graphics buffer + gl_RenderState.SetEffect(EFF_STENCIL); gl_RenderState.EnableTexture(false); - glColor3f(1,1,1); + gl_RenderState.ResetColor(); glDepthFunc(GL_LESS); gl_RenderState.Apply(); @@ -201,13 +214,13 @@ bool GLPortal::Start(bool usestencil, bool doquery) if (!QueryObject) glGenQueries(1, &QueryObject); if (QueryObject) { - glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject); + glBeginQuery(GL_SAMPLES_PASSED, QueryObject); } else doquery = false; // some kind of error happened DrawPortalStencil(); - glEndQuery(GL_SAMPLES_PASSED_ARB); + glEndQuery(GL_SAMPLES_PASSED); // Clear Z-buffer glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil @@ -221,11 +234,12 @@ bool GLPortal::Start(bool usestencil, bool doquery) gl_RenderState.EnableTexture(true); glDepthFunc(GL_LESS); glColorMask(1,1,1,1); - glDepthRange(0,1); + gl_RenderState.SetEffect(EFF_NONE); + glDepthRange(0, 1); GLuint sampleCount; - glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount); + glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount); if (sampleCount==0) // not visible { @@ -250,6 +264,7 @@ bool GLPortal::Start(bool usestencil, bool doquery) glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil gl_RenderState.EnableTexture(true); glColorMask(1,1,1,1); + gl_RenderState.SetEffect(EFF_NONE); glDisable(GL_DEPTH_TEST); glDepthMask(false); // don't write to Z-buffer! } @@ -269,9 +284,12 @@ bool GLPortal::Start(bool usestencil, bool doquery) glDisable(GL_DEPTH_TEST); } } - // The clip plane from the previous portal must be deactivated for this one. - clipsave = glIsEnabled(GL_CLIP_PLANE0+renderdepth-1); - if (clipsave) glDisable(GL_CLIP_PLANE0+renderdepth-1); + planestack.Push(gl_RenderState.GetClipHeightTop()); + planestack.Push(gl_RenderState.GetClipHeightBottom()); + glDisable(GL_CLIP_DISTANCE0); + glDisable(GL_CLIP_DISTANCE1); + gl_RenderState.SetClipHeightBottom(-65536.f); + gl_RenderState.SetClipHeightTop(65536.f); // save viewpoint savedviewx=viewx; @@ -331,7 +349,15 @@ void GLPortal::End(bool usestencil) PortalAll.Clock(); GLRenderer->mCurrentPortal = NextPortal; - if (clipsave) glEnable (GL_CLIP_PLANE0+renderdepth-1); + + float f; + planestack.Pop(f); + gl_RenderState.SetClipHeightBottom(f); + if (f > -65535.f) glEnable(GL_CLIP_DISTANCE0); + planestack.Pop(f); + gl_RenderState.SetClipHeightTop(f); + if (f < 65535.f) glEnable(GL_CLIP_DISTANCE1); + if (usestencil) { if (needdepth) FDrawInfo::EndDrawInfo(); @@ -345,9 +371,9 @@ void GLPortal::End(bool usestencil) in_area=savedviewarea; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - glColor4f(1,1,1,1); glColorMask(0,0,0,0); // no graphics - glColor3f(1,1,1); + gl_RenderState.SetEffect(EFF_NONE); + gl_RenderState.ResetColor(); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); @@ -373,7 +399,8 @@ void GLPortal::End(bool usestencil) gl_RenderState.EnableTexture(true); - glColorMask(1,1,1,1); + gl_RenderState.SetEffect(EFF_NONE); + glColorMask(1, 1, 1, 1); recursion--; // restore old stencil op. @@ -404,12 +431,14 @@ void GLPortal::End(bool usestencil) // This draws a valid z-buffer into the stencil's contents to ensure it // doesn't get overwritten by the level's geometry. - glColor4f(1,1,1,1); + gl_RenderState.ResetColor(); glDepthFunc(GL_LEQUAL); glDepthRange(0,1); glColorMask(0,0,0,0); // no graphics + gl_RenderState.SetEffect(EFF_STENCIL); gl_RenderState.EnableTexture(false); DrawPortalStencil(); + gl_RenderState.SetEffect(EFF_NONE); gl_RenderState.EnableTexture(true); glColorMask(1,1,1,1); glDepthFunc(GL_LESS); @@ -604,7 +633,7 @@ void GLSkyboxPortal::DrawContents() PlaneMirrorMode=0; - glDisable(GL_DEPTH_CLAMP_NV); + glDisable(GL_DEPTH_CLAMP); viewx = origin->PrevX + FixedMul(r_TicFrac, origin->x - origin->PrevX); viewy = origin->PrevY + FixedMul(r_TicFrac, origin->y - origin->PrevY); @@ -634,7 +663,7 @@ void GLSkyboxPortal::DrawContents() GLRenderer->DrawScene(); origin->flags&=~MF_JUSTHIT; inskybox=false; - glEnable(GL_DEPTH_CLAMP_NV); + glEnable(GL_DEPTH_CLAMP); skyboxrecursion--; PlaneMirrorMode=old_pm; @@ -769,14 +798,23 @@ void GLPlaneMirrorPortal::DrawContents() GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); ClearClipper(); - glEnable(GL_CLIP_PLANE0+renderdepth); - // This only works properly for non-sloped planes so don't bother with the math. - //double d[4]={origin->a/65536., origin->c/65536., origin->b/65536., FIXED2FLOAT(origin->d)}; - double d[4]={0, static_cast(PlaneMirrorMode), 0, FIXED2FLOAT(origin->d)}; - glClipPlane(GL_CLIP_PLANE0+renderdepth, d); + float f = FIXED2FLOAT(planez); + if (PlaneMirrorMode < 0) + { + gl_RenderState.SetClipHeightTop(f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling + glEnable(GL_CLIP_DISTANCE1); + } + else + { + gl_RenderState.SetClipHeightBottom(f); // floor mirror: clip everything with a z higher than the portal's floor + glEnable(GL_CLIP_DISTANCE0); + } GLRenderer->DrawScene(); - glDisable(GL_CLIP_PLANE0+renderdepth); + glDisable(GL_CLIP_DISTANCE0); + glDisable(GL_CLIP_DISTANCE1); + gl_RenderState.SetClipHeightBottom(-65536.f); + gl_RenderState.SetClipHeightTop(65536.f); PlaneMirrorFlag--; PlaneMirrorMode=old_pm; } @@ -844,12 +882,12 @@ void GLMirrorPortal::DrawContents() // any mirror--use floats to avoid integer overflow. // Use doubles to avoid losing precision which is very important here. - double dx = FIXED2FLOAT(v2->x - v1->x); - double dy = FIXED2FLOAT(v2->y - v1->y); - double x1 = FIXED2FLOAT(v1->x); - double y1 = FIXED2FLOAT(v1->y); - double x = FIXED2FLOAT(startx); - double y = FIXED2FLOAT(starty); + double dx = FIXED2DBL(v2->x - v1->x); + double dy = FIXED2DBL(v2->y - v1->y); + double x1 = FIXED2DBL(v1->x); + double y1 = FIXED2DBL(v1->y); + double x = FIXED2DBL(startx); + double y = FIXED2DBL(starty); // the above two cases catch len == 0 double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy); @@ -947,7 +985,7 @@ void GLHorizonPortal::DrawContents() float z; player_t * player=&players[consoleplayer]; - gltexture=FMaterial::ValidateTexture(sp->texture, true); + gltexture=FMaterial::ValidateTexture(sp->texture, false, true); if (!gltexture) { ClearScreen(); @@ -962,50 +1000,45 @@ void GLHorizonPortal::DrawContents() if (gltexture && gltexture->tex->isFullbright()) { // glowing textures are always drawn full bright without color - gl_SetColor(255, 0, NULL, 1.f); + gl_SetColor(255, 0, origin->colormap, 1.f); gl_SetFog(255, 0, &origin->colormap, false); } else { int rel = getExtraLight(); - gl_SetColor(origin->lightlevel, rel, &origin->colormap, 1.0f); + gl_SetColor(origin->lightlevel, rel, origin->colormap, 1.0f); gl_SetFog(origin->lightlevel, rel, &origin->colormap, false); } - gltexture->Bind(origin->colormap.colormap); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); - gl_RenderState.EnableAlphaTest(false); + gl_SetPlaneTextureRotation(sp, gltexture); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); gl_RenderState.Apply(); - bool pushed = gl_SetPlaneTextureRotation(sp, gltexture); float vx=FIXED2FLOAT(viewx); float vy=FIXED2FLOAT(viewy); // Draw to some far away boundary + // This is not drawn as larher strips because it causes visual glitches. for(float x=-32768+vx; x<32768+vx; x+=4096) { for(float y=-32768+vy; y<32768+vy;y+=4096) { - glBegin(GL_TRIANGLE_FAN); - - glTexCoord2f(x/64, -y/64); - glVertex3f(x, z, y); - - glTexCoord2f(x/64 + 64, -y/64); - glVertex3f(x + 4096, z, y); - - glTexCoord2f(x/64 + 64, -y/64 - 64); - glVertex3f(x + 4096, z, y + 4096); - - glTexCoord2f(x/64, -y/64 - 64); - glVertex3f(x, z, y + 4096); - - glEnd(); - + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x, z, y, x / 64, -y / 64); + ptr++; + ptr->Set(x + 4096, z, y, x / 64 + 64, -y / 64); + ptr++; + ptr->Set(x, z, y + 4096, x / 64, -y / 64 - 64); + ptr++; + ptr->Set(x + 4096, z, y + 4096, x / 64 + 64, -y / 64 - 64); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } } @@ -1016,41 +1049,30 @@ void GLHorizonPortal::DrawContents() // Since I can't draw into infinity there can always be a // small gap - glBegin(GL_TRIANGLE_STRIP); - - glTexCoord2f(512.f, 0); - glVertex3f(-32768+vx, z, -32768+vy); - glTexCoord2f(512.f, tz); - glVertex3f(-32768+vx, vz, -32768+vy); - - glTexCoord2f(-512.f, 0); - glVertex3f(-32768+vx, z, 32768+vy); - glTexCoord2f(-512.f, tz); - glVertex3f(-32768+vx, vz, 32768+vy); - - glTexCoord2f(512.f, 0); - glVertex3f( 32768+vx, z, 32768+vy); - glTexCoord2f(512.f, tz); - glVertex3f( 32768+vx, vz, 32768+vy); - - glTexCoord2f(-512.f, 0); - glVertex3f( 32768+vx, z, -32768+vy); - glTexCoord2f(-512.f, tz); - glVertex3f( 32768+vx, vz, -32768+vy); - - glTexCoord2f(512.f, 0); - glVertex3f(-32768+vx, z, -32768+vy); - glTexCoord2f(512.f, tz); - glVertex3f(-32768+vx, vz, -32768+vy); - - glEnd(); - - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0); + ptr++; + ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz); + ptr++; + ptr->Set(-32768 + vx, z, 32768 + vy, -512.f, 0); + ptr++; + ptr->Set(-32768 + vx, vz, 32768 + vy, -512.f, tz); + ptr++; + ptr->Set(32768 + vx, z, 32768 + vy, 512.f, 0); + ptr++; + ptr->Set(32768 + vx, vz, 32768 + vy, 512.f, tz); + ptr++; + ptr->Set(32768 + vx, z, -32768 + vy, -512.f, 0); + ptr++; + ptr->Set(32768 + vx, vz, -32768 + vy, -512.f, tz); + ptr++; + ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0); + ptr++; + ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + gl_RenderState.EnableTextureMatrix(false); PortalAll.Unclock(); } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index b04873ec8..ccc6d174d 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -82,6 +82,7 @@ class GLPortal static int recursion; static unsigned int QueryObject; protected: + static TArray planestack; static int MirrorFlag; static int PlaneMirrorFlag; static int renderdepth; @@ -101,9 +102,9 @@ private: angle_t savedviewangle; AActor * savedviewactor; area_t savedviewarea; - unsigned char clipsave; GLPortal *NextPortal; TArray savedmapsection; + TArray mPrimIndices; protected: TArray lines; diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index 7aba676f5..a8ef49e25 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -48,7 +48,6 @@ #include "gl/renderer/gl_renderer.h" #include "gl/data/gl_data.h" #include "gl/dynlights/gl_glow.h" -#include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/utility/gl_clock.h" diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 9244ba21f..b095d261b 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -57,6 +57,7 @@ #include "p_local.h" #include "gl/gl_functions.h" +#include "gl/dynlights/gl_lightbuffer.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" @@ -65,7 +66,6 @@ #include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_lightbuffer.h" #include "gl/models/gl_models.h" #include "gl/scene/gl_clipper.h" #include "gl/scene/gl_drawinfo.h" @@ -85,7 +85,7 @@ CVAR(Bool, gl_texture, true, 0) CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Float, gl_mask_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Float, gl_mask_sprite_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR(Bool, gl_forcemultipass, false, 0) +CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Int, screenblocks) EXTERN_CVAR (Bool, cl_capfps) @@ -247,36 +247,11 @@ void FGLRenderer::SetCameraPos(fixed_t viewx, fixed_t viewy, fixed_t viewz, angl // //----------------------------------------------------------------------------- -static void setPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) -{ - GLdouble m[4][4]; - double sine, cotangent, deltaZ; - double radians = fovy / 2 * M_PI / 180; - - deltaZ = zFar - zNear; - sine = sin(radians); - if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { - return; - } - cotangent = cos(radians) / sine; - - memset(m, 0, sizeof(m)); - m[0][0] = cotangent / aspect; - m[1][1] = cotangent; - m[2][2] = -(zFar + zNear) / deltaZ; - m[2][3] = -1; - m[3][2] = -2 * zNear * zFar / deltaZ; - m[3][3] = 0; - glLoadMatrixd(&m[0][0]); -} - - void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) { - glMatrixMode(GL_PROJECTION); float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovratio)); - setPerspective(fovy, ratio, 5.f, 65536.f); + gl_RenderState.mProjectionMatrix.perspective(fovy, ratio, 5.f, 65536.f); gl_RenderState.Set2DMode(false); } @@ -288,27 +263,15 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) void FGLRenderer::SetViewMatrix(bool mirror, bool planemirror) { - if (gl.shadermodel >= 4) - { - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - } - glActiveTexture(GL_TEXTURE0); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - float mult = mirror? -1:1; float planemult = planemirror? -1:1; - glRotatef(GLRenderer->mAngles.Roll, 0.0f, 0.0f, 1.0f); - glRotatef(GLRenderer->mAngles.Pitch, 1.0f, 0.0f, 0.0f); - glRotatef(GLRenderer->mAngles.Yaw, 0.0f, mult, 0.0f); - glTranslatef( GLRenderer->mCameraPos.X * mult, -GLRenderer->mCameraPos.Z*planemult, -GLRenderer->mCameraPos.Y); - glScalef(-mult, planemult, 1); + gl_RenderState.mViewMatrix.loadIdentity(); + gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Roll, 0.0f, 0.0f, 1.0f); + gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Pitch, 1.0f, 0.0f, 0.0f); + gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Yaw, 0.0f, mult, 0.0f); + gl_RenderState.mViewMatrix.translate( GLRenderer->mCameraPos.X * mult, -GLRenderer->mCameraPos.Z*planemult, -GLRenderer->mCameraPos.Y); + gl_RenderState.mViewMatrix.scale(-mult, planemult, 1); } @@ -322,6 +285,7 @@ void FGLRenderer::SetupView(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t { SetCameraPos(viewx, viewy, viewz, viewangle); SetViewMatrix(mirror, planemirror); + gl_RenderState.ApplyMatrices(); } //----------------------------------------------------------------------------- @@ -353,7 +317,6 @@ void FGLRenderer::CreateScene() gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks - GLRenderer->mVBO->UnmapVBO (); ProcessAll.Unclock(); } @@ -378,150 +341,84 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableFog(true); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); - // First draw all single-pass stuff + if (gl_sort_textures) + { + gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls(); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats(); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls(); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats(); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls(); + } + + // if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front, + // so that we don't have to do repeated map/unmap calls on the buffer. + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE)) + { + GLRenderer->mLights->Begin(); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY); + GLRenderer->mLights->Finish(); + } // Part 1: solid geometry. This is set up so that there are no transparent parts glDepthFunc(GL_LESS); - - - gl_RenderState.EnableAlphaTest(false); - - glDisable(GL_POLYGON_OFFSET_FILL); // just in case + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + glDisable(GL_POLYGON_OFFSET_FILL); int pass; - if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && gl_dynlight_shader) + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_BUFFER_STORAGE)) { pass = GLPASS_ALL; } - else if (gl_texture) + else { pass = GLPASS_PLAIN; } - else - { - pass = GLPASS_BASE; - } gl_RenderState.EnableTexture(gl_texture); - gl_RenderState.EnableBrightmap(gl_fixedcolormap == CM_DEFAULT); - gl_drawinfo->drawlists[GLDL_PLAIN].Sort(); - gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass); - gl_RenderState.EnableBrightmap(false); - gl_drawinfo->drawlists[GLDL_FOG].Sort(); - gl_drawinfo->drawlists[GLDL_FOG].Draw(pass); - gl_drawinfo->drawlists[GLDL_LIGHTFOG].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(pass); + gl_RenderState.EnableBrightmap(true); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(pass); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(pass); - gl_RenderState.EnableAlphaTest(true); - - // Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show + // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show if (!gl_texture) { gl_RenderState.EnableTexture(true); gl_RenderState.SetTextureMode(TM_MASK); } - if (pass == GLPASS_BASE) pass = GLPASS_BASE_MASKED; - gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold); - gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_MASKED].Sort(); - gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); - gl_RenderState.EnableBrightmap(false); - gl_drawinfo->drawlists[GLDL_FOGMASKED].Sort(); - gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(pass); - gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(pass); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(pass); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(pass); - // And now the multipass stuff - if (!gl_dynlight_shader && gl_lights) + // Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use. + if (gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0) { - // First pass: empty background with sector light only - - // Part 1: solid geometry. This is set up so that there are no transparent parts - - // remove any remaining texture bindings and shaders whick may get in the way. - gl_RenderState.EnableTexture(false); - gl_RenderState.EnableBrightmap(false); - gl_RenderState.Apply(); - gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_BASE); - gl_RenderState.EnableTexture(true); - - // Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show - // This creates a blank surface that only fills the nontransparent parts of the texture - gl_RenderState.SetTextureMode(TM_MASK); - gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_BASE_MASKED); - gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Draw(GLPASS_BASE_MASKED); - gl_RenderState.EnableBrightmap(false); - gl_RenderState.SetTextureMode(TM_MODULATE); - - - // second pass: draw lights (on fogged surfaces they are added to the textures!) - glDepthMask(false); - if (mLightCount && !gl_fixedcolormap) - { - if (gl_SetupLightTexture()) - { - gl_RenderState.BlendFunc(GL_ONE, GL_ONE); - glDepthFunc(GL_EQUAL); - if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0f); // Korshun. - for(int i=GLDL_FIRSTLIGHT; i<=GLDL_LASTLIGHT; i++) - { - gl_drawinfo->drawlists[i].Draw(GLPASS_LIGHT); - } - gl_RenderState.BlendEquation(GL_FUNC_ADD); - } - else gl_lights=false; - } - - // third pass: modulated texture - glColor3f(1.0f, 1.0f, 1.0f); - gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - gl_RenderState.EnableFog(false); - glDepthFunc(GL_LEQUAL); - if (gl_texture) - { - gl_RenderState.EnableAlphaTest(false); - gl_drawinfo->drawlists[GLDL_LIGHT].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_TEXTURE); - gl_RenderState.EnableAlphaTest(true); - gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_TEXTURE); - gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Draw(GLPASS_TEXTURE); - } - - // fourth pass: additive lights - gl_RenderState.EnableFog(true); - if (gl_lights && mLightCount && !gl_fixedcolormap) - { - gl_RenderState.BlendFunc(GL_ONE, GL_ONE); - glDepthFunc(GL_EQUAL); - if (gl_SetupLightTexture()) - { - for(int i=0; idrawlists[i].Draw(GLPASS_LIGHT_ADDITIVE); - } - gl_RenderState.BlendEquation(GL_FUNC_ADD); - } - else gl_lights=false; - } + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -128.0f); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(pass); + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); } + gl_drawinfo->drawlists[GLDL_MODELS].Draw(pass); + gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // Draw decals (not a real pass) + // Part 4: Draw decals (not a real pass) glDepthFunc(GL_LEQUAL); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); glDepthMask(false); - for(int i=0; idrawlists[i].Draw(GLPASS_DECALS); - } + // this is the only geometry type on which decals can possibly appear + gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals(); gl_RenderState.SetTextureMode(TM_MODULATE); @@ -532,21 +429,20 @@ void FGLRenderer::RenderScene(int recursion) // so they don't interfere with overlapping mid textures. glPolygonOffset(1.0f, 128.0f); - // flood all the gaps with the back sector's flat texture - // This will always be drawn like GLDL_PLAIN or GLDL_FOG, depending on the fog settings + // Part 5: flood all the gaps with the back sector's flat texture + // This will always be drawn like GLDL_PLAIN, depending on the fog settings glDepthMask(false); // don't write to Z-buffer! gl_RenderState.EnableFog(true); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); gl_drawinfo->DrawUnhandledMissingTextures(); - gl_RenderState.EnableAlphaTest(true); glDepthMask(true); glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); - RenderAll.Unclock(); + } //----------------------------------------------------------------------------- @@ -565,8 +461,7 @@ void FGLRenderer::RenderTranslucent() gl_RenderState.SetCameraPos(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy), FIXED2FLOAT(viewz)); // final pass: translucent stuff - gl_RenderState.EnableAlphaTest(true); - gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.EnableBrightmap(true); @@ -576,7 +471,7 @@ void FGLRenderer::RenderTranslucent() glDepthMask(true); - gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); RenderAll.Unclock(); } @@ -617,6 +512,23 @@ void FGLRenderer::DrawScene(bool toscreen) } +static void FillScreen() +{ + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + gl_RenderState.EnableTexture(false); + gl_RenderState.Apply(); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(0, 0, 0, 0, 0); + ptr++; + ptr->Set(0, (float)SCREENHEIGHT, 0, 0, 0); + ptr++; + ptr->Set((float)SCREENWIDTH, 0, 0, 0, 0); + ptr++; + ptr->Set((float)SCREENWIDTH, (float)SCREENHEIGHT, 0, 0, 0); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); +} + //========================================================================== // // Draws a blend over the entire view @@ -643,12 +555,12 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) { if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC)) { - switch(in_area) + switch (in_area) { default: - case area_normal: blendv=viewsector->heightsec->midmap; break; - case area_above: blendv=viewsector->heightsec->topmap; break; - case area_below: blendv=viewsector->heightsec->bottommap; break; + case area_normal: blendv = viewsector->heightsec->midmap; break; + case area_above: blendv = viewsector->heightsec->topmap; break; + case area_below: blendv = viewsector->heightsec->bottommap; break; } } } @@ -656,70 +568,62 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) { TArray & lightlist = viewsector->e->XFloor.lightlist; - for(unsigned int i=0;ifloorplane.ZatPoint(viewx,viewy); + if (i < lightlist.Size() - 1) + lightbottom = lightlist[i + 1].plane.ZatPoint(viewx, viewy); + else + lightbottom = viewsector->floorplane.ZatPoint(viewx, viewy); - if (lightbottomflags&FF_FADEWALLS))) + if (lightbottom < viewz && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS))) { // 3d floor 'fog' is rendered as a blending value - blendv=lightlist[i].blend; + blendv = lightlist[i].blend; // If this is the same as the sector's it doesn't apply! - if (blendv == viewsector->ColorMap->Fade) blendv=0; + if (blendv == viewsector->ColorMap->Fade) blendv = 0; // a little hack to make this work for Legacy maps. - if (blendv.a==0 && blendv!=0) blendv.a=128; + if (blendv.a == 0 && blendv != 0) blendv.a = 128; break; } } } - } - if (blendv.a==0) - { - blendv = R_BlendForColormap(blendv); - if (blendv.a==255) + if (blendv.a == 0) { - // The calculated average is too dark so brighten it according to the palettes's overall brightness - int maxcol = MAX(MAX(framebuffer->palette_brightness, blendv.r), MAX(blendv.g, blendv.b)); - blendv.r = blendv.r * 255 / maxcol; - blendv.g = blendv.g * 255 / maxcol; - blendv.b = blendv.b * 255 / maxcol; + blendv = R_BlendForColormap(blendv); + if (blendv.a == 255) + { + // The calculated average is too dark so brighten it according to the palettes's overall brightness + int maxcol = MAX(MAX(framebuffer->palette_brightness, blendv.r), MAX(blendv.g, blendv.b)); + blendv.r = blendv.r * 255 / maxcol; + blendv.g = blendv.g * 255 / maxcol; + blendv.b = blendv.b * 255 / maxcol; + } } - } - if (blendv.a==255) - { - - extra_red = blendv.r / 255.0f; - extra_green = blendv.g / 255.0f; - extra_blue = blendv.b / 255.0f; - - // If this is a multiplicative blend do it separately and add the additive ones on top of it! - blendv=0; - - // black multiplicative blends are ignored - if (extra_red || extra_green || extra_blue) + if (blendv.a == 255) { - gl_RenderState.EnableAlphaTest(false); - gl_RenderState.EnableTexture(false); - gl_RenderState.BlendFunc(GL_DST_COLOR,GL_ZERO); - glColor4f(extra_red, extra_green, extra_blue, 1.0f); - gl_RenderState.Apply(true); - glBegin(GL_TRIANGLE_STRIP); - glVertex2f( 0.0f, 0.0f); - glVertex2f( 0.0f, (float)SCREENHEIGHT); - glVertex2f( (float)SCREENWIDTH, 0.0f); - glVertex2f( (float)SCREENWIDTH, (float)SCREENHEIGHT); - glEnd(); + + extra_red = blendv.r / 255.0f; + extra_green = blendv.g / 255.0f; + extra_blue = blendv.b / 255.0f; + + // If this is a multiplicative blend do it separately and add the additive ones on top of it. + blendv = 0; + + // black multiplicative blends are ignored + if (extra_red || extra_green || extra_blue) + { + gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); + gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f); + FillScreen(); + } + } + else if (blendv.a) + { + V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, blendv.a / 255.0f, blend); } - } - else if (blendv.a) - { - V_AddBlend (blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, blendv.a/255.0f,blend); } // This mostly duplicates the code in shared_sbar.cpp @@ -742,16 +646,8 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) if (blend[3]>0.0f) { gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.EnableAlphaTest(false); - gl_RenderState.EnableTexture(false); - glColor4fv(blend); - gl_RenderState.Apply(true); - glBegin(GL_TRIANGLE_STRIP); - glVertex2f( 0.0f, 0.0f); - glVertex2f( 0.0f, (float)SCREENHEIGHT); - glVertex2f( (float)SCREENWIDTH, 0.0f); - glVertex2f( (float)SCREENWIDTH, (float)SCREENHEIGHT); - glEnd(); + gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]); + FillScreen(); } } @@ -779,7 +675,6 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) } glDisable(GL_STENCIL_TEST); - glDisable(GL_POLYGON_SMOOTH); framebuffer->Begin2D(false); @@ -789,14 +684,15 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) { DrawPlayerSprites (viewsector, false); } + gl_RenderState.SetFixedColormap(CM_DEFAULT); + gl_RenderState.SetSoftLightLevel(-1); DrawTargeterSprites(); DrawBlend(viewsector); // Restore standard rendering state gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor3f(1.0f,1.0f,1.0f); + gl_RenderState.ResetColor(); gl_RenderState.EnableTexture(true); - gl_RenderState.EnableAlphaTest(true); glDisable(GL_SCISSOR_TEST); } @@ -862,6 +758,7 @@ void FGLRenderer::SetFixedColormap (player_t *player) } } } + gl_RenderState.SetFixedColormap(gl_fixedcolormap); } //----------------------------------------------------------------------------- @@ -900,6 +797,8 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper SetCameraPos(viewx, viewy, viewz, viewangle); SetViewMatrix(false, false); + gl_RenderState.ApplyMatrices(); + GLRenderer->mLights->Clear(); clipper.Clear(); angle_t a1 = FrustumAngle(); @@ -924,6 +823,7 @@ void FGLRenderer::RenderView (player_t* player) OpenGLFrameBuffer* GLTarget = static_cast(screen); AActor *&LastCamera = GLTarget->LastCamera; + checkBenchActive(); if (player->camera != LastCamera) { // If the camera changed don't interpolate @@ -932,7 +832,8 @@ void FGLRenderer::RenderView (player_t* player) LastCamera=player->camera; } - mVBO->BindVBO(); + gl_RenderState.SetVertexBuffer(mVBO); + GLRenderer->mVBO->Reset(); // reset statistics counters ResetProfilingData(); @@ -993,6 +894,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei bounds.height=height; glFlush(); SetFixedColormap(player); + gl_RenderState.SetVertexBuffer(mVBO); + GLRenderer->mVBO->Reset(); // Check if there's some lights. If not some code can be skipped. TThinkerIterator it(STAT_DLIGHT); @@ -1001,6 +904,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true, false); glDisable(GL_STENCIL_TEST); + gl_RenderState.SetFixedColormap(CM_DEFAULT); + gl_RenderState.SetSoftLightLevel(-1); screen->Begin2D(false); DrawBlend(viewsector); glFlush(); @@ -1063,7 +968,7 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache) { if (cache) { - tex->PrecacheGL(); + tex->PrecacheGL(cache); } else { @@ -1158,6 +1063,7 @@ void FGLInterface::RenderView(player_t *player) void FGLInterface::Init() { gl_ParseDefs(); + gl_InitData(); } //=========================================================================== @@ -1170,22 +1076,15 @@ extern TexFilter_s TexFilter[]; void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, int FOV) { - FMaterial * gltex = FMaterial::ValidateTexture(tex); + FMaterial * gltex = FMaterial::ValidateTexture(tex, false); - int width = gltex->TextureWidth(GLUSE_TEXTURE); - int height = gltex->TextureHeight(GLUSE_TEXTURE); + int width = gltex->TextureWidth(); + int height = gltex->TextureHeight(); gl_fixedcolormap=CM_DEFAULT; + gl_RenderState.SetFixedColormap(CM_DEFAULT); - bool usefb; - - if (gl.flags & RFL_FRAMEBUFFER) - { - usefb = gl_usefb || width > screen->GetWidth() || height > screen->GetHeight(); - } - else usefb = false; - - + bool usefb = gl_usefb || width > screen->GetWidth() || height > screen->GetHeight(); if (!usefb) { glFlush(); @@ -1212,15 +1111,15 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in GL_IRECT bounds; bounds.left=bounds.top=0; - bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth(GLUSE_TEXTURE)); - bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight(GLUSE_TEXTURE)); + bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth()); + bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight()); GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false); if (!usefb) { glFlush(); - gltex->Bind(CM_DEFAULT, 0, 0); + gl_RenderState.SetMaterial(gltex, 0, 0, -1, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height); } else @@ -1228,8 +1127,6 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in GLRenderer->EndOffscreen(); } - gltex->Bind(CM_DEFAULT, 0, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); tex->SetUpdated(); } diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index b236f45d8..d208e6875 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -111,7 +111,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) } FTextureID texno = s->GetTexture(pos); - skyinfo.texture[0] = FMaterial::ValidateTexture(texno, true); + skyinfo.texture[0] = FMaterial::ValidateTexture(texno, false, true); if (!skyinfo.texture[0] || skyinfo.texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky; skyinfo.skytexno1 = texno; skyinfo.x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos)); @@ -123,7 +123,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) normalsky: if (level.flags&LEVEL_DOUBLESKY) { - skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, true); + skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, false, true); skyinfo.x_offset[1] = GLRenderer->mSky1Pos; skyinfo.doublesky = true; } @@ -131,14 +131,14 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) && sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first! { - skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, true); + skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, false, true); skyinfo.skytexno1=sky2texture; skyinfo.sky2 = true; skyinfo.x_offset[0] = GLRenderer->mSky2Pos; } else { - skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, true); + skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, false, true); skyinfo.skytexno1=sky1texture; skyinfo.x_offset[0] = GLRenderer->mSky1Pos; } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index dee3ea4e3..a6ee502d5 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -45,6 +45,7 @@ #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/scene/gl_drawinfo.h" @@ -63,280 +64,245 @@ // //----------------------------------------------------------------------------- -CVAR (Int, gl_sky_detail, 16, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -EXTERN_CVAR (Bool, r_stretchsky) +CVAR(Float, skyoffset, 0, 0) // for testing extern int skyfog; -// The texture offset to be applied to the texture coordinates in SkyVertex(). - -static angle_t maxSideAngle = ANGLE_180 / 3; -static int rows, columns; -static fixed_t scale = 10000 << FRACBITS; -static bool yflip; -static int texw; -static float yAdd; -static bool foglayer; -static bool secondlayer; -static float R,G,B; -static bool skymirror; - -#define SKYHEMI_UPPER 0x1 -#define SKYHEMI_LOWER 0x2 -#define SKYHEMI_JUST_CAP 0x4 // Just draw the top or bottom cap. - - //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- -static void SkyVertex(int r, int c) +FSkyVertexBuffer::FSkyVertexBuffer() { - angle_t topAngle= (angle_t)(c / (float)columns * ANGLE_MAX); - angle_t sideAngle = maxSideAngle * (rows - r) / rows; + CreateDome(); + + glBindVertexArray(vao_id); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x); + glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u); + glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color); + glEnableVertexAttribArray(VATTR_VERTEX); + glEnableVertexAttribArray(VATTR_TEXCOORD); + glEnableVertexAttribArray(VATTR_COLOR); + glBindVertexArray(0); + +} + +FSkyVertexBuffer::~FSkyVertexBuffer() +{ +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FSkyVertexBuffer::SkyVertex(int r, int c, bool yflip) +{ + static const angle_t maxSideAngle = ANGLE_180 / 3; + static const fixed_t scale = 10000 << FRACBITS; + + angle_t topAngle= (angle_t)(c / (float)mColumns * ANGLE_MAX); + angle_t sideAngle = maxSideAngle * (mRows - r) / mRows; fixed_t height = finesine[sideAngle>>ANGLETOFINESHIFT]; fixed_t realRadius = FixedMul(scale, finecosine[sideAngle>>ANGLETOFINESHIFT]); fixed_t x = FixedMul(realRadius, finecosine[topAngle>>ANGLETOFINESHIFT]); fixed_t y = (!yflip) ? FixedMul(scale, height) : FixedMul(scale, height) * -1; fixed_t z = FixedMul(realRadius, finesine[topAngle>>ANGLETOFINESHIFT]); - float fx, fy, fz; - float color = r * 1.f / rows; - float u, v; - float timesRepeat; + + FSkyVertex vert; - timesRepeat = (short)(4 * (256.f / texw)); - if (timesRepeat == 0.f) timesRepeat = 1.f; - - if (!foglayer) + vert.color = r == 0 ? 0xffffff : 0xffffffff; + + // And the texture coordinates. + if(!yflip) // Flipped Y is for the lower hemisphere. { - gl_SetColor(255, 0, NULL, r==0? 0.0f : 1.0f); - - // And the texture coordinates. - if(!yflip) // Flipped Y is for the lower hemisphere. - { - u = (-timesRepeat * c / (float)columns) ; - v = (r / (float)rows) + yAdd; - } - else - { - u = (-timesRepeat * c / (float)columns) ; - v = 1.0f + ((rows-r)/(float)rows) + yAdd; - } - - - glTexCoord2f(skymirror? -u:u, v); + vert.u = (-c / (float)mColumns) ; + vert.v = (r / (float)mRows); } + else + { + vert.u = (-c / (float)mColumns); + vert.v = 1.0f + ((mRows - r) / (float)mRows); + } + if (r != 4) y+=FRACUNIT*300; // And finally the vertex. - fx =-FIXED2FLOAT(x); // Doom mirrors the sky vertically! - fy = FIXED2FLOAT(y); - fz = FIXED2FLOAT(z); - glVertex3f(fx, fy - 1.f, fz); + vert.x =-FIXED2FLOAT(x); // Doom mirrors the sky vertically! + vert.y = FIXED2FLOAT(y) - 1.f; + vert.z = FIXED2FLOAT(z); + + mVertices.Push(vert); } //----------------------------------------------------------------------------- // -// Hemi is Upper or Lower. Zero is not acceptable. -// The current texture is used. SKYHEMI_NO_TOPCAP can be used. +// // //----------------------------------------------------------------------------- -static void RenderSkyHemisphere(int hemi, bool mirror) +void FSkyVertexBuffer::CreateSkyHemisphere(int hemi) { int r, c; - - if (hemi & SKYHEMI_LOWER) + bool yflip = !!(hemi & SKYHEMI_LOWER); + + mPrimStart.Push(mVertices.Size()); + + for (c = 0; c < mColumns; c++) { - yflip = true; - } - else - { - yflip = false; + SkyVertex(1, c, yflip); } - skymirror = mirror; - - // The top row (row 0) is the one that's faded out. - // There must be at least 4 columns. The preferable number - // is 4n, where n is 1, 2, 3... There should be at least - // two rows because the first one is always faded. - rows = 4; - - if (hemi & SKYHEMI_JUST_CAP) - { - return; - } - - - // Draw the cap as one solid color polygon - if (!foglayer) - { - columns = 4 * (gl_sky_detail > 0 ? gl_sky_detail : 1); - foglayer=true; - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(true); - - - if (!secondlayer) - { - glColor3f(R, G ,B); - glBegin(GL_TRIANGLE_FAN); - for(c = 0; c < columns; c++) - { - SkyVertex(1, c); - } - glEnd(); - } - - gl_RenderState.EnableTexture(true); - foglayer=false; - gl_RenderState.Apply(); - } - else - { - gl_RenderState.Apply(true); - columns=4; // no need to do more! - glBegin(GL_TRIANGLE_FAN); - for(c = 0; c < columns; c++) - { - SkyVertex(0, c); - } - glEnd(); - } - // The total number of triangles per hemisphere can be calculated // as follows: rows * columns * 2 + 2 (for the top cap). - for(r = 0; r < rows; r++) + for (r = 0; r < mRows; r++) { - if (yflip) + mPrimStart.Push(mVertices.Size()); + for (c = 0; c <= mColumns; c++) { - glBegin(GL_TRIANGLE_STRIP); - SkyVertex(r + 1, 0); - SkyVertex(r, 0); - for(c = 1; c <= columns; c++) - { - SkyVertex(r + 1, c); - SkyVertex(r, c); - } - glEnd(); - } - else - { - glBegin(GL_TRIANGLE_STRIP); - SkyVertex(r, 0); - SkyVertex(r + 1, 0); - for(c = 1; c <= columns; c++) - { - SkyVertex(r, c); - SkyVertex(r + 1, c); - } - glEnd(); + SkyVertex(r + yflip, c, yflip); + SkyVertex(r + 1 - yflip, c, yflip); } } } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FSkyVertexBuffer::CreateDome() +{ + // the first thing we put into the buffer is the fog layer object which is just 4 triangles around the viewpoint. + + mVertices.Reserve(12); + mVertices[0].Set( 1.0f, 1.0f, -1.0f); + mVertices[1].Set( 1.0f, -1.0f, -1.0f); + mVertices[2].Set(-1.0f, 0.0f, -1.0f); + + mVertices[3].Set( 1.0f, 1.0f, -1.0f); + mVertices[4].Set( 1.0f, -1.0f, -1.0f); + mVertices[5].Set( 0.0f, 0.0f, 1.0f); + + mVertices[6].Set(-1.0f, 0.0f, -1.0f); + mVertices[7].Set( 1.0f, 1.0f, -1.0f); + mVertices[8].Set( 0.0f, 0.0f, 1.0f); + + mVertices[9].Set(1.0f, -1.0f, -1.0f); + mVertices[10].Set(-1.0f, 0.0f, -1.0f); + mVertices[11].Set( 0.0f, 0.0f, 1.0f); + + mColumns = 128; + mRows = 4; + CreateSkyHemisphere(SKYHEMI_UPPER); + CreateSkyHemisphere(SKYHEMI_LOWER); + mPrimStart.Push(mVertices.Size()); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], GL_STATIC_DRAW); +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +inline void FSkyVertexBuffer::RenderRow(int prim, int row) +{ + glDrawArrays(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]); +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) +{ + int rc = mRows + 1; + + // The caps only get drawn for the main layer but not for the overlay. + if (mode == SKYMODE_MAINLAYER && tex != NULL) + { + PalEntry pe = tex->tex->GetSkyCapColor(false); + gl_RenderState.SetObjectColor(pe); + gl_RenderState.EnableTexture(false); + gl_RenderState.Apply(); + RenderRow(GL_TRIANGLE_FAN, 0); + + pe = tex->tex->GetSkyCapColor(true); + gl_RenderState.SetObjectColor(pe); + gl_RenderState.Apply(); + RenderRow(GL_TRIANGLE_FAN, rc); + gl_RenderState.EnableTexture(true); + } + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.Apply(); + for (int i = 1; i <= mRows; i++) + { + RenderRow(GL_TRIANGLE_STRIP, i); + RenderRow(GL_TRIANGLE_STRIP, rc + i); + } +} + //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- -CVAR(Float, skyoffset, 0, 0) // for testing -static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float y_offset, bool mirror, int CM_Index) +void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, int mode) { int texh = 0; - bool texscale = false; + int texw = 0; - // 57 worls units roughly represent one sky texel for the glTranslate call. + // 57 world units roughly represent one sky texel for the glTranslate call. const float skyoffsetfactor = 57; if (tex) { - glPushMatrix(); - tex->Bind(CM_Index, 0, 0); - texw = tex->TextureWidth(GLUSE_TEXTURE); - texh = tex->TextureHeight(GLUSE_TEXTURE); + gl_RenderState.SetMaterial(tex, CLAMP_NONE, 0, -1, false); + texw = tex->TextureWidth(); + texh = tex->TextureHeight(); + gl_RenderState.EnableModelMatrix(true); - glRotatef(-180.0f+x_offset, 0.f, 1.f, 0.f); - yAdd = y_offset/texh; + gl_RenderState.mModelMatrix.loadIdentity(); + gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, 0.f, 1.f, 0.f); + float xscale = 1024.f / float(texw); + float yscale = 1.f; if (texh < 200) { - glTranslatef(0.f, -1250.f, 0.f); - glScalef(1.f, texh/230.f, 1.f); + gl_RenderState.mModelMatrix.translate(0.f, -1250.f, 0.f); + gl_RenderState.mModelMatrix.scale(1.f, texh/230.f, 1.f); } else if (texh <= 240) { - glTranslatef(0.f, (200 - texh + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); - glScalef(1.f, 1.f + ((texh-200.f)/200.f) * 1.17f, 1.f); + gl_RenderState.mModelMatrix.translate(0.f, (200 - texh + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); + gl_RenderState.mModelMatrix.scale(1.f, 1.f + ((texh-200.f)/200.f) * 1.17f, 1.f); } else { - glTranslatef(0.f, (-40 + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); - glScalef(1.f, 1.2f * 1.17f, 1.f); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - glScalef(1.f, 240.f / texh, 1.f); - glMatrixMode(GL_MODELVIEW); - texscale = true; + gl_RenderState.mModelMatrix.translate(0.f, (-40 + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); + gl_RenderState.mModelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); + yscale = 240.f / texh; } + gl_RenderState.EnableTextureMatrix(true); + gl_RenderState.mTextureMatrix.loadIdentity(); + gl_RenderState.mTextureMatrix.scale(mirror? -xscale : xscale, yscale, 1.f); + gl_RenderState.mTextureMatrix.translate(1.f, y_offset / texh, 1.f); } - if (tex && !secondlayer) - { - PalEntry pe = tex->tex->GetSkyCapColor(false); - if (CM_Index!=CM_DEFAULT) ModifyPalette(&pe, &pe, CM_Index, 1); - - R=pe.r/255.0f; - G=pe.g/255.0f; - B=pe.b/255.0f; - - if (gl_fixedcolormap) - { - float rr, gg, bb; - - gl_GetLightColor(255, 0, NULL, &rr, &gg, &bb); - R*=rr; - G*=gg; - B*=bb; - } - } - - RenderSkyHemisphere(SKYHEMI_UPPER, mirror); - - if (tex && !secondlayer) - { - PalEntry pe = tex->tex->GetSkyCapColor(true); - if (CM_Index!=CM_DEFAULT) ModifyPalette(&pe, &pe, CM_Index, 1); - R=pe.r/255.0f; - G=pe.g/255.0f; - B=pe.b/255.0f; - - if (gl_fixedcolormap != CM_DEFAULT) - { - float rr,gg,bb; - - gl_GetLightColor(255, 0, NULL, &rr, &gg, &bb); - R*=rr; - G*=gg; - B*=bb; - } - } - - RenderSkyHemisphere(SKYHEMI_LOWER, mirror); - if (texscale) - { - glMatrixMode(GL_TEXTURE); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } - if (tex) glPopMatrix(); - + GLRenderer->mSkyVBO->RenderDome(tex, mode); + gl_RenderState.EnableTextureMatrix(false); + gl_RenderState.EnableModelMatrix(false); } @@ -346,185 +312,149 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float // //----------------------------------------------------------------------------- -static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int CM_Index, bool sky2) +static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool sky2) { FSkyBox * sb = static_cast(gltex->tex); int faces; FMaterial * tex; + gl_RenderState.EnableModelMatrix(true); + gl_RenderState.mModelMatrix.loadIdentity(); + if (!sky2) - glRotatef(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y); + gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y); else - glRotatef(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y); - - glColor3f(R, G ,B); + gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y); + FFlatVertex *ptr; if (sb->faces[5]) { faces=4; // north - tex = FMaterial::ValidateTexture(sb->faces[0]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[0], false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); - glVertex3f(128.f, 128.f, -128.f); - glTexCoord2f(1, 0); - glVertex3f(-128.f, 128.f, -128.f); - glTexCoord2f(1, 1); - glVertex3f(-128.f, -128.f, -128.f); - glTexCoord2f(0, 1); - glVertex3f(128.f, -128.f, -128.f); - glEnd(); + + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(128.f, 128.f, -128.f, 0, 0); + ptr++; + ptr->Set(-128.f, 128.f, -128.f, 1, 0); + ptr++; + ptr->Set(128.f, -128.f, -128.f, 0, 1); + ptr++; + ptr->Set(-128.f, -128.f, -128.f, 1, 1); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // east - tex = FMaterial::ValidateTexture(sb->faces[1]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[1], false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); - glVertex3f(-128.f, 128.f, -128.f); - glTexCoord2f(1, 0); - glVertex3f(-128.f, 128.f, 128.f); - glTexCoord2f(1, 1); - glVertex3f(-128.f, -128.f, 128.f); - glTexCoord2f(0, 1); - glVertex3f(-128.f, -128.f, -128.f); - glEnd(); + + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(-128.f, 128.f, -128.f, 0, 0); + ptr++; + ptr->Set(-128.f, 128.f, 128.f, 1, 0); + ptr++; + ptr->Set(-128.f, -128.f, -128.f, 0, 1); + ptr++; + ptr->Set(-128.f, -128.f, 128.f, 1, 1); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // south - tex = FMaterial::ValidateTexture(sb->faces[2]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[2], false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); - glVertex3f(-128.f, 128.f, 128.f); - glTexCoord2f(1, 0); - glVertex3f(128.f, 128.f, 128.f); - glTexCoord2f(1, 1); - glVertex3f(128.f, -128.f, 128.f); - glTexCoord2f(0, 1); - glVertex3f(-128.f, -128.f, 128.f); - glEnd(); + + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(-128.f, 128.f, 128.f, 0, 0); + ptr++; + ptr->Set(128.f, 128.f, 128.f, 1, 0); + ptr++; + ptr->Set(-128.f, -128.f, 128.f, 0, 1); + ptr++; + ptr->Set(128.f, -128.f, 128.f, 1, 1); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // west - tex = FMaterial::ValidateTexture(sb->faces[3]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[3], false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); - glVertex3f(128.f, 128.f, 128.f); - glTexCoord2f(1, 0); - glVertex3f(128.f, 128.f, -128.f); - glTexCoord2f(1, 1); - glVertex3f(128.f, -128.f, -128.f); - glTexCoord2f(0, 1); - glVertex3f(128.f, -128.f, 128.f); - glEnd(); + + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(128.f, 128.f, 128.f, 0, 0); + ptr++; + ptr->Set(128.f, 128.f, -128.f, 1, 0); + ptr++; + ptr->Set(128.f, -128.f, 128.f, 0, 1); + ptr++; + ptr->Set(128.f, -128.f, -128.f, 1, 1); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } else { faces=1; - // all 4 sides - tex = FMaterial::ValidateTexture(sb->faces[0]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); - gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); - glVertex3f(128.f, 128.f, -128.f); - glTexCoord2f(.25f, 0); - glVertex3f(-128.f, 128.f, -128.f); - glTexCoord2f(.25f, 1); - glVertex3f(-128.f, -128.f, -128.f); - glTexCoord2f(0, 1); - glVertex3f(128.f, -128.f, -128.f); - glEnd(); - - // east - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(.25f, 0); - glVertex3f(-128.f, 128.f, -128.f); - glTexCoord2f(.5f, 0); - glVertex3f(-128.f, 128.f, 128.f); - glTexCoord2f(.5f, 1); - glVertex3f(-128.f, -128.f, 128.f); - glTexCoord2f(.25f, 1); - glVertex3f(-128.f, -128.f, -128.f); - glEnd(); - - // south - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(.5f, 0); - glVertex3f(-128.f, 128.f, 128.f); - glTexCoord2f(.75f, 0); - glVertex3f(128.f, 128.f, 128.f); - glTexCoord2f(.75f, 1); - glVertex3f(128.f, -128.f, 128.f); - glTexCoord2f(.5f, 1); - glVertex3f(-128.f, -128.f, 128.f); - glEnd(); - - // west - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(.75f, 0); - glVertex3f(128.f, 128.f, 128.f); - glTexCoord2f(1, 0); - glVertex3f(128.f, 128.f, -128.f); - glTexCoord2f(1, 1); - glVertex3f(128.f, -128.f, -128.f); - glTexCoord2f(.75f, 1); - glVertex3f(128.f, -128.f, 128.f); - glEnd(); + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(128.f, 128.f, -128.f, 0, 0); + ptr++; + ptr->Set(128.f, -128.f, -128.f, 0, 1); + ptr++; + ptr->Set(-128.f, 128.f, -128.f, 0.25f, 0); + ptr++; + ptr->Set(-128.f, -128.f, -128.f, 0.25f, 1); + ptr++; + ptr->Set(-128.f, 128.f, 128.f, 0.5f, 0); + ptr++; + ptr->Set(-128.f, -128.f, 128.f, 0.5f, 1); + ptr++; + ptr->Set(128.f, 128.f, 128.f, 0.75f, 0); + ptr++; + ptr->Set(128.f, -128.f, 128.f, 0.75f, 1); + ptr++; + ptr->Set(128.f, 128.f, -128.f, 1, 0); + ptr++; + ptr->Set(128.f, -128.f, -128.f, 1, 1); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } // top - tex = FMaterial::ValidateTexture(sb->faces[faces]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[faces], false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - if (!sb->fliptop) - { - glTexCoord2f(0, 0); - glVertex3f(128.f, 128.f, -128.f); - glTexCoord2f(1, 0); - glVertex3f(-128.f, 128.f, -128.f); - glTexCoord2f(1, 1); - glVertex3f(-128.f, 128.f, 128.f); - glTexCoord2f(0, 1); - glVertex3f(128.f, 128.f, 128.f); - } - else - { - glTexCoord2f(0, 0); - glVertex3f(128.f, 128.f, 128.f); - glTexCoord2f(1, 0); - glVertex3f(-128.f, 128.f, 128.f); - glTexCoord2f(1, 1); - glVertex3f(-128.f, 128.f, -128.f); - glTexCoord2f(0, 1); - glVertex3f(128.f, 128.f, -128.f); - } - glEnd(); + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(128.f, 128.f, -128.f, 0, sb->fliptop); + ptr++; + ptr->Set(-128.f, 128.f, -128.f, 1, sb->fliptop); + ptr++; + ptr->Set(128.f, 128.f, 128.f, 0, !sb->fliptop); + ptr++; + ptr->Set(-128.f, 128.f, 128.f, 1, !sb->fliptop); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // bottom - tex = FMaterial::ValidateTexture(sb->faces[faces+1]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[faces+1], false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); - glVertex3f(128.f, -128.f, -128.f); - glTexCoord2f(1, 0); - glVertex3f(-128.f, -128.f, -128.f); - glTexCoord2f(1, 1); - glVertex3f(-128.f, -128.f, 128.f); - glTexCoord2f(0, 1); - glVertex3f(128.f, -128.f, 128.f); - glEnd(); - + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(128.f, -128.f, -128.f, 0, 0); + ptr++; + ptr->Set(-128.f, -128.f, -128.f, 1, 0); + ptr++; + ptr->Set(128.f, -128.f, 128.f, 0, 1); + ptr++; + ptr->Set(-128.f, -128.f, 128.f, 1, 1); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + gl_RenderState.EnableModelMatrix(false); } //----------------------------------------------------------------------------- @@ -535,80 +465,59 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C void GLSkyPortal::DrawContents() { bool drawBoth = false; - int CM_Index; - PalEntry FadeColor(0,0,0,0); // We have no use for Doom lighting special handling here, so disable it for this function. int oldlightmode = glset.lightmode; if (glset.lightmode == 8) glset.lightmode = 2; - if (gl_fixedcolormap) - { - CM_Index=gl_fixedcolormapfadecolor; - } - + gl_RenderState.ResetColor(); gl_RenderState.EnableFog(false); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gl_MatrixStack.Push(gl_RenderState.mViewMatrix); GLRenderer->SetupView(0, 0, 0, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); if (origin->texture[0] && origin->texture[0]->tex->gl_info.bSkybox) { - if (gl_fixedcolormap != CM_DEFAULT) - { - float rr,gg,bb; - - gl_GetLightColor(255, 0, NULL, &rr, &gg, &bb); - R=rr; - G=gg; - B=bb; - } - else R=G=B=1.f; - - RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], CM_Index, origin->sky2); - gl_RenderState.EnableAlphaTest(true); + RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2); } else { + gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO); if (origin->texture[0]==origin->texture[1] && origin->doublesky) origin->doublesky=false; if (origin->texture[0]) { gl_RenderState.SetTextureMode(TM_OPAQUE); - RenderDome(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, CM_Index); + RenderDome(origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER); gl_RenderState.SetTextureMode(TM_MODULATE); } - gl_RenderState.EnableAlphaTest(true); - gl_RenderState.AlphaFunc(GL_GEQUAL,0.05f); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.05f); if (origin->doublesky && origin->texture[1]) { - secondlayer=true; - RenderDome(FNullTextureID(), origin->texture[1], origin->x_offset[1], origin->y_offset, false, CM_Index); - secondlayer=false; + RenderDome(origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER); } - if (skyfog>0 && (FadeColor.r ||FadeColor.g || FadeColor.b)) + if (skyfog>0 && gl_fixedcolormap == CM_DEFAULT && (origin->fadecolor & 0xffffff) != 0) { + PalEntry FadeColor = origin->fadecolor; + FadeColor.a = clamp(skyfog, 0, 255); + gl_RenderState.EnableTexture(false); - foglayer=true; - glColor4f(FadeColor.r/255.0f,FadeColor.g/255.0f,FadeColor.b/255.0f,skyfog/255.0f); - RenderDome(FNullTextureID(), NULL, 0, 0, false, CM_DEFAULT); + gl_RenderState.SetObjectColor(FadeColor); + gl_RenderState.Apply(); + glDrawArrays(GL_TRIANGLES, 0, 12); gl_RenderState.EnableTexture(true); - foglayer=false; + gl_RenderState.SetObjectColor(0xffffffff); } + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } - glPopMatrix(); + gl_MatrixStack.Pop(gl_RenderState.mViewMatrix); + gl_RenderState.ApplyMatrices(); glset.lightmode = oldlightmode; } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index a600ef5a2..5d8995a34 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -52,6 +52,7 @@ #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" +#include "gl/renderer/gl_renderer.h" #include "gl/data/gl_data.h" #include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" @@ -60,6 +61,7 @@ #include "gl/shaders/gl_shader.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" +#include "gl/data/gl_vertexbuffer.h" CVAR(Bool, gl_usecolorblending, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, gl_spritebrightfog, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); @@ -110,12 +112,8 @@ CVAR(Bool, gl_nolayer, false, 0) //========================================================================== void GLSprite::Draw(int pass) { - if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) return; + if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return; - // Hack to enable bright sprites in faded maps - uint32 backupfade = Colormap.FadeColor.d; - if (gl_spritebrightfog && fullbright) - Colormap.FadeColor = 0; bool additivefog = false; @@ -126,25 +124,24 @@ void GLSprite::Draw(int pass) { // The translucent pass requires special setup for the various modes. - // Brightmaps will only be used when doing regular drawing ops and having no fog - if (!gl_spritebrightfog && (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE || - RenderStyle.BlendOp != STYLEOP_Add)) + // for special render styles brightmaps would not look good - especially for subtractive. + if (RenderStyle.BlendOp != STYLEOP_Add) { gl_RenderState.EnableBrightmap(false); } gl_SetRenderStyle(RenderStyle, false, // The rest of the needed checks are done inside gl_SetRenderStyle - trans > 1.f - FLT_EPSILON && gl_usecolorblending && gl_fixedcolormap < CM_FIRSTSPECIALCOLORMAP && actor && + trans > 1.f - FLT_EPSILON && gl_usecolorblending && gl_fixedcolormap == CM_DEFAULT && actor && fullbright && gltexture && !gltexture->GetTransparent()); if (hw_styleflags == STYLEHW_NoAlphaTest) { - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); } else { - gl_RenderState.AlphaFunc(GL_GEQUAL,trans*gl_mask_sprite_threshold); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); } if (RenderStyle.BlendOp == STYLEOP_Shadow) @@ -168,8 +165,8 @@ void GLSprite::Draw(int pass) minalpha*=factor; } - gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold); - glColor4f(0.2f,0.2f,0.2f,fuzzalpha); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); + gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, Colormap.desaturation); additivefog = true; } else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One) @@ -179,24 +176,13 @@ void GLSprite::Draw(int pass) } if (RenderStyle.BlendOp!=STYLEOP_Shadow) { - if (actor) + if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap) { - lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, ThingColor, trans, - fullbright || gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP, false); + gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL); } - else if (particle) - { - if (gl_light_particles) - { - lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, ThingColor); - } - else - { - gl_SetColor(lightlevel, rel, &Colormap, trans, ThingColor); - } - } - else return; + gl_SetColor(lightlevel, rel, Colormap, trans); } + gl_RenderState.SetObjectColor(ThingColor); if (gl_isBlack(Colormap.FadeColor)) foglevel=lightlevel; @@ -206,11 +192,6 @@ void GLSprite::Draw(int pass) additivefog = true; } - if (RenderStyle.Flags & STYLEF_InvertOverlay) - { - Colormap.FadeColor = Colormap.FadeColor.InverseColor(); - additivefog=false; - } if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub) { if (!modelframe) @@ -218,18 +199,9 @@ void GLSprite::Draw(int pass) // non-black fog with subtractive style needs special treatment if (!gl_isBlack(Colormap.FadeColor)) { - if (gl.shadermodel >= 4 && !gl_nolayer) - { - // fog layer only works on modern hardware. - foglayer = true; - // Due to the two-layer approach we need to force an alpha test that lets everything pass - gl_RenderState.AlphaFunc(GL_GREATER, 0); - } - else - { - // this at least partially handles the fog issue - Colormap.FadeColor = Colormap.FadeColor.InverseColor(); - } + foglayer = true; + // Due to the two-layer approach we need to force an alpha test that lets everything pass + gl_RenderState.AlphaFunc(GL_GREATER, 0); } } else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work. @@ -242,7 +214,7 @@ void GLSprite::Draw(int pass) gl_RenderState.SetFog(0, 0); } - if (gltexture) gltexture->BindPatch(Colormap.colormap, translation, OverrideShader); + if (gltexture) gl_RenderState.SetMaterial(gltexture, CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); else if (!modelframe) gl_RenderState.EnableTexture(false); if (!modelframe) @@ -286,23 +258,18 @@ void GLSprite::Draw(int pass) v4 = Vector(x2, z2, y2); } - glBegin(GL_TRIANGLE_STRIP); - if (gltexture) - { - glTexCoord2f(ul, vt); glVertex3fv(&v1[0]); - glTexCoord2f(ur, vt); glVertex3fv(&v2[0]); - glTexCoord2f(ul, vb); glVertex3fv(&v3[0]); - glTexCoord2f(ur, vb); glVertex3fv(&v4[0]); - } - else // Particle - { - glVertex3fv(&v1[0]); - glVertex3fv(&v2[0]); - glVertex3fv(&v3[0]); - glVertex3fv(&v4[0]); - } - - glEnd(); + FFlatVertex *ptr; + unsigned int offset, count; + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(v1[0], v1[1], v1[2], ul, vt); + ptr++; + ptr->Set(v2[0], v2[1], v2[2], ur, vt); + ptr++; + ptr->Set(v3[0], v3[1], v3[2], ul, vb); + ptr++; + ptr->Set(v4[0], v4[1], v4[2], ur, vb); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); if (foglayer) { @@ -312,29 +279,13 @@ void GLSprite::Draw(int pass) gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.Apply(); - - glBegin(GL_TRIANGLE_STRIP); - if (gltexture) - { - glTexCoord2f(ul, vt); glVertex3fv(&v1[0]); - glTexCoord2f(ur, vt); glVertex3fv(&v2[0]); - glTexCoord2f(ul, vb); glVertex3fv(&v3[0]); - glTexCoord2f(ur, vb); glVertex3fv(&v4[0]); - } - else // Particle - { - glVertex3fv(&v1[0]); - glVertex3fv(&v2[0]); - glVertex3fv(&v3[0]); - glVertex3fv(&v4[0]); - } - glEnd(); - + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); + gl_RenderState.SetFixedColormap(CM_DEFAULT); } } else { - gl_RenderModel(this, Colormap.colormap); + gl_RenderModel(this); } if (pass==GLPASS_TRANSLUCENT) @@ -343,22 +294,9 @@ void GLSprite::Draw(int pass) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.SetTextureMode(TM_MODULATE); - - // [BB] Restore the alpha test after drawing a smooth particle. - if (hw_styleflags == STYLEHW_NoAlphaTest) - { - gl_RenderState.EnableAlphaTest(true); - } - else - { - gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); - } } - // End of gl_sprite_brightfog hack: restore FadeColor to normalcy - if (backupfade != Colormap.FadeColor.d) - Colormap.FadeColor = backupfade; - + gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.EnableTexture(true); gl_RenderState.SetDynLight(0,0,0); } @@ -377,13 +315,9 @@ inline void GLSprite::PutSprite(bool translucent) { list = GLDL_TRANSLUCENT; } - else if ((!gl_isBlack (Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)) - { - list = GLDL_FOGMASKED; - } else { - list = GLDL_MASKED; + list = GLDL_MODELS; } gl_drawinfo->drawlists[list].AddSprite(this); } @@ -425,13 +359,6 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent) copySprite.Colormap.LightColor.b=(255+v+v)/3; } - if (!gl_isWhite(ThingColor)) - { - copySprite.Colormap.LightColor.r=(copySprite.Colormap.LightColor.r*ThingColor.r)>>8; - copySprite.Colormap.LightColor.g=(copySprite.Colormap.LightColor.g*ThingColor.g)>>8; - copySprite.Colormap.LightColor.b=(copySprite.Colormap.LightColor.b*ThingColor.b)>>8; - } - z1=copySprite.z2=maplightbottom; vt=copySprite.vb=copySprite.vt+ (maplightbottom-copySprite.z1)*(copySprite.vb-copySprite.vt)/(z2-copySprite.z1); @@ -471,13 +398,6 @@ void GLSprite::SetSpriteColor(sector_t *sector, fixed_t center_y) Colormap.LightColor.g= Colormap.LightColor.b=(255+v+v)/3; } - - if (!gl_isWhite(ThingColor)) - { - Colormap.LightColor.r=(Colormap.LightColor.r*ThingColor.r)>>8; - Colormap.LightColor.g=(Colormap.LightColor.g*ThingColor.g)>>8; - Colormap.LightColor.b=(Colormap.LightColor.b*ThingColor.b)>>8; - } return; } } @@ -535,8 +455,9 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, fixed_t thingx, fixed_ if (top == -1000000.0f) top = FIXED2FLOAT(thing->Sector->ceilingplane.ZatPoint(thingx, thingy)); - float diffb = z2 - btm; - float difft = z1 - top; + // +/-1 to account for the one pixel empty frame around the sprite. + float diffb = (z2+1) - btm; + float difft = (z1-1) - top; if (diffb >= 0 /*|| !gl_sprite_clip_to_floor*/) diffb = 0; // Adjust sprites clipping into ceiling and adjust clipping adjustment for tall graphics if (smarterclip) @@ -678,12 +599,13 @@ void GLSprite::Process(AActor* thing,sector_t * sector) bool mirror; FTextureID patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, ang - thing->angle, &mirror); if (!patch.isValid()) return; - gltexture = FMaterial::ValidateTexture(patch, false); + int type = thing->renderflags & RF_SPRITETYPEMASK; + gltexture = FMaterial::ValidateTexture(patch, (type == RF_FACESPRITE), false); if (!gltexture) return; vt = gltexture->GetSpriteVT(); vb = gltexture->GetSpriteVB(); - gltexture->GetRect(&r, GLUSE_SPRITE); + gltexture->GetSpriteRect(&r); if (mirror) { r.left = -r.width - r.left; // mirror the sprite's x-offset @@ -704,7 +626,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) z1 = z - r.top; z2 = z1 - r.height; - float spriteheight = FIXED2FLOAT(spritescaleY) * gltexture->GetScaledHeightFloat(GLUSE_SPRITE); + float spriteheight = FIXED2FLOAT(spritescaleY) * r.height; // Tests show that this doesn't look good for many decorations and corpses if (spriteheight > 0 && gl_spriteclip > 0 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE) @@ -754,7 +676,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) // allow disabling of the fullbright flag by a brightmap definition // (e.g. to do the gun flashes of Doom's zombies correctly. fullbright = (thing->flags5 & MF5_BRIGHT) || - ((thing->renderflags & RF_FULLBRIGHT) && (!gl_BrightmapsActive() || !gltexture || !gltexture->tex->gl_info.bBrightmapDisablesFullbright)); + ((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->gl_info.bBrightmapDisablesFullbright)); lightlevel=fullbright? 255 : gl_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ? @@ -763,6 +685,10 @@ void GLSprite::Process(AActor* thing,sector_t * sector) lightlevel = (byte)gl_CheckSpriteGlow(rendersector, lightlevel, thingx, thingy, thingz); + ThingColor = (thing->RenderStyle.Flags & STYLEF_ColorIsFixed) ? thing->fillcolor : 0xffffff; + ThingColor.a = 255; + RenderStyle = thing->RenderStyle; + // colormap stuff is a little more complicated here... if (gl_fixedcolormap) { @@ -771,14 +697,14 @@ void GLSprite::Process(AActor* thing,sector_t * sector) || (gl_enhanced_nv_stealth == 3)) // Any fixed colormap enhancedvision=true; - Colormap.GetFixedColormap(); + Colormap.Clear(); if (gl_fixedcolormap==CM_LITE) { if (gl_enhanced_nightvision && (thing->IsKindOf(RUNTIME_CLASS(AInventory)) || thing->flags3&MF3_ISMONSTER || thing->flags&MF_MISSILE || thing->flags&MF_CORPSE)) { - Colormap.colormap = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP; + RenderStyle.Flags |= STYLEF_InvertSource; } } } @@ -804,18 +730,13 @@ void GLSprite::Process(AActor* thing,sector_t * sector) } else if (glset.nocoloredspritelighting) { - int v = (Colormap.LightColor.r /* * 77 */ + Colormap.LightColor.g /**143 */ + Colormap.LightColor.b /**35*/)/3;//255; - Colormap.LightColor.r= - Colormap.LightColor.g= - Colormap.LightColor.b=(255+v+v)/3; + Colormap.Decolorize(); } } translation=thing->Translation; - ThingColor=0xffffff; - RenderStyle = thing->RenderStyle; - OverrideShader = 0; + OverrideShader = -1; trans = FIXED2FLOAT(thing->alpha); hw_styleflags = STYLEHW_Normal; @@ -824,7 +745,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) RenderStyle.CheckFuzz(); if (RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl.shadermodel >= 4 && gl_fuzztype != 0) + if (gl_fuzztype != 0) { // Todo: implement shader selection here RenderStyle = LegacyRenderStyles[STYLE_Translucent]; @@ -951,7 +872,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s if (gl_fixedcolormap) { - Colormap.GetFixedColormap(); + Colormap.Clear(); } else if (!particle->bright) { @@ -984,8 +905,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s OverrideShader = 0; ThingColor = particle->color; - gl_ModifyColor(ThingColor.r, ThingColor.g, ThingColor.b, Colormap.colormap); - ThingColor.a=0; + ThingColor.a = 255; modelframe=NULL; gltexture=NULL; @@ -1005,7 +925,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s if (lump != NULL) { - gltexture=FMaterial::ValidateTexture(lump); + gltexture = FMaterial::ValidateTexture(lump, true); translation = 0; ul = gltexture->GetUL(); @@ -1013,7 +933,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s vt = gltexture->GetVT(); vb = gltexture->GetVB(); FloatRect r; - gltexture->GetRect(&r, GLUSE_PATCH); + gltexture->GetSpriteRect(&r); } } diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index b1216d86b..e66941283 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -59,245 +59,68 @@ //========================================================================== // -// Gets the light for a sprite - takes dynamic lights into account +// Sets a single light value from all dynamic lights affecting the specified location // //========================================================================== -bool gl_GetSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, int desaturation, float * out, line_t *line, int side) +void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec) { ADynamicLight *light; float frac, lr, lg, lb; float radius; - bool changed = false; + float out[3] = { 0.0f, 0.0f, 0.0f }; - out[0]=out[1]=out[2]=0; - - for(int j=0;j<2;j++) + // Go through both light lists + FLightNode * node = subsec->lighthead; + while (node) { - // Go through both light lists - FLightNode * node = subsec->lighthead[j]; - while (node) + light=node->lightsource; + if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer()) { - light=node->lightsource; - if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer()) + if (!(light->flags2&MF2_DORMANT) && + (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self)) { - if (!(light->flags2&MF2_DORMANT) && - (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self)) + float dist = FVector3(FIXED2FLOAT(x - light->x), FIXED2FLOAT(y - light->y), FIXED2FLOAT(z - light->z)).Length(); + radius = light->GetRadius() * gl_lights_size; + + if (dist < radius) { - float dist = FVector3(FIXED2FLOAT(x - light->x), FIXED2FLOAT(y - light->y), FIXED2FLOAT(z - light->z)).Length(); - radius = light->GetRadius() * gl_lights_size; + frac = 1.0f - (dist / radius); - if (dist < radius) + if (frac > 0) { - frac = 1.0f - (dist / radius); - - if (frac > 0) + lr = light->GetRed() / 255.0f * gl_lights_intensity; + lg = light->GetGreen() / 255.0f * gl_lights_intensity; + lb = light->GetBlue() / 255.0f * gl_lights_intensity; + if (light->IsSubtractive()) { - if (line != NULL) - { - if (P_PointOnLineSide(light->x, light->y, line) != side) - { - node = node->nextLight; - continue; - } - } - lr = light->GetRed() / 255.0f * gl_lights_intensity; - lg = light->GetGreen() / 255.0f * gl_lights_intensity; - lb = light->GetBlue() / 255.0f * gl_lights_intensity; - if (light->IsSubtractive()) - { - float bright = FVector3(lr, lg, lb).Length(); - FVector3 lightColor(lr, lg, lb); - lr = (bright - lr) * -1; - lg = (bright - lg) * -1; - lb = (bright - lb) * -1; - } - - out[0] += lr * frac; - out[1] += lg * frac; - out[2] += lb * frac; - changed = true; + float bright = FVector3(lr, lg, lb).Length(); + FVector3 lightColor(lr, lg, lb); + lr = (bright - lr) * -1; + lg = (bright - lg) * -1; + lb = (bright - lb) * -1; } + + out[0] += lr * frac; + out[1] += lg * frac; + out[2] += lb * frac; } } } - node = node->nextLight; } + node = node->nextLight; } - - // Desaturate dynamic lighting if applicable - if (desaturation>0 && desaturation<=CM_DESAT31) - { - float gray=(out[0]*77 + out[1]*143 + out[2]*37)/257; - - out[0]= (out[0]*(31-desaturation)+ gray*desaturation)/31; - out[1]= (out[1]*(31-desaturation)+ gray*desaturation)/31; - out[2]= (out[2]*(31-desaturation)+ gray*desaturation)/31; - } - return changed; + gl_RenderState.SetDynLight(out[0], out[1], out[2]); } - - -//========================================================================== -// -// Sets the light for a sprite - takes dynamic lights into account -// -//========================================================================== - -static int gl_SetSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, - int lightlevel, int rellight, FColormap * cm, float alpha, - PalEntry ThingColor, bool weapon) +void gl_SetDynSpriteLight(AActor *thing, particle_t *particle) { - float r,g,b; - float result[4]; // Korshun. - - gl_GetLightColor(lightlevel, rellight, cm, &r, &g, &b, weapon); - bool res = gl_GetSpriteLight(self, x, y, z, subsec, cm? cm->colormap : 0, result); - if (!res || glset.lightmode == 8) + if (thing != NULL) { - r *= ThingColor.r/255.f; - g *= ThingColor.g/255.f; - b *= ThingColor.b/255.f; - glColor4f(r, g, b, alpha); - if (glset.lightmode == 8) - { - glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(lightlevel, rellight, weapon) / 255.0f); // Korshun. - gl_RenderState.SetDynLight(result[0], result[1], result[2]); - } - return lightlevel; + gl_SetDynSpriteLight(thing, thing->x, thing->y, thing->z + (thing->height >> 1), thing->subsector); } - else + else if (particle != NULL) { - // Note: Due to subtractive lights the values can easily become negative so we have to clamp both - // at the low and top end of the range! - r = clamp(result[0]+r, 0, 1.0f); - g = clamp(result[1]+g, 0, 1.0f); - b = clamp(result[2]+b, 0, 1.0f); - - float dlightlevel = r*77 + g*143 + b*35; - - r *= ThingColor.r/255.f; - g *= ThingColor.g/255.f; - b *= ThingColor.b/255.f; - - glColor4f(r, g, b, alpha); - - if (dlightlevel == 0) return 0; - - if (glset.lightmode&2 && dlightlevel<192.f) - { - return xs_CRoundToInt(192.f - (192.f - dlightlevel) / 1.95f); - } - else - { - return xs_CRoundToInt(dlightlevel); - } + gl_SetDynSpriteLight(NULL, particle->x, particle->y, particle->z, particle->subsector); } } - -int gl_SetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm, - float alpha, PalEntry ThingColor, bool weapon) -{ - subsector_t * subsec = thing->subsector; - return gl_SetSpriteLight(thing, thing->x, thing->y, thing->z+(thing->height>>1), subsec, - lightlevel, rellight, cm, alpha, ThingColor, weapon); -} - -int gl_SetSpriteLight(particle_t * thing, int lightlevel, int rellight, FColormap *cm, float alpha, PalEntry ThingColor) -{ - return gl_SetSpriteLight(NULL, thing->x, thing->y, thing->z, thing->subsector, lightlevel, rellight, - cm, alpha, ThingColor, false); -} - -//========================================================================== -// -// Modifies the color values depending on the render style -// -//========================================================================== - -void gl_GetSpriteLighting(FRenderStyle style, AActor *thing, FColormap *cm, PalEntry &ThingColor) -{ - if (style.Flags & STYLEF_RedIsAlpha) - { - cm->colormap = CM_SHADE; - } - if (style.Flags & STYLEF_ColorIsFixed) - { - if (style.Flags & STYLEF_InvertSource) - { - ThingColor = PalEntry(thing->fillcolor).InverseColor(); - } - else - { - ThingColor = thing->fillcolor; - } - } - - // This doesn't work like in the software renderer. - if (style.Flags & STYLEF_InvertSource) - { - int gray = (cm->LightColor.r*77 + cm->LightColor.r*143 + cm->LightColor.r*36)>>8; - cm->LightColor.r = cm->LightColor.g = cm->LightColor.b = gray; - } -} - - -//========================================================================== -// -// Sets render state to draw the given render style -// -//========================================================================== - -int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int rellight, FColormap *cm, - PalEntry ThingColor, float alpha, bool fullbright, bool weapon) -{ - FColormap internal_cm; - - if (style.Flags & STYLEF_RedIsAlpha) - { - cm->colormap = CM_SHADE; - } - if (style.Flags & STYLEF_ColorIsFixed) - { - if (style.Flags & STYLEF_InvertSource) - { - ThingColor = PalEntry(thing->fillcolor).InverseColor(); - } - else - { - ThingColor = thing->fillcolor; - } - gl_ModifyColor(ThingColor.r, ThingColor.g, ThingColor.b, cm->colormap); - } - - // This doesn't work like in the software renderer. - if (style.Flags & STYLEF_InvertSource) - { - internal_cm = *cm; - cm = &internal_cm; - - int gray = (internal_cm.LightColor.r*77 + internal_cm.LightColor.r*143 + internal_cm.LightColor.r*36)>>8; - cm->LightColor.r = cm->LightColor.g = cm->LightColor.b = gray; - } - - if (style.BlendOp == STYLEOP_Shadow) - { - glColor4f(0.2f * ThingColor.r / 255.f, 0.2f * ThingColor.g / 255.f, - 0.2f * ThingColor.b / 255.f, (alpha = 0.33f)); - } - else - { - if (gl_light_sprites && gl_lights && GLRenderer->mLightCount && !fullbright) - { - lightlevel = gl_SetSpriteLight(thing, lightlevel, rellight, cm, alpha, ThingColor, weapon); - } - else - { - gl_SetColor(lightlevel, rellight, cm, alpha, ThingColor, weapon); - } - } - gl_RenderState.AlphaFunc(GL_GEQUAL,alpha*gl_mask_sprite_threshold); - return lightlevel; -} - diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index 3aff28d1f..c0f21adce 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -45,6 +45,7 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -53,7 +54,6 @@ #include "gl/utility/gl_templates.h" EXTERN_CVAR(Bool, gl_seamless) -extern int vertexcount; //========================================================================== // @@ -61,7 +61,7 @@ extern int vertexcount; // //========================================================================== -void GLWall::SplitUpperEdge(texcoord * tcs) +void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) { if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; @@ -73,7 +73,7 @@ void GLWall::SplitUpperEdge(texcoord * tcs) float facc = (zceil[1] - zceil[0]) / polyw; float facf = (zfloor[1] - zfloor[0]) / polyw; - for (int i=0; i < sidedef->numsegs - 1; i++) + for (int i = 0; i < sidedef->numsegs - 1; i++) { seg_t *cseg = sidedef->segs[i]; float sidefrac = cseg->sidefrac; @@ -82,10 +82,13 @@ void GLWall::SplitUpperEdge(texcoord * tcs) float fracfac = sidefrac - glseg.fracleft; - glTexCoord2f(tcs[1].u + facu * fracfac, tcs[1].v + facv * fracfac); - glVertex3f(cseg->v2->fx, ztop[0] + fact * fracfac, cseg->v2->fy); + ptr->x = cseg->v2->fx; + ptr->y = cseg->v2->fy; + ptr->z = ztop[0] + fact * fracfac; + ptr->u = tcs[1].u + facu * fracfac; + ptr->v = tcs[1].v + facv * fracfac; + ptr++; } - vertexcount += sidedef->numsegs-1; } //========================================================================== @@ -94,7 +97,7 @@ void GLWall::SplitUpperEdge(texcoord * tcs) // //========================================================================== -void GLWall::SplitLowerEdge(texcoord * tcs) +void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) { if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; @@ -106,7 +109,7 @@ void GLWall::SplitLowerEdge(texcoord * tcs) float facc = (zceil[1] - zceil[0]) / polyw; float facf = (zfloor[1] - zfloor[0]) / polyw; - for (int i = sidedef->numsegs-2; i >= 0; i--) + for (int i = sidedef->numsegs - 2; i >= 0; i--) { seg_t *cseg = sidedef->segs[i]; float sidefrac = cseg->sidefrac; @@ -115,10 +118,13 @@ void GLWall::SplitLowerEdge(texcoord * tcs) float fracfac = sidefrac - glseg.fracleft; - glTexCoord2f(tcs[0].u + facu * fracfac, tcs[0].v + facv * fracfac); - glVertex3f(cseg->v2->fx, zbottom[0] + facb * fracfac, cseg->v2->fy); + ptr->x = cseg->v2->fx; + ptr->y = cseg->v2->fy; + ptr->z = zbottom[0] + facb * fracfac; + ptr->u = tcs[0].u + facu * fracfac; + ptr->v = tcs[0].v + facv * fracfac; + ptr++; } - vertexcount += sidedef->numsegs-1; } //========================================================================== @@ -127,29 +133,31 @@ void GLWall::SplitLowerEdge(texcoord * tcs) // //========================================================================== -void GLWall::SplitLeftEdge(texcoord * tcs) +void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) { - if (vertexes[0]==NULL) return; + if (vertexes[0] == NULL) return; - vertex_t * vi=vertexes[0]; + vertex_t * vi = vertexes[0]; if (vi->numheights) { - int i=0; + int i = 0; - float polyh1=ztop[0] - zbottom[0]; - float factv1=polyh1? (tcs[1].v - tcs[0].v) / polyh1:0; - float factu1=polyh1? (tcs[1].u - tcs[0].u) / polyh1:0; + float polyh1 = ztop[0] - zbottom[0]; + float factv1 = polyh1 ? (tcs[1].v - tcs[0].v) / polyh1 : 0; + float factu1 = polyh1 ? (tcs[1].u - tcs[0].u) / polyh1 : 0; - while (inumheights && vi->heightlist[i] <= zbottom[0] ) i++; + while (inumheights && vi->heightlist[i] <= zbottom[0]) i++; while (inumheights && vi->heightlist[i] < ztop[0]) { - glTexCoord2f(factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u, - factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v); - glVertex3f(glseg.x1, vi->heightlist[i], glseg.y1); + ptr->x = glseg.x1; + ptr->y = glseg.y1; + ptr->z = vi->heightlist[i]; + ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u; + ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v; + ptr++; i++; } - vertexcount+=i; } } @@ -159,29 +167,31 @@ void GLWall::SplitLeftEdge(texcoord * tcs) // //========================================================================== -void GLWall::SplitRightEdge(texcoord * tcs) +void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr) { - if (vertexes[1]==NULL) return; + if (vertexes[1] == NULL) return; - vertex_t * vi=vertexes[1]; + vertex_t * vi = vertexes[1]; if (vi->numheights) { - int i=vi->numheights-1; + int i = vi->numheights - 1; float polyh2 = ztop[1] - zbottom[1]; - float factv2 = polyh2? (tcs[2].v - tcs[3].v) / polyh2:0; - float factu2 = polyh2? (tcs[2].u - tcs[3].u) / polyh2:0; + float factv2 = polyh2 ? (tcs[2].v - tcs[3].v) / polyh2 : 0; + float factu2 = polyh2 ? (tcs[2].u - tcs[3].u) / polyh2 : 0; while (i>0 && vi->heightlist[i] >= ztop[1]) i--; while (i>0 && vi->heightlist[i] > zbottom[1]) { - glTexCoord2f(factu2 * (vi->heightlist[i] - ztop[1]) + tcs[2].u, - factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v); - glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2); + ptr->x = glseg.x2; + ptr->y = glseg.y2; + ptr->z = vi->heightlist[i]; + ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[2].u; + ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[2].v; + ptr++; i--; } - vertexcount+=i; } } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 2fecf1d60..7a6acbc89 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -20,6 +20,7 @@ struct GLDrawList; struct GLSkyInfo; struct FTexCoordInfo; struct FPortal; +struct FFlatVertex; enum WallTypes @@ -38,7 +39,6 @@ enum WallTypes RENDERWALL_MIRROR, RENDERWALL_MIRRORSURFACE, RENDERWALL_M2SNF, - RENDERWALL_M2SFOG, RENDERWALL_COLOR, RENDERWALL_FFBLOCK, RENDERWALL_COLORLAYER, @@ -96,13 +96,22 @@ public: //GLWF_CLAMPX=1, use GLT_* for these! //GLWF_CLAMPY=2, GLWF_SKYHACK=4, - GLWF_FOGGY=8, - GLWF_GLOW=16, // illuminated by glowing flats - GLWF_NOSHADER=32, // cannot be drawn with shaders. - GLWF_NOSPLITUPPER=64, - GLWF_NOSPLITLOWER=128, + GLWF_GLOW=8, // illuminated by glowing flats + GLWF_NOSPLITUPPER=16, + GLWF_NOSPLITLOWER=32, + GLWF_NOSPLIT=64, }; + enum + { + RWF_BLANK = 0, + RWF_TEXTURED = 1, // actually not being used anymore because with buffers it's even less efficient not writing the texture coordinates - but leave it here + RWF_GLOW = 2, + RWF_NOSPLIT = 4, + RWF_NORENDER = 8, + }; + + friend struct GLDrawList; friend class GLPortal; @@ -126,7 +135,7 @@ public: float topglowcolor[4]; float bottomglowcolor[4]; - int firstdynlight, lastdynlight; + int dynlightindex; int firstwall, numwalls; // splitting info. union @@ -158,7 +167,7 @@ private: void SetupLights(); bool PrepareLight(texcoord * tcs, ADynamicLight * light); - void RenderWall(int textured, float * color2, ADynamicLight * light=NULL); + void RenderWall(int textured, unsigned int *store = NULL); void FloodPlane(int pass); @@ -210,10 +219,10 @@ private: void RenderMirrorSurface(); void RenderTranslucentWall(); - void SplitLeftEdge(texcoord * tcs); - void SplitRightEdge(texcoord * tcs); - void SplitUpperEdge(texcoord * tcs); - void SplitLowerEdge(texcoord * tcs); + void SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr); + void SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr); + void SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr); + void SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr); public: @@ -270,16 +279,17 @@ public: int dynlightindex; - bool SetupSubsectorLights(bool lightsapplied, subsector_t * sub); + void SetupSubsectorLights(int pass, subsector_t * sub, int *dli = NULL); void DrawSubsector(subsector_t * sub); void DrawSubsectorLights(subsector_t * sub, int pass); - void DrawSubsectors(int pass, bool istrans); + void DrawSubsectors(int pass, bool processlights, bool istrans); + void ProcessLights(bool istrans); void PutFlat(bool fog = false); void Process(sector_t * model, int whichplane, bool notexture); void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside); void ProcessSector(sector_t * frontsector); - void Draw(int pass); + void Draw(int pass, bool trans); }; @@ -346,20 +356,7 @@ inline float Dist2(float x1,float y1,float x2,float y2) // Light + color -bool gl_GetSpriteLight(AActor *Self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, int desaturation, float * out, line_t *line = NULL, int side = 0); -int gl_SetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm, float alpha, PalEntry ThingColor = 0xffffff, bool weapon=false); - -void gl_GetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm, - float *red, float *green, float *blue, - PalEntry ThingColor, bool weapon); - -int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int rellight, FColormap *cm, - PalEntry ThingColor, float alpha, bool fullbright, bool weapon); - -int gl_SetSpriteLight(particle_t * thing, int lightlevel, int rellight, FColormap *cm, float alpha, PalEntry ThingColor = 0xffffff); -void gl_GetLightForThing(AActor * thing, float upper, float lower, float & r, float & g, float & b); - - - +void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t *subsec); +void gl_SetDynSpriteLight(AActor *actor, particle_t *particle); #endif diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 24c850112..94386c9a5 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -53,7 +53,6 @@ #include "gl/data/gl_data.h" #include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_glow.h" -#include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/textures/gl_material.h" @@ -71,7 +70,7 @@ void GLWall::CheckGlowing() { bottomglowcolor[3] = topglowcolor[3] = 0; - if (!gl_isFullbright(Colormap.LightColor, lightlevel) && gl_GlowActive()) + if (!gl_isFullbright(Colormap.LightColor, lightlevel)) { FTexture *tex = TexMan[topflat]; if (tex != NULL && tex->isGlowing()) @@ -115,9 +114,8 @@ void GLWall::PutWall(bool translucent) 4, //RENDERWALL_SECTORSTACK, // special 4, //RENDERWALL_PLANEMIRROR, // special 4, //RENDERWALL_MIRROR, // special - 1, //RENDERWALL_MIRRORSURFACE, // needs special handling - 2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog - 2, //RENDERWALL_M2SFOG, // depends on render and texture settings, no fog + 1, //RENDERWALL_MIRRORSURFACE, // only created here from RENDERWALL_MIRROR + 2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog, used on mid texture lines with a fog boundary. 3, //RENDERWALL_COLOR, // translucent 2, //RENDERWALL_FFBLOCK // depends on render and texture settings 4, //RENDERWALL_COLORLAYER // color layer needs special handling @@ -133,7 +131,7 @@ void GLWall::PutWall(bool translucent) // light planes don't get drawn with fullbright rendering if (!gltexture && passflag[type]!=4) return; - Colormap.GetFixedColormap(); + Colormap.Clear(); } CheckGlowing(); @@ -146,46 +144,18 @@ void GLWall::PutWall(bool translucent) } else if (passflag[type]!=4) // non-translucent walls { - static DrawListType list_indices[2][2][2]={ - { { GLDL_PLAIN, GLDL_FOG }, { GLDL_MASKED, GLDL_FOGMASKED } }, - { { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } } - }; bool masked; - bool light = gl_forcemultipass; - if (!gl_fixedcolormap) + masked = passflag[type]==1? false : (gltexture && gltexture->isMasked()); + + if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S)) { - if (gl_lights && !gl_dynlight_shader) - { - if (seg->sidedef == NULL) - { - light = false; - } - else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) - { - light = seg->sidedef->lighthead[0] != NULL; - } - else if (sub) - { - // for polyobjects we cannot use the side's light list. - // We must use the subsector's. - light = sub->lighthead[0] != NULL; - } - } + list = GLDL_MASKEDWALLSOFS; } - else + else { - flags&=~GLWF_FOGGY; - } - - masked = passflag[type]==1? false : (light && type!=RENDERWALL_FFBLOCK) || (gltexture && gltexture->isMasked()); - - list = list_indices[light][masked][!!(flags&GLWF_FOGGY)]; - if (list == GLDL_LIGHT) - { - if (gltexture->tex->gl_info.Brightmap && gl_BrightmapsActive()) list = GLDL_LIGHTBRIGHT; - if (flags & GLWF_GLOW) list = GLDL_LIGHTBRIGHT; + list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS; } gl_drawinfo->drawlists[list].AddWall(this); @@ -193,7 +163,7 @@ void GLWall::PutWall(bool translucent) else switch (type) { case RENDERWALL_COLORLAYER: - gl_drawinfo->drawlists[GLDL_TRANSLUCENT].AddWall(this); + gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].AddWall(this); break; // portals don't go into the draw list. @@ -520,7 +490,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) hi.colormap.LightColor = (light->extra_colormap)->Color; } - if (gl_fixedcolormap) hi.colormap.GetFixedColormap(); + if (gl_fixedcolormap) hi.colormap.Clear(); horizon = &hi; PutWall(0); } @@ -549,8 +519,8 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) hi.colormap.LightColor = (light->extra_colormap)->Color; } - if (gl_fixedcolormap) hi.colormap.GetFixedColormap(); - horizon=&hi; + if (gl_fixedcolormap) hi.colormap.Clear(); + horizon = &hi; PutWall(0); } } @@ -808,12 +778,12 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, if ( (seg->linedef->flags & ML_DONTPEGBOTTOM) >0) { texturebottom = MAX(realfront->GetPlaneTexZ(sector_t::floor),realback->GetPlaneTexZ(sector_t::floor))+rowoffset; - texturetop=texturebottom+(gltexture->TextureHeight(GLUSE_TEXTURE)<TextureHeight()<GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling))+rowoffset; - texturebottom=texturetop-(gltexture->TextureHeight(GLUSE_TEXTURE)<TextureHeight()<>FRACBITS)+seg->sidedef->TexelLength; - if ((textureoffset==0 && righttex<=gltexture->TextureWidth(GLUSE_TEXTURE)) || - (textureoffset>=0 && righttex==gltexture->TextureWidth(GLUSE_TEXTURE))) + if ((textureoffset==0 && righttex<=gltexture->TextureWidth()) || + (textureoffset>=0 && righttex==gltexture->TextureWidth())) { flags|=GLT_CLAMPX; } @@ -1009,6 +979,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, // FloatRect *splitrect; int v = gltexture->GetAreas(&splitrect); + if (seg->frontsector == seg->backsector) flags |= GLWF_NOSPLIT; // we don't need to do vertex splits if a line has both sides in the same sector if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX)) { // split the poly! @@ -1118,19 +1089,19 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover, if (rover->flags&FF_UPPERTEXTURE) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true); + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true); if (!gltexture) return; gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(side_t::top), seg->sidedef->GetTextureYScale(side_t::top)); } else if (rover->flags&FF_LOWERTEXTURE) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true); + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true); if (!gltexture) return; gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(side_t::bottom), seg->sidedef->GetTextureYScale(side_t::bottom)); } else { - gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), true); + gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), false, true); if (!gltexture) return; gltexture->GetTexCoordInfo(&tci, mastersd->GetTextureXScale(side_t::mid), mastersd->GetTextureYScale(side_t::mid)); } @@ -1432,7 +1403,7 @@ void GLWall::DoFFloorBlocks(seg_t * seg,sector_t * frontsector,sector_t * backse //========================================================================== void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) { - vertex_t * v1, * v2; + vertex_t * v1, *v2; fixed_t fch1; fixed_t ffh1; fixed_t fch2; @@ -1446,7 +1417,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) int a = 0; } #endif - + // note: we always have a valid sidedef and linedef reference when getting here. this->seg = seg; @@ -1461,24 +1432,24 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) { // Need these for aligning the textures realfront = §ors[frontsector->sectornum]; - realback = backsector? §ors[backsector->sectornum] : NULL; + realback = backsector ? §ors[backsector->sectornum] : NULL; } if (seg->sidedef == seg->linedef->sidedef[0]) { - v1=seg->linedef->v1; - v2=seg->linedef->v2; + v1 = seg->linedef->v1; + v2 = seg->linedef->v2; } else { - v1=seg->linedef->v2; - v2=seg->linedef->v1; + v1 = seg->linedef->v2; + v2 = seg->linedef->v1; } if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { - glseg.fracleft=0; - glseg.fracright=1; + glseg.fracleft = 0; + glseg.fracright = 1; if (gl_seamless) { if (v1->dirty) gl_RecalcVertexHeights(v1); @@ -1487,40 +1458,42 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) } else // polyobjects must be rendered per seg. { - if (abs(v1->x-v2->x) > abs(v1->y-v2->y)) + if (abs(v1->x - v2->x) > abs(v1->y - v2->y)) { - glseg.fracleft = float(seg->v1->x - v1->x)/float(v2->x-v1->x); - glseg.fracright = float(seg->v2->x - v1->x)/float(v2->x-v1->x); + glseg.fracleft = float(seg->v1->x - v1->x) / float(v2->x - v1->x); + glseg.fracright = float(seg->v2->x - v1->x) / float(v2->x - v1->x); } else { - glseg.fracleft = float(seg->v1->y - v1->y)/float(v2->y-v1->y); - glseg.fracright = float(seg->v2->y - v1->y)/float(v2->y-v1->y); + glseg.fracleft = float(seg->v1->y - v1->y) / float(v2->y - v1->y); + glseg.fracright = float(seg->v2->y - v1->y) / float(v2->y - v1->y); } - v1=seg->v1; - v2=seg->v2; + v1 = seg->v1; + v2 = seg->v2; } - vertexes[0]=v1; - vertexes[1]=v2; + vertexes[0] = v1; + vertexes[1] = v2; - glseg.x1= FIXED2FLOAT(v1->x); - glseg.y1= FIXED2FLOAT(v1->y); - glseg.x2= FIXED2FLOAT(v2->x); - glseg.y2= FIXED2FLOAT(v2->y); - Colormap=frontsector->ColorMap; - flags = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)? GLWF_FOGGY : 0; + glseg.x1 = FIXED2FLOAT(v1->x); + glseg.y1 = FIXED2FLOAT(v1->y); + glseg.x2 = FIXED2FLOAT(v2->x); + glseg.y2 = FIXED2FLOAT(v2->y); + Colormap = frontsector->ColorMap; + flags = 0; + dynlightindex = UINT_MAX; int rel = 0; int orglightlevel = gl_ClampLight(frontsector->lightlevel); - lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(!!(flags&GLWF_FOGGY), orglightlevel, false, &rel)); + bool foggy = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE); // fog disables fake contrast + lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, false, &rel)); if (orglightlevel >= 253) // with the software renderer fake contrast won't be visible above this. { - rellight = 0; + rellight = 0; } else if (lightlevel - rel > 256) // the brighter part of fake contrast will be clamped so also clamp the darker part by the same amount for better looks - { + { rellight = 256 - lightlevel + rel; } else @@ -1528,35 +1501,35 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) rellight = rel; } - alpha=1.0f; - RenderStyle=STYLE_Normal; - gltexture=NULL; + alpha = 1.0f; + RenderStyle = STYLE_Normal; + gltexture = NULL; - topflat=frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because - bottomflat=frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy. + topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because + bottomflat = frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy. topplane = frontsector->ceilingplane; bottomplane = frontsector->floorplane; // Save a little time (up to 0.3 ms per frame ;) ) if (frontsector->floorplane.a | frontsector->floorplane.b) { - ffh1=frontsector->floorplane.ZatPoint(v1); - ffh2=frontsector->floorplane.ZatPoint(v2); - zfloor[0]=FIXED2FLOAT(ffh1); - zfloor[1]=FIXED2FLOAT(ffh2); + ffh1 = frontsector->floorplane.ZatPoint(v1); + ffh2 = frontsector->floorplane.ZatPoint(v2); + zfloor[0] = FIXED2FLOAT(ffh1); + zfloor[1] = FIXED2FLOAT(ffh2); } else { - ffh1 = ffh2 = -frontsector->floorplane.d; + ffh1 = ffh2 = -frontsector->floorplane.d; zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh2); } if (frontsector->ceilingplane.a | frontsector->ceilingplane.b) { - fch1=frontsector->ceilingplane.ZatPoint(v1); - fch2=frontsector->ceilingplane.ZatPoint(v2); - zceil[0]= FIXED2FLOAT(fch1); - zceil[1]= FIXED2FLOAT(fch2); + fch1 = frontsector->ceilingplane.ZatPoint(v1); + fch2 = frontsector->ceilingplane.ZatPoint(v2); + zceil[0] = FIXED2FLOAT(fch1); + zceil[1] = FIXED2FLOAT(fch2); } else { @@ -1565,27 +1538,27 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) } - if (seg->linedef->special==Line_Horizon) + if (seg->linedef->special == Line_Horizon) { - SkyNormal(frontsector,v1,v2); - DoHorizon(seg,frontsector, v1,v2); + SkyNormal(frontsector, v1, v2); + DoHorizon(seg, frontsector, v1, v2); return; } //return; // [GZ] 3D middle textures are necessarily two-sided, even if they lack the explicit two-sided flag - if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED|ML_3DMIDTEX))) // one sided + if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED | ML_3DMIDTEX))) // one sided { // sector's sky - SkyNormal(frontsector,v1,v2); - + SkyNormal(frontsector, v1, v2); + // normal texture - gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true); - if (gltexture) + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true); + if (gltexture) { - DoTexture(RENDERWALL_M1S,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0, - realfront->GetPlaneTexZ(sector_t::ceiling),realfront->GetPlaneTexZ(sector_t::floor), // must come from the original! - fch1,fch2,ffh1,ffh2,0); + DoTexture(RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, + realfront->GetPlaneTexZ(sector_t::ceiling), realfront->GetPlaneTexZ(sector_t::floor), // must come from the original! + fch1, fch2, ffh1, ffh2, 0); } } else // two sided @@ -1598,8 +1571,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (backsector->floorplane.a | backsector->floorplane.b) { - bfh1=backsector->floorplane.ZatPoint(v1); - bfh2=backsector->floorplane.ZatPoint(v2); + bfh1 = backsector->floorplane.ZatPoint(v1); + bfh2 = backsector->floorplane.ZatPoint(v2); } else { @@ -1608,51 +1581,51 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (backsector->ceilingplane.a | backsector->ceilingplane.b) { - bch1=backsector->ceilingplane.ZatPoint(v1); - bch2=backsector->ceilingplane.ZatPoint(v2); + bch1 = backsector->ceilingplane.ZatPoint(v1); + bch2 = backsector->ceilingplane.ZatPoint(v2); } else { bch1 = bch2 = backsector->ceilingplane.d; } - SkyTop(seg,frontsector,backsector,v1,v2); - SkyBottom(seg,frontsector,backsector,v1,v2); - + SkyTop(seg, frontsector, backsector, v1, v2); + SkyBottom(seg, frontsector, backsector, v1, v2); + // upper texture - if (frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || backsector->GetTexture(sector_t::ceiling)!=skyflatnum) + if (frontsector->GetTexture(sector_t::ceiling) != skyflatnum || backsector->GetTexture(sector_t::ceiling) != skyflatnum) { - fixed_t bch1a=bch1, bch2a=bch2; - if (frontsector->GetTexture(sector_t::floor)!=skyflatnum || backsector->GetTexture(sector_t::floor)!=skyflatnum) + fixed_t bch1a = bch1, bch2a = bch2; + if (frontsector->GetTexture(sector_t::floor) != skyflatnum || backsector->GetTexture(sector_t::floor) != skyflatnum) { // the back sector's floor obstructs part of this wall - if (ffh1>bch1 && ffh2>bch2) + if (ffh1 > bch1 && ffh2 > bch2) { - bch2a=ffh2; - bch1a=ffh1; + bch2a = ffh2; + bch1a = ffh1; } } - if (bch1asidedef->GetTexture(side_t::top), true); - if (gltexture) + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true); + if (gltexture) { - DoTexture(RENDERWALL_TOP,seg,(seg->linedef->flags & (ML_DONTPEGTOP))==0, - realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling), - fch1,fch2,bch1a,bch2a,0); + DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, + realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling), + fch1, fch2, bch1a, bch2a, 0); } - else if ((frontsector->ceilingplane.a | frontsector->ceilingplane.b | - backsector->ceilingplane.a | backsector->ceilingplane.b) && - frontsector->GetTexture(sector_t::ceiling)!=skyflatnum && - backsector->GetTexture(sector_t::ceiling)!=skyflatnum) + else if ((frontsector->ceilingplane.a | frontsector->ceilingplane.b | + backsector->ceilingplane.a | backsector->ceilingplane.b) && + frontsector->GetTexture(sector_t::ceiling) != skyflatnum && + backsector->GetTexture(sector_t::ceiling) != skyflatnum) { - gltexture=FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), true); + gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), false, true); if (gltexture) { - DoTexture(RENDERWALL_TOP,seg,(seg->linedef->flags & (ML_DONTPEGTOP))==0, - realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling), - fch1,fch2,bch1a,bch2a,0); + DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, + realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling), + fch1, fch2, bch1a, bch2a, 0); } } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) @@ -1676,58 +1649,58 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) { tex = tex->GetRawTexture(); } - gltexture=FMaterial::ValidateTexture(tex); + gltexture = FMaterial::ValidateTexture(tex, false); } else gltexture = NULL; if (gltexture || drawfogboundary) { - DoMidTexture(seg, drawfogboundary, frontsector, backsector, realfront, realback, + DoMidTexture(seg, drawfogboundary, frontsector, backsector, realfront, realback, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); } - if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size()) + if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size()) { - DoFFloorBlocks(seg,frontsector,backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); + DoFFloorBlocks(seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); } - + /* bottom texture */ // the back sector's ceiling obstructs part of this wall (specially important for sky sectors) if (fch1ffh1 || bfh2>ffh2) { - gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true); - if (gltexture) + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true); + if (gltexture) { - DoTexture(RENDERWALL_BOTTOM,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0, - realback->GetPlaneTexZ(sector_t::floor),realfront->GetPlaneTexZ(sector_t::floor), - bfh1,bfh2,ffh1,ffh2, - frontsector->GetTexture(sector_t::ceiling)==skyflatnum && backsector->GetTexture(sector_t::ceiling)==skyflatnum ? - realfront->GetPlaneTexZ(sector_t::floor)-realback->GetPlaneTexZ(sector_t::ceiling) : - realfront->GetPlaneTexZ(sector_t::floor)-realfront->GetPlaneTexZ(sector_t::ceiling)); + DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, + realback->GetPlaneTexZ(sector_t::floor), realfront->GetPlaneTexZ(sector_t::floor), + bfh1, bfh2, ffh1, ffh2, + frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum ? + realfront->GetPlaneTexZ(sector_t::floor) - realback->GetPlaneTexZ(sector_t::ceiling) : + realfront->GetPlaneTexZ(sector_t::floor) - realfront->GetPlaneTexZ(sector_t::ceiling)); } - else if ((frontsector->floorplane.a | frontsector->floorplane.b | - backsector->floorplane.a | backsector->floorplane.b) && - frontsector->GetTexture(sector_t::floor)!=skyflatnum && - backsector->GetTexture(sector_t::floor)!=skyflatnum) + else if ((frontsector->floorplane.a | frontsector->floorplane.b | + backsector->floorplane.a | backsector->floorplane.b) && + frontsector->GetTexture(sector_t::floor) != skyflatnum && + backsector->GetTexture(sector_t::floor) != skyflatnum) { // render it anyway with the sector's floor texture. With a background sky // there are ugly holes otherwise and slopes are simply not precise enough // to mach in any case. - gltexture=FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true); + gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true); if (gltexture) { - DoTexture(RENDERWALL_BOTTOM,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0, - realback->GetPlaneTexZ(sector_t::floor),realfront->GetPlaneTexZ(sector_t::floor), - bfh1,bfh2,ffh1,ffh2, realfront->GetPlaneTexZ(sector_t::floor)-realfront->GetPlaneTexZ(sector_t::ceiling)); + DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, + realback->GetPlaneTexZ(sector_t::floor), realfront->GetPlaneTexZ(sector_t::floor), + bfh1, bfh2, ffh1, ffh2, realfront->GetPlaneTexZ(sector_t::floor) - realfront->GetPlaneTexZ(sector_t::ceiling)); } } - else if (backsector->GetTexture(sector_t::floor)!=skyflatnum && + else if (backsector->GetTexture(sector_t::floor) != skyflatnum && !(seg->sidedef->Flags & WALLF_POLYOBJ)) { // skip processing if the back is a malformed subsector @@ -1747,19 +1720,19 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) //========================================================================== void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * backsector) { - if (frontsector->GetTexture(sector_t::floor)==skyflatnum) return; + if (frontsector->GetTexture(sector_t::floor) == skyflatnum) return; - fixed_t ffh = frontsector->GetPlaneTexZ(sector_t::floor); - fixed_t bfh = backsector->GetPlaneTexZ(sector_t::floor); - if (bfh>ffh) + fixed_t ffh = frontsector->GetPlaneTexZ(sector_t::floor); + fixed_t bfh = backsector->GetPlaneTexZ(sector_t::floor); + if (bfh > ffh) { this->seg = seg; this->sub = NULL; - vertex_t * v1=seg->v1; - vertex_t * v2=seg->v2; - vertexes[0]=v1; - vertexes[1]=v2; + vertex_t * v1 = seg->v1; + vertex_t * v2 = seg->v2; + vertexes[0] = v1; + vertexes[1] = v2; glseg.x1 = FIXED2FLOAT(v1->x); glseg.y1 = FIXED2FLOAT(v1->y); @@ -1768,7 +1741,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * glseg.fracleft = 0; glseg.fracright = 1; - flags = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)? GLWF_FOGGY : 0; + flags = 0; // can't do fake contrast without a sidedef lightlevel = gl_ClampLight(frontsector->lightlevel); @@ -1782,15 +1755,16 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * bottomflat = frontsector->GetTexture(sector_t::floor); topplane = frontsector->ceilingplane; bottomplane = frontsector->floorplane; + dynlightindex = UINT_MAX; zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh); - gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true); + gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true); - if (gltexture) + if (gltexture) { FTexCoordInfo tci; - type=RENDERWALL_BOTTOM; + type = RENDERWALL_BOTTOM; gltexture->GetTexCoordInfo(&tci, FRACUNIT, FRACUNIT); SetWallCoordinates(seg, &tci, FIXED2FLOAT(bfh), bfh, bfh, ffh, ffh, 0); PutWall(false); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index d7edc6ef7..bad0aa5d1 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -48,9 +48,12 @@ #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" +#include "gl/renderer/gl_renderer.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_glow.h" +#include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" @@ -60,57 +63,6 @@ EXTERN_CVAR(Bool, gl_seamless) -//========================================================================== -// -// Sets up the texture coordinates for one light to be rendered -// -//========================================================================== -bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light) -{ - float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2}; - Plane p; - Vector nearPt, up, right; - float scale; - - p.Init(vtx,4); - - if (!p.ValidNormal()) - { - return false; - } - - if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, true, !!(flags&GLWF_FOGGY))) - { - return false; - } - - if (tcs != NULL) - { - Vector t1; - int outcnt[4]={0,0,0,0}; - - for(int i=0;i<4;i++) - { - t1.Set(&vtx[i*3]); - Vector nearToVert = t1 - nearPt; - tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f; - tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f; - - // quick check whether the light touches this polygon - if (tcs[i].u<0) outcnt[0]++; - if (tcs[i].u>1) outcnt[1]++; - if (tcs[i].v<0) outcnt[2]++; - if (tcs[i].v>1) outcnt[3]++; - - } - // The light doesn't touch this polygon - if (outcnt[0]==4 || outcnt[1]==4 || outcnt[2]==4 || outcnt[3]==4) return false; - } - - draw_dlight++; - return true; -} - //========================================================================== // // Collect lights for shader @@ -118,8 +70,19 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light) //========================================================================== FDynLightData lightdata; + void GLWall::SetupLights() { + // check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.) + switch (type) + { + case RENDERWALL_FOGBOUNDARY: + case RENDERWALL_MIRRORSURFACE: + case RENDERWALL_COLOR: + case RENDERWALL_COLORLAYER: + return; + } + float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2}; Plane p; @@ -130,89 +93,80 @@ void GLWall::SetupLights() { return; } - for(int i=0;i<2;i++) + FLightNode *node; + if (seg->sidedef == NULL) { - FLightNode *node; - if (seg->sidedef == NULL) - { - node = NULL; - } - else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) - { - node = seg->sidedef->lighthead[i]; - } - else if (sub) - { - // Polobject segs cannot be checked per sidedef so use the subsector instead. - node = sub->lighthead[i]; - } - else node = NULL; + node = NULL; + } + else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) + { + node = seg->sidedef->lighthead; + } + else if (sub) + { + // Polobject segs cannot be checked per sidedef so use the subsector instead. + node = sub->lighthead; + } + else node = NULL; - // Iterate through all dynamic lights which touch this wall and render them - while (node) + // Iterate through all dynamic lights which touch this wall and render them + while (node) + { + if (!(node->lightsource->flags2&MF2_DORMANT)) { - if (!(node->lightsource->flags2&MF2_DORMANT)) + iter_dlight++; + + Vector fn, pos; + + float x = FIXED2FLOAT(node->lightsource->x); + float y = FIXED2FLOAT(node->lightsource->y); + float z = FIXED2FLOAT(node->lightsource->z); + float dist = fabsf(p.DistToPoint(x, z, y)); + float radius = (node->lightsource->GetRadius() * gl_lights_size); + float scale = 1.0f / ((2.f * radius) - dist); + + if (radius > 0.f && dist < radius) { - iter_dlight++; + Vector nearPt, up, right; - Vector fn, pos; + pos.Set(x,z,y); + fn=p.Normal(); + fn.GetRightUp(right, up); - float x = FIXED2FLOAT(node->lightsource->x); - float y = FIXED2FLOAT(node->lightsource->y); - float z = FIXED2FLOAT(node->lightsource->z); - float dist = fabsf(p.DistToPoint(x, z, y)); - float radius = (node->lightsource->GetRadius() * gl_lights_size); - float scale = 1.0f / ((2.f * radius) - dist); + Vector tmpVec = fn * dist; + nearPt = pos + tmpVec; - if (radius > 0.f && dist < radius) + Vector t1; + int outcnt[4]={0,0,0,0}; + texcoord tcs[4]; + + // do a quick check whether the light touches this polygon + for(int i=0;i<4;i++) { - Vector nearPt, up, right; + t1.Set(&vtx[i*3]); + Vector nearToVert = t1 - nearPt; + tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f; + tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f; - pos.Set(x,z,y); - fn=p.Normal(); - fn.GetRightUp(right, up); + if (tcs[i].u<0) outcnt[0]++; + if (tcs[i].u>1) outcnt[1]++; + if (tcs[i].v<0) outcnt[2]++; + if (tcs[i].v>1) outcnt[3]++; - Vector tmpVec = fn * dist; - nearPt = pos + tmpVec; - - Vector t1; - int outcnt[4]={0,0,0,0}; - texcoord tcs[4]; - - // do a quick check whether the light touches this polygon - for(int i=0;i<4;i++) - { - t1.Set(&vtx[i*3]); - Vector nearToVert = t1 - nearPt; - tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f; - tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f; - - if (tcs[i].u<0) outcnt[0]++; - if (tcs[i].u>1) outcnt[1]++; - if (tcs[i].v<0) outcnt[2]++; - if (tcs[i].v>1) outcnt[3]++; - - } - if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) - { - gl_GetLight(p, node->lightsource, Colormap.colormap, true, false, lightdata); - } + } + if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) + { + gl_GetLight(p, node->lightsource, true, false, lightdata); } } - node = node->nextLight; } + node = node->nextLight; } - int numlights[3]; - lightdata.Combine(numlights, gl.MaxLights()); - if (numlights[2] > 0) - { - draw_dlight+=numlights[2]/2; - gl_RenderState.EnableLight(true); - gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]); - } + dynlightindex = GLRenderer->mLights->UploadLights(lightdata); } + //========================================================================== // // General purpose wall rendering function @@ -220,67 +174,54 @@ void GLWall::SetupLights() // //========================================================================== -void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) +void GLWall::RenderWall(int textured, unsigned int *store) { - texcoord tcs[4]; - bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); + static texcoord tcs[4]; // making this variable static saves us a relatively costly stack integrity check. + bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); - if (!light) + tcs[0]=lolft; + tcs[1]=uplft; + tcs[2]=uprgt; + tcs[3]=lorgt; + if ((flags&GLWF_GLOW) && (textured & RWF_GLOW)) { - tcs[0]=lolft; - tcs[1]=uplft; - tcs[2]=uprgt; - tcs[3]=lorgt; - if (!!(flags&GLWF_GLOW) && (textured & 2)) - { - gl_RenderState.SetGlowPlanes(topplane, bottomplane); - gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); - } - - } - else - { - if (!PrepareLight(tcs, light)) return; + gl_RenderState.SetGlowPlanes(topplane, bottomplane); + gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); } - - gl_RenderState.Apply(); + if (!(textured & RWF_NORENDER)) + { + gl_RenderState.Apply(); + gl_RenderState.ApplyLightIndex(dynlightindex); + } // the rest of the code is identical for textured rendering and lights + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + unsigned int count, offset; - glBegin(GL_TRIANGLE_FAN); - - // lower left corner - if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v); - glVertex3f(glseg.x1,zbottom[0],glseg.y1); - - if (split && glseg.fracleft==0) SplitLeftEdge(tcs); - - // upper left corner - if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v); - glVertex3f(glseg.x1,ztop[0],glseg.y1); - - if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs); - - // color for right side - if (color2) glColor4fv(color2); - - // upper right corner - if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v); - glVertex3f(glseg.x2,ztop[1],glseg.y2); - - if (split && glseg.fracright==1) SplitRightEdge(tcs); - - // lower right corner - if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v); - glVertex3f(glseg.x2,zbottom[1],glseg.y2); - - if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs); - - glEnd(); - - vertexcount+=4; - + ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v); + ptr++; + if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr); + ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v); + ptr++; + if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr); + ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v); + ptr++; + if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr); + ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v); + ptr++; + if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); + count = GLRenderer->mVBO->GetCount(ptr, &offset); + if (!(textured & RWF_NORENDER)) + { + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count); + vertexcount += count; + } + if (store != NULL) + { + store[0] = offset; + store[1] = count; + } } //========================================================================== @@ -293,52 +234,12 @@ void GLWall::RenderFogBoundary() { if (gl_fogmode && gl_fixedcolormap == 0) { - // with shaders this can be done properly - if (gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_fog_shader)) - { - int rel = rellight + getExtraLight(); - gl_SetFog(lightlevel, rel, &Colormap, false); - gl_RenderState.SetEffect(EFF_FOGBOUNDARY); - gl_RenderState.EnableAlphaTest(false); - RenderWall(0, NULL); - gl_RenderState.EnableAlphaTest(true); - gl_RenderState.SetEffect(EFF_NONE); - } - else - { - // otherwise some approximation is needed. This won't look as good - // as the shader version but it's an acceptable compromise. - float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor); - - float xcamera=FIXED2FLOAT(viewx); - float ycamera=FIXED2FLOAT(viewy); - - float dist1=Dist2(xcamera,ycamera, glseg.x1,glseg.y1); - float dist2=Dist2(xcamera,ycamera, glseg.x2,glseg.y2); - - - // these values were determined by trial and error and are scale dependent! - float fogd1=(0.95f-exp(-fogdensity*dist1/62500.f)) * 1.05f; - float fogd2=(0.95f-exp(-fogdensity*dist2/62500.f)) * 1.05f; - - gl_ModifyColor(Colormap.FadeColor.r, Colormap.FadeColor.g, Colormap.FadeColor.b, Colormap.colormap); - float fc[4]={Colormap.FadeColor.r/255.0f,Colormap.FadeColor.g/255.0f,Colormap.FadeColor.b/255.0f,fogd2}; - - gl_RenderState.EnableTexture(false); - gl_RenderState.EnableFog(false); - gl_RenderState.AlphaFunc(GL_GREATER,0); - glDepthFunc(GL_LEQUAL); - glColor4f(fc[0],fc[1],fc[2], fogd1); - if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); // Korshun. - - flags &= ~GLWF_GLOW; - RenderWall(4,fc); - - glDepthFunc(GL_LESS); - gl_RenderState.EnableFog(true); - gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f); - gl_RenderState.EnableTexture(true); - } + int rel = rellight + getExtraLight(); + gl_SetFog(lightlevel, rel, &Colormap, false); + gl_RenderState.SetEffect(EFF_FOGBOUNDARY); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + RenderWall(RWF_BLANK); + gl_RenderState.SetEffect(EFF_NONE); } } @@ -355,29 +256,35 @@ void GLWall::RenderMirrorSurface() // For the sphere map effect we need a normal of the mirror surface, Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1); v.Normalize(); - glNormal3fv(&v[0]); + + // we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is. + lolft.u = lorgt.u = uplft.u = uprgt.u = v.X(); + lolft.v = lorgt.v = uplft.v = uprgt.v = v.Z(); + + gl_RenderState.EnableTextureMatrix(true); + gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix); // Use sphere mapping for this gl_RenderState.SetEffect(EFF_SPHEREMAP); - gl_SetColor(lightlevel, 0, &Colormap ,0.1f); + gl_SetColor(lightlevel, 0, Colormap ,0.1f); + gl_SetFog(lightlevel, 0, &Colormap, true); gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); gl_RenderState.AlphaFunc(GL_GREATER,0); glDepthFunc(GL_LEQUAL); - gl_SetFog(lightlevel, getExtraLight(), &Colormap, true); - FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture); - pat->BindPatch(Colormap.colormap, 0); + FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture, false); + gl_RenderState.SetMaterial(pat, CLAMP_NONE, 0, -1, false); flags &= ~GLWF_GLOW; - //flags |= GLWF_NOSHADER; - RenderWall(0,NULL); + RenderWall(RWF_BLANK); + gl_RenderState.EnableTextureMatrix(false); gl_RenderState.SetEffect(EFF_NONE); // Restore the defaults for the translucent pass gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f*gl_mask_sprite_threshold); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); glDepthFunc(GL_LESS); // This is drawn in the translucent pass which is done after the decal pass @@ -411,16 +318,15 @@ void GLWall::RenderTranslucentWall() // and until that changes I won't fix this code for the new blending modes! bool isadditive = RenderStyle == STYLE_Add; - if (!transparent) gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold*fabs(alpha)); - else gl_RenderState.EnableAlphaTest(false); + if (!transparent) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); int extra; if (gltexture) { - if (flags&GLWF_FOGGY) gl_RenderState.EnableBrightmap(false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(Colormap.colormap, flags, 0); + gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false); extra = getExtraLight(); } else @@ -429,21 +335,19 @@ void GLWall::RenderTranslucentWall() extra = 0; } - gl_SetColor(lightlevel, extra, &Colormap, fabsf(alpha)); + gl_SetColor(lightlevel, extra, Colormap, fabsf(alpha)); if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive); else gl_SetFog(255, 0, NULL, false); - RenderWall(5,NULL); + RenderWall(RWF_TEXTURED|RWF_NOSPLIT); // restore default settings if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (transparent) gl_RenderState.EnableAlphaTest(true); if (!gltexture) { gl_RenderState.EnableTexture(true); } - gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableGlow(false); } @@ -454,7 +358,6 @@ void GLWall::RenderTranslucentWall() //========================================================================== void GLWall::Draw(int pass) { - FLightNode * node; int rel; #ifdef _DEBUG @@ -465,102 +368,31 @@ void GLWall::Draw(int pass) #endif - // This allows mid textures to be drawn on lines that might overlap a sky wall - if ((flags&GLWF_SKYHACK && type==RENDERWALL_M2S) || type == RENDERWALL_COLORLAYER) + if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY) { - if (pass != GLPASS_DECALS) - { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -128.0f); - } + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -128.0f); } switch (pass) { - case GLPASS_ALL: // Single-pass rendering + case GLPASS_LIGHTSONLY: + SetupLights(); + break; + + case GLPASS_ALL: SetupLights(); // fall through - case GLPASS_PLAIN: // Single-pass rendering + case GLPASS_PLAIN: rel = rellight + getExtraLight(); - gl_SetColor(lightlevel, rel, &Colormap,1.0f); + gl_SetColor(lightlevel, rel, Colormap,1.0f); if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false); else gl_SetFog(255, 0, NULL, false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(Colormap.colormap, flags, 0); - RenderWall(3, NULL); + gl_RenderState.SetMaterial(gltexture, flags & 3, false, -1, false); + RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); - gl_RenderState.EnableLight(false); - break; - - case GLPASS_BASE: // Base pass for non-masked polygons (all opaque geometry) - case GLPASS_BASE_MASKED: // Base pass for masked polygons (2sided mid-textures and transparent 3D floors) - rel = rellight + getExtraLight(); - gl_SetColor(lightlevel, rel, &Colormap,1.0f); - if (!(flags&GLWF_FOGGY)) - { - if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false); - else gl_SetFog(255, 0, NULL, false); - } - gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - // fall through - - if (pass != GLPASS_BASE) - { - gltexture->Bind(Colormap.colormap, flags, 0); - } - RenderWall(pass == GLPASS_BASE? 2:3, NULL); - gl_RenderState.EnableGlow(false); - gl_RenderState.EnableLight(false); - break; - - case GLPASS_TEXTURE: // modulated texture - gltexture->Bind(Colormap.colormap, flags, 0); - RenderWall(1, NULL); - break; - - case GLPASS_LIGHT: - case GLPASS_LIGHT_ADDITIVE: - // black fog is diminishing light and should affect lights less than the rest! - if (!(flags&GLWF_FOGGY)) gl_SetFog((255+lightlevel)>>1, 0, NULL, false); - else gl_SetFog(lightlevel, 0, &Colormap, true); - - if (seg->sidedef == NULL) - { - node = NULL; - } - else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) - { - // Iterate through all dynamic lights which touch this wall and render them - node = seg->sidedef->lighthead[pass==GLPASS_LIGHT_ADDITIVE]; - } - else if (sub) - { - // To avoid constant rechecking for polyobjects use the subsector's lightlist instead - node = sub->lighthead[pass==GLPASS_LIGHT_ADDITIVE]; - } - else node = NULL; - while (node) - { - if (!(node->lightsource->flags2&MF2_DORMANT)) - { - iter_dlight++; - RenderWall(1, NULL, node->lightsource); - } - node = node->nextLight; - } - break; - - case GLPASS_DECALS: - case GLPASS_DECALS_NOFOG: - if (seg->sidedef && seg->sidedef->AttachedDecals) - { - if (pass==GLPASS_DECALS) - { - gl_SetFog(lightlevel, rellight + getExtraLight(), &Colormap, false); - } - DoDrawDecals(); - } break; case GLPASS_TRANSLUCENT: @@ -580,12 +412,9 @@ void GLWall::Draw(int pass) } } - if ((flags&GLWF_SKYHACK && type==RENDERWALL_M2S) || type == RENDERWALL_COLORLAYER) + if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY) { - if (pass!=GLPASS_DECALS) - { - glDisable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(0, 0); - } + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); } } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index aa991c0a0..d64c0a39a 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -51,6 +51,7 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/models/gl_models.h" @@ -69,7 +70,7 @@ EXTERN_CVAR(Int, gl_fuzztype) // //========================================================================== -void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep, int OverrideShader) +void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, bool hudModelStep, int OverrideShader, bool alphatexture) { float fU1,fV1; float fU2,fV2; @@ -83,7 +84,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed // [BB] In the HUD model step we just render the model and break out. if ( hudModelStep ) { - gl_RenderHUDModel( psp, sx, sy, cm_index ); + gl_RenderHUDModel( psp, sx, sy); return; } @@ -92,10 +93,10 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, &mirror); if (!lump.isValid()) return; - FMaterial * tex = FMaterial::ValidateTexture(lump, false); + FMaterial * tex = FMaterial::ValidateTexture(lump, true, false); if (!tex) return; - tex->BindPatch(cm_index, 0, OverrideShader); + gl_RenderState.SetMaterial(tex, CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture); int vw = viewwidth; int vh = viewheight; @@ -103,18 +104,18 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed // calculate edges of the shape scalex = xratio[WidescreenRatio] * vw / 320; - tx = sx - ((160 + tex->GetScaledLeftOffset(GLUSE_PATCH))<GetScaledLeftOffset())<>FRACBITS) + (vw>>1); if (x1 > vw) return; // off the right side x1+=viewwindowx; - tx += tex->TextureWidth(GLUSE_PATCH) << FRACBITS; + tx += tex->TextureWidth() << FRACBITS; x2 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1); if (x2 < 0) return; // off the left side x2+=viewwindowx; // killough 12/98: fix psprite positioning problem - texturemid = (100<GetScaledTopOffset(GLUSE_PATCH)<GetScaledTopOffset()<ReadyWeapon; if (wi && wi->YAdjust) @@ -131,7 +132,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed scale = ((SCREENHEIGHT*vw)/SCREENWIDTH) / 200.0f; y1 = viewwindowy + (vh >> 1) - (int)(((float)texturemid / (float)FRACUNIT) * scale); - y2 = y1 + (int)((float)tex->TextureHeight(GLUSE_PATCH) * scale) + 1; + y2 = y1 + (int)((float)tex->TextureHeight() * scale) + 1; if (!mirror) { @@ -148,21 +149,22 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed fV2=tex->GetVB(); } - if (tex->GetTransparent() || OverrideShader != 0) + if (tex->GetTransparent() || OverrideShader != -1) { - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); } gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(fU1, fV1); glVertex2f(x1,y1); - glTexCoord2f(fU1, fV2); glVertex2f(x1,y2); - glTexCoord2f(fU2, fV1); glVertex2f(x2,y1); - glTexCoord2f(fU2, fV2); glVertex2f(x2,y2); - glEnd(); - if (tex->GetTransparent() || OverrideShader != 0) - { - gl_RenderState.EnableAlphaTest(true); - } + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x1, y1, 0, fU1, fV1); + ptr++; + ptr->Set(x1, y2, 0, fU1, fV2); + ptr++; + ptr->Set(x2, y1, 0, fU2, fV1); + ptr++; + ptr->Set(x2, y2, 0, fU2, fV2); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); } //========================================================================== @@ -192,36 +194,32 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) (players[consoleplayer].cheats & CF_CHASECAM)) return; - /* - if(!player || playermo->renderflags&RF_INVISIBLE || !r_drawplayersprites || - mViewActor!=playermo || playermo->RenderStyle.BlendOp == STYLEOP_None) return; - */ - P_BobWeapon (player, &player->psprites[ps_weapon], &ofsx, &ofsy); // check for fullbright if (player->fixedcolormap==NOFIXEDCOLORMAP) { - for (i=0, psp=player->psprites; i<=ps_flash; i++,psp++) + for (i = 0, psp = player->psprites; i <= ps_flash; i++, psp++) + { if (psp->state != NULL) { bool disablefullbright = false; FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL); - if (lump.isValid() && gl_BrightmapsActive()) + if (lump.isValid()) { - FMaterial * tex=FMaterial::ValidateTexture(lump, false); + FMaterial * tex=FMaterial::ValidateTexture(lump, false, false); if (tex) disablefullbright = tex->tex->gl_info.bBrightmapDisablesFullbright; } statebright[i] = !!psp->state->GetFullbright() && !disablefullbright; } - + } } if (gl_fixedcolormap) { lightlevel=255; - cm.GetFixedColormap(); + cm.Clear(); statebright[0] = statebright[1] = true; fakesec = viewsector; } @@ -286,7 +284,9 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) statebright[0] = statebright[1] = true; } - PalEntry ThingColor = playermo->fillcolor; + PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; + ThingColor.a = 255; + visstyle_t vis; vis.RenderStyle=playermo->RenderStyle; @@ -297,23 +297,23 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) playermo->Inventory->AlterWeaponSprite(&vis); if (vis.colormap >= SpecialColormaps[0].Colormap && vis.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap && - cm.colormap == CM_DEFAULT) + gl_fixedcolormap == CM_DEFAULT) { - ptrdiff_t specialmap = (vis.colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap); - cm.colormap = int(CM_FIRSTSPECIALCOLORMAP + specialmap); + // this only happens for Strife's inverted weapon sprite + vis.RenderStyle.Flags |= STYLEF_InvertSource; } } // Set the render parameters - int OverrideShader = 0; + int OverrideShader = -1; float trans = 0.f; if (vis.RenderStyle.BlendOp >= STYLEOP_Fuzz && vis.RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) { vis.RenderStyle.CheckFuzz(); if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl.shadermodel >= 4 && gl_fuzztype != 0) + if (gl_fuzztype != 0) { // Todo: implement shader selection here vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; @@ -345,6 +345,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // now draw the different layers of the weapon gl_RenderState.EnableBrightmap(true); + gl_RenderState.SetObjectColor(ThingColor); if (statebright[0] || statebright[1]) { // brighten the weapon to reduce the difference between @@ -365,7 +366,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) if (statebright[i]) { if (fakesec == viewsector || in_area != area_below) - // under water areas keep most of their color for fullbright objects { cmc.LightColor.r= cmc.LightColor.g= @@ -373,17 +373,27 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) } else { - cmc.LightColor.r = (3*cmc.LightColor.r + 0xff)/4; + // under water areas keep most of their color for fullbright objects + cmc.LightColor.r = (3 * cmc.LightColor.r + 0xff) / 4; cmc.LightColor.g = (3*cmc.LightColor.g + 0xff)/4; cmc.LightColor.b = (3*cmc.LightColor.b + 0xff)/4; } } - // set the lighting parameters (only calls glColor and glAlphaFunc) - gl_SetSpriteLighting(vis.RenderStyle, playermo, statebright[i]? 255 : lightlevel, - 0, &cmc, 0xffffff, trans, statebright[i], true); - DrawPSprite (player,psp,psp->sx+ofsx, psp->sy+ofsy, cm.colormap, hudModelStep, OverrideShader); + // set the lighting parameters + if (vis.RenderStyle.BlendOp == STYLEOP_Shadow) + { + gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, cmc.desaturation); + } + else + { + gl_SetDynSpriteLight(playermo, NULL); + gl_SetColor(statebright[i] ? 255 : lightlevel, 0, cmc, trans, true); + } + DrawPSprite(player, psp, psp->sx + ofsx, psp->sy + ofsy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha)); } } + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.SetDynLight(0, 0, 0); gl_RenderState.EnableBrightmap(false); glset.lightmode = oldlightmode; } @@ -408,10 +418,10 @@ void FGLRenderer::DrawTargeterSprites() gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); gl_RenderState.BlendEquation(GL_FUNC_ADD); - glColor3f(1.0f,1.0f,1.0f); + gl_RenderState.ResetColor(); gl_RenderState.SetTextureMode(TM_MODULATE); // The Targeter's sprites are always drawn normally. for (i=ps_targetcenter, psp = &player->psprites[ps_targetcenter]; istate) DrawPSprite (player,psp,psp->sx, psp->sy, CM_DEFAULT, false, 0); + if (psp->state) DrawPSprite (player,psp,psp->sx, psp->sy, false, 0, false); } \ No newline at end of file diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index ef0f84f0d..3d4afdbcc 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -51,22 +51,13 @@ #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_matrix.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_shader.h" #include "gl/textures/gl_material.h" - -// these will only have an effect on SM3 cards. -// For SM4 they are always on and for SM2 always off -CVAR(Bool, gl_warp_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) -CVAR(Bool, gl_fog_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) -CVAR(Bool, gl_colormap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) -CVAR(Bool, gl_brightmap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) -CVAR(Bool, gl_glow_shader, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) - - -extern long gl_frameMS; +#include "gl/dynlights/gl_lightbuffer.h" //========================================================================== // @@ -79,123 +70,174 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * static char buffer[10000]; FString error; - if (gl.shadermodel > 0) + int i_lump = Wads.CheckNumForFullName("shaders/glsl/shaderdefs.i"); + if (i_lump == -1) I_Error("Unable to load 'shaders/glsl/shaderdefs.i'"); + FMemLump i_data = Wads.ReadLump(i_lump); + + int vp_lump = Wads.CheckNumForFullName(vert_prog_lump); + if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump); + FMemLump vp_data = Wads.ReadLump(vp_lump); + + int fp_lump = Wads.CheckNumForFullName(frag_prog_lump); + if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump); + FMemLump fp_data = Wads.ReadLump(fp_lump); + + + +// +// The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break! +// + unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType(); + unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize(); + + FString vp_comb; + + if (lightbuffertype == GL_UNIFORM_BUFFER) { - int vp_lump = Wads.CheckNumForFullName(vert_prog_lump); - if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump); - FMemLump vp_data = Wads.ReadLump(vp_lump); - - int fp_lump = Wads.CheckNumForFullName(frag_prog_lump); - if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump); - FMemLump fp_data = Wads.ReadLump(fp_lump); - - - FString vp_comb; - FString fp_comb; - vp_comb = defines; - if (gl.shadermodel < 4) - { - vp_comb << "#define NO_SM4\n"; - } - - fp_comb = vp_comb; - // This uses GetChars on the strings to get rid of terminating 0 characters. - vp_comb << vp_data.GetString().GetChars() << "\n"; - fp_comb << fp_data.GetString().GetChars() << "\n"; - - if (proc_prog_lump != NULL) - { - if (*proc_prog_lump != '#') - { - int pp_lump = Wads.CheckNumForFullName(proc_prog_lump); - if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump); - FMemLump pp_data = Wads.ReadLump(pp_lump); - - fp_comb << pp_data.GetString().GetChars(); - } - else - { - // Proc_prog_lump is not a lump name but the source itself (from generated shaders) - fp_comb << proc_prog_lump+1; - } - } - - hVertProg = glCreateShader(GL_VERTEX_SHADER); - hFragProg = glCreateShader(GL_FRAGMENT_SHADER); - - - int vp_size = (int)vp_comb.Len(); - int fp_size = (int)fp_comb.Len(); - - const char *vp_ptr = vp_comb.GetChars(); - const char *fp_ptr = fp_comb.GetChars(); - - glShaderSource(hVertProg, 1, &vp_ptr, &vp_size); - glShaderSource(hFragProg, 1, &fp_ptr, &fp_size); - - glCompileShader(hVertProg); - glCompileShader(hFragProg); - - hShader = glCreateProgram(); - - glAttachShader(hShader, hVertProg); - glAttachShader(hShader, hFragProg); - - glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams"); - glBindAttribLocation(hShader, VATTR_LIGHTLEVEL, "lightlevel_in"); // Korshun. - - glLinkProgram(hShader); - - glGetShaderInfoLog(hVertProg, 10000, NULL, buffer); - if (*buffer) - { - error << "Vertex shader:\n" << buffer << "\n"; - } - glGetShaderInfoLog(hFragProg, 10000, NULL, buffer); - if (*buffer) - { - error << "Fragment shader:\n" << buffer << "\n"; - } - - glGetProgramInfoLog(hShader, 10000, NULL, buffer); - if (*buffer) - { - error << "Linking:\n" << buffer << "\n"; - } - int linked; - glGetProgramiv(hShader, GL_LINK_STATUS, &linked); - if (linked == 0) - { - // only print message if there's an error. - Printf("Init Shader '%s':\n%s\n", name, error.GetChars()); - } - timer_index = glGetUniformLocation(hShader, "timer"); - desaturation_index = glGetUniformLocation(hShader, "desaturation_factor"); - fogenabled_index = glGetUniformLocation(hShader, "fogenabled"); - texturemode_index = glGetUniformLocation(hShader, "texturemode"); - camerapos_index = glGetUniformLocation(hShader, "camerapos"); - lightparms_index = glGetUniformLocation(hShader, "lightparms"); - colormapstart_index = glGetUniformLocation(hShader, "colormapstart"); - colormaprange_index = glGetUniformLocation(hShader, "colormaprange"); - lightrange_index = glGetUniformLocation(hShader, "lightrange"); - fogcolor_index = glGetUniformLocation(hShader, "fogcolor"); - lights_index = glGetUniformLocation(hShader, "lights"); - dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor"); - - glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor"); - glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor"); - glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane"); - glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane"); - - glUseProgram(hShader); - - int texture_index = glGetUniformLocation(hShader, "texture2"); - if (texture_index > 0) glUniform1i(texture_index, 1); - - glUseProgram(0); - return !!linked; + vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } - return false; + else + { + vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; + } + + vp_comb << defines << i_data.GetString().GetChars(); + FString fp_comb = vp_comb; + + vp_comb << vp_data.GetString().GetChars() << "\n"; + fp_comb << fp_data.GetString().GetChars() << "\n"; + + if (proc_prog_lump != NULL) + { + if (*proc_prog_lump != '#') + { + int pp_lump = Wads.CheckNumForFullName(proc_prog_lump); + if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump); + FMemLump pp_data = Wads.ReadLump(pp_lump); + + if (pp_data.GetString().IndexOf("ProcessTexel") < 0) + { + // this looks like an old custom hardware shader. + // We need to replace the ProcessTexel call to make it work. + + fp_comb.Substitute("vec4 frag = ProcessTexel();", "vec4 frag = Process(vec4(1.0));"); + } + fp_comb << pp_data.GetString().GetChars(); + fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders. + + if (pp_data.GetString().IndexOf("ProcessLight") < 0) + { + int pl_lump = Wads.CheckNumForFullName("shaders/glsl/func_defaultlight.fp"); + if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp"); + FMemLump pl_data = Wads.ReadLump(pl_lump); + fp_comb << "\n" << pl_data.GetString().GetChars(); + } + } + else + { + // Proc_prog_lump is not a lump name but the source itself (from generated shaders) + fp_comb << proc_prog_lump + 1; + } + } + + hVertProg = glCreateShader(GL_VERTEX_SHADER); + hFragProg = glCreateShader(GL_FRAGMENT_SHADER); + + + int vp_size = (int)vp_comb.Len(); + int fp_size = (int)fp_comb.Len(); + + const char *vp_ptr = vp_comb.GetChars(); + const char *fp_ptr = fp_comb.GetChars(); + + glShaderSource(hVertProg, 1, &vp_ptr, &vp_size); + glShaderSource(hFragProg, 1, &fp_ptr, &fp_size); + + glCompileShader(hVertProg); + glCompileShader(hFragProg); + + hShader = glCreateProgram(); + + glAttachShader(hShader, hVertProg); + glAttachShader(hShader, hFragProg); + + glBindAttribLocation(hShader, VATTR_VERTEX, "aPosition"); + glBindAttribLocation(hShader, VATTR_TEXCOORD, "aTexCoord"); + glBindAttribLocation(hShader, VATTR_COLOR, "aColor"); + glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); + + glLinkProgram(hShader); + + glGetShaderInfoLog(hVertProg, 10000, NULL, buffer); + if (*buffer) + { + error << "Vertex shader:\n" << buffer << "\n"; + } + glGetShaderInfoLog(hFragProg, 10000, NULL, buffer); + if (*buffer) + { + error << "Fragment shader:\n" << buffer << "\n"; + } + + glGetProgramInfoLog(hShader, 10000, NULL, buffer); + if (*buffer) + { + error << "Linking:\n" << buffer << "\n"; + } + int linked; + glGetProgramiv(hShader, GL_LINK_STATUS, &linked); + if (linked == 0) + { + // only print message if there's an error. + I_Error("Init Shader '%s':\n%s\n", name, error.GetChars()); + } + + + muDesaturation.Init(hShader, "uDesaturationFactor"); + muFogEnabled.Init(hShader, "uFogEnabled"); + muTextureMode.Init(hShader, "uTextureMode"); + muCameraPos.Init(hShader, "uCameraPos"); + muLightParms.Init(hShader, "uLightAttr"); + muColormapStart.Init(hShader, "uFixedColormapStart"); + muColormapRange.Init(hShader, "uFixedColormapRange"); + muLightIndex.Init(hShader, "uLightIndex"); + muFogColor.Init(hShader, "uFogColor"); + muDynLightColor.Init(hShader, "uDynLightColor"); + muObjectColor.Init(hShader, "uObjectColor"); + muGlowBottomColor.Init(hShader, "uGlowBottomColor"); + muGlowTopColor.Init(hShader, "uGlowTopColor"); + muGlowBottomPlane.Init(hShader, "uGlowBottomPlane"); + muGlowTopPlane.Init(hShader, "uGlowTopPlane"); + muFixedColormap.Init(hShader, "uFixedColormap"); + muInterpolationFactor.Init(hShader, "uInterpolationFactor"); + muClipHeightTop.Init(hShader, "uClipHeightTop"); + muClipHeightBottom.Init(hShader, "uClipHeightBottom"); + muAlphaThreshold.Init(hShader, "uAlphaThreshold"); + muTimer.Init(hShader, "timer"); + + lights_index = glGetUniformLocation(hShader, "lights"); + fakevb_index = glGetUniformLocation(hShader, "fakeVB"); + projectionmatrix_index = glGetUniformLocation(hShader, "ProjectionMatrix"); + viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix"); + modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix"); + texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix"); + + int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO"); + if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT); + + glUseProgram(hShader); + + // set up other texture units (if needed by the shader) + for (int i = 2; i<16; i++) + { + char stringbuf[20]; + mysnprintf(stringbuf, 20, "texture%d", i); + tempindex = glGetUniformLocation(hShader, stringbuf); + if (tempindex > 0) glUniform1i(tempindex, i - 1); + } + + glUseProgram(0); + return !!linked; } //========================================================================== @@ -218,160 +260,41 @@ FShader::~FShader() // //========================================================================== -bool FShader::Bind(float Speed) +bool FShader::Bind() { GLRenderer->mShaderManager->SetActiveShader(this); - if (timer_index >=0 && Speed > 0.f) glUniform1f(timer_index, gl_frameMS*Speed/1000.f); return true; } //========================================================================== // -// +// Since all shaders are REQUIRED, any error here needs to be fatal // //========================================================================== -FShaderContainer::FShaderContainer(const char *ShaderName, const char *ShaderPath) +FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard) { - const char * shaderdefines[] = { - "#define NO_GLOW\n#define NO_DESATURATE\n", - "#define NO_DESATURATE\n", - "#define NO_GLOW\n", - "\n", - "#define NO_GLOW\n#define NO_DESATURATE\n#define DYNLIGHT\n", - "#define NO_DESATURATE\n#define DYNLIGHT\n", - "#define NO_GLOW\n#define DYNLIGHT\n", - "\n#define DYNLIGHT\n", - "#define NO_GLOW\n#define NO_DESATURATE\n#define SOFTLIGHT\n", - "#define NO_DESATURATE\n#define SOFTLIGHT\n", - "#define NO_GLOW\n#define SOFTLIGHT\n", - "\n#define SOFTLIGHT\n", - "#define NO_GLOW\n#define NO_DESATURATE\n#define DYNLIGHT\n#define SOFTLIGHT\n", - "#define NO_DESATURATE\n#define DYNLIGHT\n#define SOFTLIGHT\n", - "#define NO_GLOW\n#define DYNLIGHT\n#define SOFTLIGHT\n", - "\n#define DYNLIGHT\n#define SOFTLIGHT\n" - }; - - const char * shaderdesc[] = { - "::default", - "::glow", - "::desaturate", - "::glow+desaturate", - "::default+dynlight", - "::glow+dynlight", - "::desaturate+dynlight", - "::glow+desaturate+dynlight", - "::softlight", - "::glow+softlight", - "::desaturate+softlight", - "::glow+desaturate+softlight", - "::default+dynlight+softlight", - "::glow+dynlight+softlight", - "::desaturate+dynlight+softlight", - "::glow+desaturate+dynlight+softlight", - }; - - FString name; - - name << ShaderName << "::colormap"; + FString defines; + // this can't be in the shader code due to ATI strangeness. + if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n"; + if (!usediscard) defines += "#define NO_ALPHATEST\n"; + FShader *shader = NULL; try { - shader_cm = new FShader; - if (!shader_cm->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_colormap.fp", ShaderPath, "#define NO_FOG\n#define NO_GLOW\n")) + shader = new FShader(ShaderName); + if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, defines.GetChars())) { - delete shader_cm; - shader_cm = NULL; + I_FatalError("Unable to load shader %s\n", ShaderName); } } catch(CRecoverableError &err) { - shader_cm = NULL; - I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage()); - } - - name << ShaderName << "::foglayer"; - - try - { - shader_fl = new FShader; - if (!shader_fl->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_foglayer.fp", ShaderPath, "#define NO_GLOW\n")) - { - delete shader_fl; - shader_fl = NULL; - } - } - catch (CRecoverableError &err) - { - shader_fl = NULL; - I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage()); - } - - if (gl.shadermodel > 2) - { - for(int i = 0;i < NUM_SHADERS; i++) - { - FString name; - - name << ShaderName << shaderdesc[i]; - - try - { - FString str; - if ((i&4) != 0) - { - if (gl.maxuniforms < 1024 || gl.shadermodel != 4) - { - shader[i] = NULL; - continue; - } - // this can't be in the shader code due to ATI strangeness. - str = "#version 120\n#extension GL_EXT_gpu_shader4 : enable\n"; - if (gl.MaxLights() == 128) str += "#define MAXLIGHTS128\n"; - } - if ((i&8) == 0) - { - if (gl.shadermodel != 4) - { - shader[i] = NULL; - continue; - } - } - str += shaderdefines[i]; - shader[i] = new FShader; - if (!shader[i]->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str.GetChars())) - { - delete shader[i]; - shader[i] = NULL; - } - } - catch(CRecoverableError &err) - { - shader[i] = NULL; - I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage()); - } - } - } - else memset(shader, 0, sizeof(shader)); -} - -//========================================================================== -// -// -// -//========================================================================== -FShaderContainer::~FShaderContainer() -{ - if (shader_cm != NULL) delete shader_cm; - if (shader_fl != NULL) delete shader_fl; - for (int i = 0; i < NUM_SHADERS; i++) - { - if (shader[i] != NULL) - { - delete shader[i]; - shader[i] = NULL; - } + if (shader != NULL) delete shader; + shader = NULL; + I_FatalError("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage()); } + return shader; } //========================================================================== @@ -380,49 +303,11 @@ FShaderContainer::~FShaderContainer() // //========================================================================== -FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights) +void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - FShader *sh=NULL; - - if (cm == CM_FOGLAYER) - { - if (shader_fl) - { - shader_fl->Bind(Speed); - } - return shader_fl; - } - else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_MAXCOLORMAP) - { - // these are never used with any kind of lighting or fog - sh = shader_cm; - // [BB] If there was a problem when loading the shader, sh is NULL here. - if( sh ) - { - FSpecialColormap *map = &SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP]; - sh->Bind(Speed); - float m[3]= {map->ColorizeEnd[0] - map->ColorizeStart[0], - map->ColorizeEnd[1] - map->ColorizeStart[1], map->ColorizeEnd[2] - map->ColorizeStart[2]}; - - glUniform3fv(sh->colormapstart_index, 1, map->ColorizeStart); - glUniform3fv(sh->colormaprange_index, 1, m); - } - } - else - { - bool desat = cm>=CM_DESAT1 && cm<=CM_DESAT31; - sh = shader[glowing + 2*desat + 4*lights + (glset.lightmode & 8)]; - // [BB] If there was a problem when loading the shader, sh is NULL here. - if( sh ) - { - sh->Bind(Speed); - if (desat) - { - glUniform1f(sh->desaturation_index, 1.f-float(cm-CM_DESAT0)/(CM_DESAT31-CM_DESAT0)); - } - } - } - return sh; + Bind(); + glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get()); + glUniformMatrix4fv(viewmatrix_index, 1, false, view->get()); } @@ -469,8 +354,10 @@ struct FEffectShader static const FEffectShader effectshaders[]= { - {"fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_GLOW\n"}, - {"spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define NO_GLOW\n#define NO_DESATURATE\n#define SPHEREMAP\n#define SPHEREMAP_0\n"} + { "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_ALPHATEST\n" }, + { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" }, + { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" }, + { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" }, }; @@ -502,55 +389,46 @@ FShaderManager::~FShaderManager() // //========================================================================== -void FShaderManager::Recompile() -{ - Clean(); - CompileShaders(); -} - -//========================================================================== -// -// -// -//========================================================================== - void FShaderManager::CompileShaders() { - mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; - if (gl.shadermodel > 0) + mActiveShader = NULL; + + mTextureEffects.Clear(); + mTextureEffectsNAT.Clear(); + for (int i = 0; i < MAX_EFFECTS; i++) { - for(int i=0;defaultshaders[i].ShaderName != NULL;i++) - { - FShaderContainer * shc = new FShaderContainer(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); - mTextureEffects.Push(shc); - if (gl.shadermodel <= 2) return; // SM2 will only initialize the default shader - } + mEffectShaders[i] = NULL; + } - for(unsigned i = 0; i < usershaders.Size(); i++) + for(int i=0;defaultshaders[i].ShaderName != NULL;i++) + { + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true); + mTextureEffects.Push(shc); + if (i <= 3) { - FString name = ExtractFileBase(usershaders[i]); - FName sfn = name; - - if (gl.shadermodel > 2) - { - FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]); - mTextureEffects.Push(shc); - } + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false); + mTextureEffectsNAT.Push(shc); } + } - if (gl.shadermodel > 2) + for(unsigned i = 0; i < usershaders.Size(); i++) + { + FString name = ExtractFileBase(usershaders[i]); + FName sfn = name; + + FShader *shc = Compile(sfn, usershaders[i], true); + mTextureEffects.Push(shc); + } + + for(int i=0;iLoad(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, + effectshaders[i].fp2, effectshaders[i].defines)) { - for(int i=0;iLoad(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, - effectshaders[i].fp2, effectshaders[i].defines)) - { - delete eff; - } - else mEffectShaders[i] = eff; - } + delete eff; } + else mEffectShaders[i] = eff; } } @@ -562,17 +440,24 @@ void FShaderManager::CompileShaders() void FShaderManager::Clean() { - SetActiveShader(NULL); - for(unsigned int i=0;iName == sfn) + if (mTextureEffects[i]->mName == sfn) { return i; } @@ -603,14 +488,14 @@ int FShaderManager::Find(const char * shn) void FShaderManager::SetActiveShader(FShader *sh) { - // shadermodel needs to be tested here because without it UseProgram will be NULL. - if (gl.shadermodel > 0 && mActiveShader != sh) + if (mActiveShader != sh) { - glUseProgram(sh == NULL? 0 : sh->GetHandle()); + glUseProgram(sh!= NULL? sh->GetHandle() : 0); mActiveShader = sh; } } + //========================================================================== // // @@ -619,15 +504,45 @@ void FShaderManager::SetActiveShader(FShader *sh) FShader *FShaderManager::BindEffect(int effect) { - if (effect > 0 && effect <= NUM_EFFECTS && mEffectShaders[effect-1] != NULL) + if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL) { - mEffectShaders[effect-1]->Bind(0); - return mEffectShaders[effect-1]; + mEffectShaders[effect]->Bind(); + return mEffectShaders[effect]; } return NULL; } +//========================================================================== +// +// +// +//========================================================================== +EXTERN_CVAR(Int, gl_fuzztype) + +void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) +{ + for (int i = 0; i < 4; i++) + { + mTextureEffects[i]->ApplyMatrices(proj, view); + mTextureEffectsNAT[i]->ApplyMatrices(proj, view); + } + mTextureEffects[4]->ApplyMatrices(proj, view); + if (gl_fuzztype != 0) + { + mTextureEffects[4+gl_fuzztype]->ApplyMatrices(proj, view); + } + for (unsigned i = 12; i < mTextureEffects.Size(); i++) + { + mTextureEffects[i]->ApplyMatrices(proj, view); + } + for (int i = 0; i < MAX_EFFECTS; i++) + { + mEffectShaders[i]->ApplyMatrices(proj, view); + } + if (mActiveShader != NULL) mActiveShader->Bind(); +} + //========================================================================== // // diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 61053287c..92ef221af 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -7,76 +7,222 @@ extern bool gl_shaderactive; -const int VATTR_FOGPARAMS = 14; -const int VATTR_LIGHTLEVEL = 13; // Korshun. +enum +{ + VATTR_VERTEX = 0, + VATTR_TEXCOORD = 1, + VATTR_COLOR = 2, + VATTR_VERTEX2 = 3 +}; + //========================================================================== // // //========================================================================== +class FUniform1i +{ + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + } + + void Set(int newvalue) + { + glUniform1i(mIndex, newvalue); + } +}; + +class FBufferedUniform1i +{ + int mBuffer; + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + mBuffer = 0; + } + + void Set(int newvalue) + { + if (newvalue != mBuffer) + { + mBuffer = newvalue; + glUniform1i(mIndex, newvalue); + } + } +}; + +class FBufferedUniform4i +{ + int mBuffer[4]; + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + memset(mBuffer, 0, sizeof(mBuffer)); + } + + void Set(const int *newvalue) + { + if (memcmp(newvalue, mBuffer, sizeof(mBuffer))) + { + memcpy(mBuffer, newvalue, sizeof(mBuffer)); + glUniform4iv(mIndex, 1, newvalue); + } + } +}; + +class FBufferedUniform1f +{ + float mBuffer; + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + mBuffer = 0; + } + + void Set(float newvalue) + { + if (newvalue != mBuffer) + { + mBuffer = newvalue; + glUniform1f(mIndex, newvalue); + } + } +}; + +class FBufferedUniform4f +{ + float mBuffer[4]; + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + memset(mBuffer, 0, sizeof(mBuffer)); + } + + void Set(const float *newvalue) + { + if (memcmp(newvalue, mBuffer, sizeof(mBuffer))) + { + memcpy(mBuffer, newvalue, sizeof(mBuffer)); + glUniform4fv(mIndex, 1, newvalue); + } + } +}; + +class FUniform4f +{ + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + } + + void Set(const float *newvalue) + { + glUniform4fv(mIndex, 1, newvalue); + } + + void Set(float a, float b, float c, float d) + { + glUniform4f(mIndex, a, b, c, d); + } +}; + +class FBufferedUniformPE +{ + PalEntry mBuffer; + int mIndex; + +public: + void Init(GLuint hShader, const GLchar *name) + { + mIndex = glGetUniformLocation(hShader, name); + mBuffer = 0; + } + + void Set(PalEntry newvalue) + { + if (newvalue != mBuffer) + { + mBuffer = newvalue; + glUniform4f(mIndex, newvalue.r/255.f, newvalue.g/255.f, newvalue.b/255.f, newvalue.a/255.f); + } + } +}; + + class FShader { - friend class FShaderContainer; + friend class FShaderManager; friend class FRenderState; unsigned int hShader; unsigned int hVertProg; unsigned int hFragProg; + FName mName; - int timer_index; - int desaturation_index; - int fogenabled_index; - int texturemode_index; - int camerapos_index; - int lightparms_index; - int colormapstart_index; - int colormaprange_index; - int lightrange_index; - int fogcolor_index; + FBufferedUniform1f muDesaturation; + FBufferedUniform1i muFogEnabled; + FBufferedUniform1i muTextureMode; + FBufferedUniform4f muCameraPos; + FBufferedUniform4f muLightParms; + FUniform1i muFixedColormap; + FUniform4f muColormapStart; + FUniform4f muColormapRange; + FBufferedUniform1i muLightIndex; + FBufferedUniformPE muFogColor; + FBufferedUniform4f muDynLightColor; + FBufferedUniformPE muObjectColor; + FUniform4f muGlowBottomColor; + FUniform4f muGlowTopColor; + FUniform4f muGlowBottomPlane; + FUniform4f muGlowTopPlane; + FBufferedUniform1f muInterpolationFactor; + FBufferedUniform1f muClipHeightTop; + FBufferedUniform1f muClipHeightBottom; + FBufferedUniform1f muAlphaThreshold; + FBufferedUniform1f muTimer; + int lights_index; - int dlightcolor_index; - int glowbottomcolor_index; - int glowtopcolor_index; - int glowbottomplane_index; - int glowtopplane_index; - + int projectionmatrix_index; + int viewmatrix_index; + int modelmatrix_index; + int texturematrix_index; +public: + int fakevb_index; +private: int currentglowstate; - int currentfogenabled; - int currenttexturemode; - float currentlightfactor; - float currentlightdist; - - PalEntry currentfogcolor; - float currentfogdensity; - - FStateVec3 currentcamerapos; + int currentfixedcolormap; + bool currentTextureMatrixState; + bool currentModelMatrixState; public: - FShader() + FShader(const char *name) + : mName(name) { hShader = hVertProg = hFragProg = 0; - currentglowstate = currentfogenabled = currenttexturemode = 0; - currentlightfactor = currentlightdist = 0.0f; - currentfogdensity = -1; - currentfogcolor = 0; - - timer_index = -1; - desaturation_index = -1; - fogenabled_index = -1; - texturemode_index = -1; - camerapos_index = -1; - lightparms_index = -1; - colormapstart_index = -1; - colormaprange_index = -1; - lightrange_index = -1; - fogcolor_index = -1; - lights_index = -1; - dlightcolor_index = -1; - glowtopplane_index = -1; - glowbottomplane_index = -1; - glowtopcolor_index = -1; - glowbottomcolor_index = -1; + currentglowstate = 0; + currentfixedcolormap = 0; + currentTextureMatrixState = true; // by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied. + currentModelMatrixState = true; } ~FShader(); @@ -87,34 +233,11 @@ public: void SetGlowParams(float *topcolors, float topheight, float *bottomcolors, float bottomheight); void SetLightRange(int start, int end, int forceadd); - bool Bind(float Speed); + bool Bind(); unsigned int GetHandle() const { return hShader; } -}; + void ApplyMatrices(VSMatrix *proj, VSMatrix *view); -//========================================================================== -// -// This class contains the shaders for the different lighting modes -// that are required (e.g. special colormaps etc.) -// -//========================================================================== - -class FShaderContainer -{ - friend class FShaderManager; - - FName Name; - - enum { NUM_SHADERS = 16 }; - - FShader *shader[NUM_SHADERS]; - FShader *shader_cm; // the shader for fullscreen colormaps - FShader *shader_fl; // the shader for the fog layer - -public: - FShaderContainer(const char *ShaderName, const char *ShaderPath); - ~FShaderContainer(); - FShader *Bind(int cm, bool glowing, float Speed, bool lights); }; @@ -125,14 +248,10 @@ public: //========================================================================== class FShaderManager { - enum - { - NUM_EFFECTS = 2 - }; - - TArray mTextureEffects; + TArray mTextureEffects; + TArray mTextureEffectsNAT; FShader *mActiveShader; - FShader *mEffectShaders[NUM_EFFECTS]; + FShader *mEffectShaders[MAX_EFFECTS]; void Clean(); void CompileShaders(); @@ -140,25 +259,37 @@ class FShaderManager public: FShaderManager(); ~FShaderManager(); + FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard); int Find(const char *mame); FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); + void ApplyMatrices(VSMatrix *proj, VSMatrix *view); + FShader *GetActiveShader() const + { + return mActiveShader; + } - FShaderContainer *Get(unsigned int eff) + FShader *Get(unsigned int eff, bool alphateston) { // indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom + if (!alphateston && eff <= 3) + { + return mTextureEffectsNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway + } if (eff < mTextureEffects.Size()) { return mTextureEffects[eff]; } return NULL; } - - void Recompile(); }; #define FIRST_USER_SHADER 12 +enum +{ + LIGHTBUF_BINDINGPOINT = 1 +}; #endif diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index f748f9b52..cedeec06a 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -10,12 +10,6 @@ #pragma warning(disable:4244) #endif -EXTERN_CVAR(Bool, gl_warp_shader) -EXTERN_CVAR(Bool, gl_fog_shader) -EXTERN_CVAR(Bool, gl_colormap_shader) -EXTERN_CVAR(Bool, gl_brightmap_shader) -EXTERN_CVAR(Bool, gl_glow_shader) - EXTERN_CVAR(Bool,gl_enhanced_nightvision) EXTERN_CVAR(Int, screenblocks); EXTERN_CVAR(Bool, gl_texture) @@ -27,8 +21,6 @@ EXTERN_CVAR(Bool, gl_usefb) EXTERN_CVAR(Int, gl_weaponlight) -EXTERN_CVAR(Bool, gl_forcemultipass) - EXTERN_CVAR (Bool, gl_lights); EXTERN_CVAR (Bool, gl_attachedlights); EXTERN_CVAR (Bool, gl_lights_checkside); @@ -44,15 +36,9 @@ EXTERN_CVAR(Bool,gl_mirror_envmap) EXTERN_CVAR(Bool,gl_mirrors) EXTERN_CVAR(Bool,gl_mirror_envmap) -EXTERN_CVAR(Bool, gl_render_segs) EXTERN_CVAR(Bool, gl_seamless) -EXTERN_CVAR(Bool, gl_dynlight_shader) EXTERN_CVAR(Float, gl_mask_threshold) EXTERN_CVAR(Float, gl_mask_sprite_threshold) -EXTERN_CVAR(Int, gl_usevbo) - - - #endif // _GL_INTERN_H diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 99e9bd9a4..d9f05bea6 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -54,6 +54,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/renderer/gl_renderer.h" +#include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_lightdata.h" #include "gl/data/gl_data.h" #include "gl/textures/gl_hwtexture.h" @@ -73,9 +74,9 @@ CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE) FGLRenderer *GLRenderer; -void gl_SetupMenu(); void gl_LoadExtensions(); void gl_PrintStartupLog(); +void gl_SetupMenu(); //========================================================================== // @@ -120,11 +121,12 @@ void OpenGLFrameBuffer::InitializeState() if (first) { - glewInit(); + ogl_LoadFunctions(); } gl_LoadExtensions(); Super::InitializeState(); + if (first) { first=false; @@ -137,31 +139,17 @@ void OpenGLFrameBuffer::InitializeState() glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glDepthFunc(GL_LESS); - glShadeModel(GL_SMOOTH); glEnable(GL_DITHER); - glEnable(GL_ALPHA_TEST); glDisable(GL_CULL_FACE); glDisable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_LINE); glEnable(GL_BLEND); - glEnable(GL_DEPTH_CLAMP_NV); + glEnable(GL_DEPTH_CLAMP); glDisable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glDisable(GL_LINE_SMOOTH); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glAlphaFunc(GL_GEQUAL,0.5f); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - // This was to work around a bug in some older driver. Probably doesn't make sense anymore. - glEnable(GL_FOG); - glDisable(GL_FOG); - - glHint(GL_FOG_HINT, GL_FASTEST); - glFogi(GL_FOG_MODE, GL_EXP); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -386,18 +374,10 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap) //========================================================================== bool OpenGLFrameBuffer::Begin2D(bool) { - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho( - (GLdouble) 0, - (GLdouble) GetWidth(), - (GLdouble) GetHeight(), - (GLdouble) 0, - (GLdouble) -1.0, - (GLdouble) 1.0 - ); + gl_RenderState.mViewMatrix.loadIdentity(); + gl_RenderState.mProjectionMatrix.ortho(0, GetWidth(), GetHeight(), 0, -1.0f, 1.0f); + gl_RenderState.ApplyMatrices(); + glDisable(GL_DEPTH_TEST); // Korshun: ENABLE AUTOMAP ANTIALIASING!!! @@ -556,4 +536,5 @@ void OpenGLFrameBuffer::GameRestart() ScreenshotBuffer = NULL; LastCamera = NULL; gl_GenerateGlobalBrightmapFromColormap(); -} \ No newline at end of file +} + diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 214702566..be0beaf4e 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -52,7 +52,6 @@ RenderContext gl; int occlusion_type=0; - //========================================================================== // // @@ -61,24 +60,15 @@ int occlusion_type=0; static void CollectExtensions() { - const char *supported = NULL; - char *extensions, *extension; + const char *extension; - supported = (char *)glGetString(GL_EXTENSIONS); + int max = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &max); - if (supported) + for(int i = 0; i < max; i++) { - extensions = new char[strlen(supported) + 1]; - strcpy(extensions, supported); - - extension = strtok(extensions, " "); - while(extension) - { - m_Extensions.Push(FString(extension)); - extension = strtok(NULL, " "); - } - - delete [] extensions; + extension = (const char*)glGetStringi(GL_EXTENSIONS, i); + m_Extensions.Push(FString(extension)); } } @@ -122,61 +112,41 @@ void gl_LoadExtensions() InitContext(); CollectExtensions(); - const char *version = (const char*)glGetString(GL_VERSION); + const char *version = Args->CheckValue("-glversion"); + if (version == NULL) version = (const char*)glGetString(GL_VERSION); + else Printf("Emulating OpenGL v %s\n", version); - // Don't even start if it's lower than 1.3 - if (strcmp(version, "2.0") < 0) + // Don't even start if it's lower than 3.0 + if (strcmp(version, "3.0") < 0) { - I_FatalError("Unsupported OpenGL version.\nAt least GL 2.0 is required to run " GAMENAME ".\n"); + I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.0 is required to run " GAMENAME ".\n"); } - // This loads any function pointers and flags that require a vaild render context to - // initialize properly + // add 0.01 to account for roundoff errors making the number a tad smaller than the actual version + gl.version = strtod(version, NULL) + 0.01f; + gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f; - gl.shadermodel = 0; // assume no shader support - gl.vendorstring=(char*)glGetString(GL_VENDOR); + gl.vendorstring = (char*)glGetString(GL_VENDOR); if (CheckExtension("GL_ARB_texture_compression")) gl.flags|=RFL_TEXTURE_COMPRESSION; if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC; - if (strstr(gl.vendorstring, "NVIDIA")) gl.flags|=RFL_NVIDIA; - else if (strstr(gl.vendorstring, "ATI Technologies")) gl.flags|=RFL_ATI; - - if (strcmp(version, "2.0") >= 0) gl.flags|=RFL_GL_20; - if (strcmp(version, "2.1") >= 0) gl.flags|=RFL_GL_21; - if (strcmp(version, "3.0") >= 0) gl.flags|=RFL_GL_30; - + if (!Args->CheckParm("-gl3")) + { + // don't use GL 4.x features when running in GL 3 emulation mode. + if (CheckExtension("GL_ARB_shader_storage_buffer_object")) gl.flags |= RFL_SHADER_STORAGE_BUFFER; + if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; + } + + int v; + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); + gl.maxuniforms = v; + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); + gl.maxuniformblock = v; + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); + gl.uniformblockalignment = v; + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if (gl.flags & RFL_GL_20) - { - // Rules: - // SM4 will always use shaders. No option to switch them off is needed here. - // SM3 has shaders optional but they are off by default (they will have a performance impact - // SM2 only uses shaders for colormaps on camera textures and has no option to use them in general. - // On SM2 cards the shaders will be too slow and show visual bugs (at least on GF 6800.) - if (strcmp((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION), "1.3") >= 0) gl.shadermodel = 4; - else if (CheckExtension("GL_NV_GPU_shader4")) gl.shadermodel = 4; // for pre-3.0 drivers that support GF8xxx. - else if (CheckExtension("GL_EXT_GPU_shader4")) gl.shadermodel = 4; // for pre-3.0 drivers that support GF8xxx. - else if (CheckExtension("GL_NV_vertex_program3")) gl.shadermodel = 3; - else if (!strstr(gl.vendorstring, "NVIDIA")) gl.shadermodel = 3; - else gl.shadermodel = 2; // Only for older NVidia cards which had notoriously bad shader support. - - // Command line overrides for testing and problem cases. - if (Args->CheckParm("-sm2") && gl.shadermodel > 2) gl.shadermodel = 2; - else if (Args->CheckParm("-sm3") && gl.shadermodel > 3) gl.shadermodel = 3; - } - - if (CheckExtension("GL_ARB_map_buffer_range")) - { - gl.flags|=RFL_MAP_BUFFER_RANGE; - } - - if (gl.flags & RFL_GL_30) - { - gl.flags|=RFL_FRAMEBUFFER; - } - } //========================================================================== @@ -187,99 +157,39 @@ void gl_LoadExtensions() void gl_PrintStartupLog() { + int v; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v); + Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); - Printf ("GL_VERSION: %s\n", glGetString(GL_VERSION)); + Printf ("GL_VERSION: %s (%s profile)\n", glGetString(GL_VERSION), (v & GL_CONTEXT_CORE_PROFILE_BIT)? "Core" : "Compatibility"); Printf ("GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - Printf ("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); - int v; + Printf ("GL_EXTENSIONS:"); + for (unsigned i = 0; i < m_Extensions.Size(); i++) + { + Printf(" %s", m_Extensions[i].GetChars()); + } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &v); - Printf("Max. texture size: %d\n", v); + Printf("\nMax. texture size: %d\n", v); glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &v); Printf ("Max. texture units: %d\n", v); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); Printf ("Max. fragment uniforms: %d\n", v); - if (gl.shadermodel == 4) gl.maxuniforms = v; glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &v); Printf ("Max. vertex uniforms: %d\n", v); + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); + Printf ("Max. uniform block size: %d\n", v); + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); + Printf ("Uniform block alignment: %d\n", v); + glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); - glGetIntegerv(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, &v); - Printf ("Max. combined uniforms: %d\n", v); - glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &v); - Printf ("Max. combined uniform blocks: %d\n", v); + glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &v); + Printf("Max. combined shader storage blocks: %d\n", v); + glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); + Printf("Max. vertex shader storage blocks: %d\n", v); + } -//========================================================================== -// -// -// -//========================================================================== - -void gl_SetTextureMode(int type) -{ - static float white[] = {1.f,1.f,1.f,1.f}; - - if (type == TM_MASK) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); - } - else if (type == TM_OPAQUE) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - } - else if (type == TM_INVERT) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); - } - else if (type == TM_INVERTOPAQUE) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - } - else // if (type == TM_MODULATE) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } -} - -//} // extern "C" diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 79623c07f..2d2e26d51 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -6,40 +6,30 @@ enum RenderFlags { // [BB] Added texture compression flags. - RFL_TEXTURE_COMPRESSION=8, - RFL_TEXTURE_COMPRESSION_S3TC=16, + RFL_TEXTURE_COMPRESSION=1, + RFL_TEXTURE_COMPRESSION_S3TC=2, - RFL_MAP_BUFFER_RANGE = 64, - RFL_FRAMEBUFFER = 128, - RFL_TEXTUREBUFFER = 256, - RFL_NVIDIA = 512, - RFL_ATI = 1024, - - - RFL_GL_20 = 0x10000000, - RFL_GL_21 = 0x20000000, - RFL_GL_30 = 0x40000000, + RFL_SHADER_STORAGE_BUFFER = 4, + RFL_BUFFER_STORAGE = 8 }; enum TexMode { - TMF_MASKBIT = 1, - TMF_OPAQUEBIT = 2, - TMF_INVERTBIT = 4, - - TM_MODULATE = 0, - TM_MASK = TMF_MASKBIT, - TM_OPAQUE = TMF_OPAQUEBIT, - TM_INVERT = TMF_INVERTBIT, - //TM_INVERTMASK = TMF_MASKBIT | TMF_INVERTBIT - TM_INVERTOPAQUE = TMF_INVERTBIT | TMF_OPAQUEBIT, + TM_MODULATE = 0, // (r, g, b, a) + TM_MASK, // (1, 1, 1, a) + TM_OPAQUE, // (r, g, b, 1) + TM_INVERSE, // (1-r, 1-g, 1-b, a) + TM_REDTOALPHA, // (1, 1, 1, r) }; struct RenderContext { unsigned int flags; - unsigned int shadermodel; unsigned int maxuniforms; + unsigned int maxuniformblock; + unsigned int uniformblockalignment; + float version; + float glslversion; int max_texturesize; char * vendorstring; diff --git a/src/gl/system/gl_load.c b/src/gl/system/gl_load.c new file mode 100644 index 000000000..282395016 --- /dev/null +++ b/src/gl/system/gl_load.c @@ -0,0 +1,1346 @@ +#include +#include +#include +#include "gl_load.h" + +#if defined(__APPLE__) +#include + +static void* AppleGLGetProcAddress (const GLubyte *name) +{ + static const struct mach_header* image = NULL; + NSSymbol symbol; + char* symbolName; + if (NULL == image) + { + image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + /* prepend a '_' for the Unix C symbol mangling convention */ + symbolName = malloc(strlen((const char*)name) + 2); + strcpy(symbolName+1, (const char*)name); + symbolName[0] = '_'; + symbol = NULL; + /* if (NSIsSymbolNameDefined(symbolName)) + symbol = NSLookupAndBindSymbol(symbolName); */ + symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL; + free(symbolName); + return symbol ? NSAddressOfSymbol(symbol) : NULL; +} +#endif /* __APPLE__ */ + +#if defined(__sgi) || defined (__sun) +#include +#include + +static void* SunGetProcAddress (const GLubyte* name) +{ + static void* h = NULL; + static void* gpa; + + if (h == NULL) + { + if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL; + gpa = dlsym(h, "glXGetProcAddress"); + } + + if (gpa != NULL) + return ((void*(*)(const GLubyte*))gpa)(name); + else + return dlsym(h, (const char*)name); +} +#endif /* __sgi || __sun */ + +#if defined(_WIN32) + +#ifdef _MSC_VER +// disable inlining here because it creates an incredible amount of bloat here. +#pragma inline_depth(0) +#pragma warning(disable: 4055) +#pragma warning(disable: 4054) +#endif + +static int TestPointer(const PROC pTest) +{ + ptrdiff_t iTest; + if(!pTest) return 0; + iTest = (ptrdiff_t)pTest; + + if(iTest == 1 || iTest == 2 || iTest == 3 || iTest == -1) return 0; + + return 1; +} + +static PROC WinGetProcAddress(const char *name) +{ + HMODULE glMod = NULL; + PROC pFunc = wglGetProcAddress((LPCSTR)name); + if(TestPointer(pFunc)) + { + return pFunc; + } + glMod = GetModuleHandleA("OpenGL32.dll"); + return (PROC)GetProcAddress(glMod, (LPCSTR)name); +} + +#define IntGetProcAddress(name) WinGetProcAddress(name) +#else + #if defined(__APPLE__) + #define IntGetProcAddress(name) AppleGLGetProcAddress(name) + #else + #if defined(__sgi) || defined(__sun) + #define IntGetProcAddress(name) SunGetProcAddress(name) + #else /* GLX */ + #include + + #define IntGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name) + #endif + #endif +#endif + +int ogl_ext_ARB_texture_compression = ogl_LOAD_FAILED; +int ogl_ext_EXT_texture_compression_s3tc = ogl_LOAD_FAILED; +int ogl_ext_ARB_buffer_storage = ogl_LOAD_FAILED; +int ogl_ext_ARB_shader_storage_buffer_object = ogl_LOAD_FAILED; +int ogl_ext_EXT_texture_sRGB = ogl_LOAD_FAILED; +int ogl_ext_EXT_texture_filter_anisotropic = ogl_LOAD_FAILED; + +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage1DARB)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage2DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage3DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage1DARB)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage2DARB)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage3DARB)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTexImageARB)(GLenum, GLint, GLvoid *) = NULL; + +static int Load_ARB_texture_compression() +{ + int numFailed = 0; + _ptrc_glCompressedTexImage1DARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexImage1DARB"); + if(!_ptrc_glCompressedTexImage1DARB) numFailed++; + _ptrc_glCompressedTexImage2DARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexImage2DARB"); + if(!_ptrc_glCompressedTexImage2DARB) numFailed++; + _ptrc_glCompressedTexImage3DARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexImage3DARB"); + if(!_ptrc_glCompressedTexImage3DARB) numFailed++; + _ptrc_glCompressedTexSubImage1DARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexSubImage1DARB"); + if(!_ptrc_glCompressedTexSubImage1DARB) numFailed++; + _ptrc_glCompressedTexSubImage2DARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexSubImage2DARB"); + if(!_ptrc_glCompressedTexSubImage2DARB) numFailed++; + _ptrc_glCompressedTexSubImage3DARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexSubImage3DARB"); + if(!_ptrc_glCompressedTexSubImage3DARB) numFailed++; + _ptrc_glGetCompressedTexImageARB = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLvoid *))IntGetProcAddress("glGetCompressedTexImageARB"); + if(!_ptrc_glGetCompressedTexImageARB) numFailed++; + return numFailed; +} + +void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum, GLsizeiptr, const void *, GLbitfield) = NULL; + +static int Load_ARB_buffer_storage() +{ + int numFailed = 0; + _ptrc_glBufferStorage = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizeiptr, const void *, GLbitfield))IntGetProcAddress("glBufferStorage"); + if(!_ptrc_glBufferStorage) numFailed++; + return numFailed; +} + +void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint, GLuint, GLuint) = NULL; + +static int Load_ARB_shader_storage_buffer_object() +{ + int numFailed = 0; + _ptrc_glShaderStorageBlockBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glShaderStorageBlockBinding"); + if(!_ptrc_glShaderStorageBlockBinding) numFailed++; + return numFailed; +} + +void (CODEGEN_FUNCPTR *_ptrc_glBegin)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEnd)() = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBlendFunc)(GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClear)(GLbitfield) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearDepth)(GLdouble) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearStencil)(GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glColorMask)(GLboolean, GLboolean, GLboolean, GLboolean) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCullFace)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDepthFunc)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDepthMask)(GLboolean) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDepthRange)(GLdouble, GLdouble) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDisable)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawBuffer)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEnable)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFinish)() = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFlush)() = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFrontFace)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetBooleanv)(GLenum, GLboolean *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetDoublev)(GLenum, GLdouble *) = NULL; +GLenum (CODEGEN_FUNCPTR *_ptrc_glGetError)() = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetFloatv)(GLenum, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetIntegerv)(GLenum, GLint *) = NULL; +const GLubyte * (CODEGEN_FUNCPTR *_ptrc_glGetString)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexImage)(GLenum, GLint, GLenum, GLenum, GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexLevelParameterfv)(GLenum, GLint, GLenum, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexLevelParameteriv)(GLenum, GLint, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameterfv)(GLenum, GLenum, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameteriv)(GLenum, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glHint)(GLenum, GLenum) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsEnabled)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glLineWidth)(GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glLogicOp)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPixelStoref)(GLenum, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPixelStorei)(GLenum, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPointSize)(GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPolygonMode)(GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glReadBuffer)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glScissor)(GLint, GLint, GLsizei, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glStencilFunc)(GLenum, GLint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glStencilMask)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glStencilOp)(GLenum, GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexParameterf)(GLenum, GLenum, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexParameterfv)(GLenum, GLenum, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexParameteri)(GLenum, GLenum, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexParameteriv)(GLenum, GLenum, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glViewport)(GLint, GLint, GLsizei, GLsizei) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBindTexture)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTexImage1D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTexImage2D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTexSubImage1D)(GLenum, GLint, GLint, GLint, GLint, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTexSubImage2D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteTextures)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawArrays)(GLenum, GLint, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElements)(GLenum, GLsizei, GLenum, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenTextures)(GLsizei, GLuint *) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsTexture)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPolygonOffset)(GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBlendColor)(GLfloat, GLfloat, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlendEquation)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTexSubImage3D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawRangeElements)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexSubImage3D)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glActiveTexture)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage1D)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage2D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage3D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage3D)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTexImage)(GLenum, GLint, GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSampleCoverage)(GLfloat, GLboolean) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBlendFuncSeparate)(GLenum, GLenum, GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawArrays)(GLenum, const GLint *, const GLsizei *, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawElements)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPointParameterf)(GLenum, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPointParameterfv)(GLenum, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPointParameteri)(GLenum, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPointParameteriv)(GLenum, const GLint *) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBeginQuery)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindBuffer)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBufferData)(GLenum, GLsizeiptr, const GLvoid *, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBufferSubData)(GLenum, GLintptr, GLsizeiptr, const GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteBuffers)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteQueries)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEndQuery)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenBuffers)(GLsizei, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenQueries)(GLsizei, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetBufferParameteriv)(GLenum, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetBufferPointerv)(GLenum, GLenum, GLvoid **) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetBufferSubData)(GLenum, GLintptr, GLsizeiptr, GLvoid *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjectiv)(GLuint, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjectuiv)(GLuint, GLenum, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryiv)(GLenum, GLenum, GLint *) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsBuffer)(GLuint) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsQuery)(GLuint) = NULL; +void * (CODEGEN_FUNCPTR *_ptrc_glMapBuffer)(GLenum, GLenum) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glUnmapBuffer)(GLenum) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glAttachShader)(GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindAttribLocation)(GLuint, GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlendEquationSeparate)(GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompileShader)(GLuint) = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glCreateProgram)() = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glCreateShader)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteProgram)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteShader)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDetachShader)(GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDisableVertexAttribArray)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawBuffers)(GLsizei, const GLenum *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEnableVertexAttribArray)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveAttrib)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniform)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetAttachedShaders)(GLuint, GLsizei, GLsizei *, GLuint *) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetAttribLocation)(GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramiv)(GLuint, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetShaderInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetShaderSource)(GLuint, GLsizei, GLsizei *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetShaderiv)(GLuint, GLenum, GLint *) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetUniformLocation)(GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetUniformfv)(GLuint, GLint, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetUniformiv)(GLuint, GLint, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribPointerv)(GLuint, GLenum, GLvoid **) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribdv)(GLuint, GLenum, GLdouble *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribfv)(GLuint, GLenum, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribiv)(GLuint, GLenum, GLint *) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsProgram)(GLuint) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsShader)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glLinkProgram)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glShaderSource)(GLuint, GLsizei, const GLchar *const*, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glStencilFuncSeparate)(GLenum, GLenum, GLint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glStencilMaskSeparate)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glStencilOpSeparate)(GLenum, GLenum, GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1f)(GLint, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1fv)(GLint, GLsizei, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1i)(GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1iv)(GLint, GLsizei, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2f)(GLint, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2fv)(GLint, GLsizei, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2i)(GLint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2iv)(GLint, GLsizei, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3f)(GLint, GLfloat, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3fv)(GLint, GLsizei, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3i)(GLint, GLint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3iv)(GLint, GLsizei, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4f)(GLint, GLfloat, GLfloat, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4fv)(GLint, GLsizei, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4i)(GLint, GLint, GLint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4iv)(GLint, GLsizei, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUseProgram)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glValidateProgram)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1d)(GLuint, GLdouble) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1dv)(GLuint, const GLdouble *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1f)(GLuint, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1fv)(GLuint, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1s)(GLuint, GLshort) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1sv)(GLuint, const GLshort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2d)(GLuint, GLdouble, GLdouble) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2dv)(GLuint, const GLdouble *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2f)(GLuint, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2fv)(GLuint, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2s)(GLuint, GLshort, GLshort) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2sv)(GLuint, const GLshort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3d)(GLuint, GLdouble, GLdouble, GLdouble) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3dv)(GLuint, const GLdouble *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3f)(GLuint, GLfloat, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3fv)(GLuint, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3s)(GLuint, GLshort, GLshort, GLshort) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3sv)(GLuint, const GLshort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nbv)(GLuint, const GLbyte *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Niv)(GLuint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nsv)(GLuint, const GLshort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nub)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nubv)(GLuint, const GLubyte *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nuiv)(GLuint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nusv)(GLuint, const GLushort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4bv)(GLuint, const GLbyte *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4d)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4dv)(GLuint, const GLdouble *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4f)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4fv)(GLuint, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4iv)(GLuint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4s)(GLuint, GLshort, GLshort, GLshort, GLshort) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4sv)(GLuint, const GLshort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4ubv)(GLuint, const GLubyte *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4uiv)(GLuint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4usv)(GLuint, const GLushort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x3fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x4fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x2fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x4fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x2fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x3fv)(GLint, GLsizei, GLboolean, const GLfloat *) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBeginConditionalRender)(GLuint, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBeginTransformFeedback)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindBufferBase)(GLenum, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindBufferRange)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindFragDataLocation)(GLuint, GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindFramebuffer)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindRenderbuffer)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindVertexArray)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlitFramebuffer)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum) = NULL; +GLenum (CODEGEN_FUNCPTR *_ptrc_glCheckFramebufferStatus)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClampColor)(GLenum, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearBufferfi)(GLenum, GLint, GLfloat, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearBufferfv)(GLenum, GLint, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearBufferiv)(GLenum, GLint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearBufferuiv)(GLenum, GLint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glColorMaski)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteFramebuffers)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteRenderbuffers)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteVertexArrays)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDisablei)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEnablei)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEndConditionalRender)() = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEndTransformFeedback)() = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFlushMappedBufferRange)(GLenum, GLintptr, GLsizeiptr) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferRenderbuffer)(GLenum, GLenum, GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture1D)(GLenum, GLenum, GLenum, GLuint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture2D)(GLenum, GLenum, GLenum, GLuint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture3D)(GLenum, GLenum, GLenum, GLuint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTextureLayer)(GLenum, GLenum, GLuint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenFramebuffers)(GLsizei, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenRenderbuffers)(GLsizei, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenVertexArrays)(GLsizei, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenerateMipmap)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetBooleani_v)(GLenum, GLuint, GLboolean *) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetFragDataLocation)(GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetFramebufferAttachmentParameteriv)(GLenum, GLenum, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetIntegeri_v)(GLenum, GLuint, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetRenderbufferParameteriv)(GLenum, GLenum, GLint *) = NULL; +const GLubyte * (CODEGEN_FUNCPTR *_ptrc_glGetStringi)(GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameterIiv)(GLenum, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameterIuiv)(GLenum, GLenum, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbackVarying)(GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetUniformuiv)(GLuint, GLint, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribIiv)(GLuint, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribIuiv)(GLuint, GLenum, GLuint *) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsEnabledi)(GLenum, GLuint) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsFramebuffer)(GLuint) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsRenderbuffer)(GLuint) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsVertexArray)(GLuint) = NULL; +void * (CODEGEN_FUNCPTR *_ptrc_glMapBufferRange)(GLenum, GLintptr, GLsizeiptr, GLbitfield) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glRenderbufferStorage)(GLenum, GLenum, GLsizei, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glRenderbufferStorageMultisample)(GLenum, GLsizei, GLenum, GLsizei, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexParameterIiv)(GLenum, GLenum, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexParameterIuiv)(GLenum, GLenum, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTransformFeedbackVaryings)(GLuint, GLsizei, const GLchar *const*, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1ui)(GLint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1uiv)(GLint, GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2ui)(GLint, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2uiv)(GLint, GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3ui)(GLint, GLuint, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3uiv)(GLint, GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4ui)(GLint, GLuint, GLuint, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4uiv)(GLint, GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1i)(GLuint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1iv)(GLuint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1ui)(GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1uiv)(GLuint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2i)(GLuint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2iv)(GLuint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2ui)(GLuint, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2uiv)(GLuint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3i)(GLuint, GLint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3iv)(GLuint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3ui)(GLuint, GLuint, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3uiv)(GLuint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4bv)(GLuint, const GLbyte *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4i)(GLuint, GLint, GLint, GLint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4iv)(GLuint, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4sv)(GLuint, const GLshort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4ubv)(GLuint, const GLubyte *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4ui)(GLuint, GLuint, GLuint, GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4uiv)(GLuint, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4usv)(GLuint, const GLushort *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribIPointer)(GLuint, GLint, GLenum, GLsizei, const GLvoid *) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glCopyBufferSubData)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawArraysInstanced)(GLenum, GLint, GLsizei, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstanced)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformBlockName)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformBlockiv)(GLuint, GLuint, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformName)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformsiv)(GLuint, GLsizei, const GLuint *, GLenum, GLint *) = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glGetUniformBlockIndex)(GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetUniformIndices)(GLuint, GLsizei, const GLchar *const*, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPrimitiveRestartIndex)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexBuffer)(GLenum, GLenum, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformBlockBinding)(GLuint, GLuint, GLuint) = NULL; + +GLenum (CODEGEN_FUNCPTR *_ptrc_glClientWaitSync)(GLsync, GLbitfield, GLuint64) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteSync)(GLsync) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsBaseVertex)(GLenum, GLsizei, GLenum, const GLvoid *, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstancedBaseVertex)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawRangeElementsBaseVertex)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint) = NULL; +GLsync (CODEGEN_FUNCPTR *_ptrc_glFenceSync)(GLenum, GLbitfield) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture)(GLenum, GLenum, GLuint, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetBufferParameteri64v)(GLenum, GLenum, GLint64 *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetInteger64i_v)(GLenum, GLuint, GLint64 *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetInteger64v)(GLenum, GLint64 *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetMultisamplefv)(GLenum, GLuint, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetSynciv)(GLsync, GLenum, GLsizei, GLsizei *, GLint *) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsSync)(GLsync) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawElementsBaseVertex)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProvokingVertex)(GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSampleMaski)(GLuint, GLbitfield) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexImage2DMultisample)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexImage3DMultisample)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glWaitSync)(GLsync, GLbitfield, GLuint64) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBindFragDataLocationIndexed)(GLuint, GLuint, GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindSampler)(GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteSamplers)(GLsizei, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenSamplers)(GLsizei, GLuint *) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetFragDataIndex)(GLuint, const GLchar *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjecti64v)(GLuint, GLenum, GLint64 *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjectui64v)(GLuint, GLenum, GLuint64 *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameterIiv)(GLuint, GLenum, GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameterIuiv)(GLuint, GLenum, GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameterfv)(GLuint, GLenum, GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameteriv)(GLuint, GLenum, GLint *) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsSampler)(GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glQueryCounter)(GLuint, GLenum) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterIiv)(GLuint, GLenum, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterIuiv)(GLuint, GLenum, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterf)(GLuint, GLenum, GLfloat) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterfv)(GLuint, GLenum, const GLfloat *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameteri)(GLuint, GLenum, GLint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameteriv)(GLuint, GLenum, const GLint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribDivisor)(GLuint, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP1ui)(GLuint, GLenum, GLboolean, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP1uiv)(GLuint, GLenum, GLboolean, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP2ui)(GLuint, GLenum, GLboolean, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP2uiv)(GLuint, GLenum, GLboolean, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP3ui)(GLuint, GLenum, GLboolean, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP3uiv)(GLuint, GLenum, GLboolean, const GLuint *) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4ui)(GLuint, GLenum, GLboolean, GLuint) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4uiv)(GLuint, GLenum, GLboolean, const GLuint *) = NULL; + +static int Load_Version_3_3() +{ + int numFailed = 0; + _ptrc_glBegin = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glBegin"); + if(!_ptrc_glBegin) numFailed++; + _ptrc_glEnd = (void (CODEGEN_FUNCPTR *)())IntGetProcAddress("glEnd"); + if(!_ptrc_glEnd) numFailed++; + _ptrc_glBlendFunc = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glBlendFunc"); + if(!_ptrc_glBlendFunc) numFailed++; + _ptrc_glClear = (void (CODEGEN_FUNCPTR *)(GLbitfield))IntGetProcAddress("glClear"); + if(!_ptrc_glClear) numFailed++; + _ptrc_glClearColor = (void (CODEGEN_FUNCPTR *)(GLfloat, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glClearColor"); + if(!_ptrc_glClearColor) numFailed++; + _ptrc_glClearDepth = (void (CODEGEN_FUNCPTR *)(GLdouble))IntGetProcAddress("glClearDepth"); + if(!_ptrc_glClearDepth) numFailed++; + _ptrc_glClearStencil = (void (CODEGEN_FUNCPTR *)(GLint))IntGetProcAddress("glClearStencil"); + if(!_ptrc_glClearStencil) numFailed++; + _ptrc_glColorMask = (void (CODEGEN_FUNCPTR *)(GLboolean, GLboolean, GLboolean, GLboolean))IntGetProcAddress("glColorMask"); + if(!_ptrc_glColorMask) numFailed++; + _ptrc_glCullFace = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glCullFace"); + if(!_ptrc_glCullFace) numFailed++; + _ptrc_glDepthFunc = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glDepthFunc"); + if(!_ptrc_glDepthFunc) numFailed++; + _ptrc_glDepthMask = (void (CODEGEN_FUNCPTR *)(GLboolean))IntGetProcAddress("glDepthMask"); + if(!_ptrc_glDepthMask) numFailed++; + _ptrc_glDepthRange = (void (CODEGEN_FUNCPTR *)(GLdouble, GLdouble))IntGetProcAddress("glDepthRange"); + if(!_ptrc_glDepthRange) numFailed++; + _ptrc_glDisable = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glDisable"); + if(!_ptrc_glDisable) numFailed++; + _ptrc_glDrawBuffer = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glDrawBuffer"); + if(!_ptrc_glDrawBuffer) numFailed++; + _ptrc_glEnable = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glEnable"); + if(!_ptrc_glEnable) numFailed++; + _ptrc_glFinish = (void (CODEGEN_FUNCPTR *)())IntGetProcAddress("glFinish"); + if(!_ptrc_glFinish) numFailed++; + _ptrc_glFlush = (void (CODEGEN_FUNCPTR *)())IntGetProcAddress("glFlush"); + if(!_ptrc_glFlush) numFailed++; + _ptrc_glFrontFace = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glFrontFace"); + if(!_ptrc_glFrontFace) numFailed++; + _ptrc_glGetBooleanv = (void (CODEGEN_FUNCPTR *)(GLenum, GLboolean *))IntGetProcAddress("glGetBooleanv"); + if(!_ptrc_glGetBooleanv) numFailed++; + _ptrc_glGetDoublev = (void (CODEGEN_FUNCPTR *)(GLenum, GLdouble *))IntGetProcAddress("glGetDoublev"); + if(!_ptrc_glGetDoublev) numFailed++; + _ptrc_glGetError = (GLenum (CODEGEN_FUNCPTR *)())IntGetProcAddress("glGetError"); + if(!_ptrc_glGetError) numFailed++; + _ptrc_glGetFloatv = (void (CODEGEN_FUNCPTR *)(GLenum, GLfloat *))IntGetProcAddress("glGetFloatv"); + if(!_ptrc_glGetFloatv) numFailed++; + _ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv"); + if(!_ptrc_glGetIntegerv) numFailed++; + _ptrc_glGetString = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glGetString"); + if(!_ptrc_glGetString) numFailed++; + _ptrc_glGetTexImage = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLenum, GLvoid *))IntGetProcAddress("glGetTexImage"); + if(!_ptrc_glGetTexImage) numFailed++; + _ptrc_glGetTexLevelParameterfv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLfloat *))IntGetProcAddress("glGetTexLevelParameterfv"); + if(!_ptrc_glGetTexLevelParameterfv) numFailed++; + _ptrc_glGetTexLevelParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLint *))IntGetProcAddress("glGetTexLevelParameteriv"); + if(!_ptrc_glGetTexLevelParameteriv) numFailed++; + _ptrc_glGetTexParameterfv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLfloat *))IntGetProcAddress("glGetTexParameterfv"); + if(!_ptrc_glGetTexParameterfv) numFailed++; + _ptrc_glGetTexParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *))IntGetProcAddress("glGetTexParameteriv"); + if(!_ptrc_glGetTexParameteriv) numFailed++; + _ptrc_glHint = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glHint"); + if(!_ptrc_glHint) numFailed++; + _ptrc_glIsEnabled = (GLboolean (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glIsEnabled"); + if(!_ptrc_glIsEnabled) numFailed++; + _ptrc_glLineWidth = (void (CODEGEN_FUNCPTR *)(GLfloat))IntGetProcAddress("glLineWidth"); + if(!_ptrc_glLineWidth) numFailed++; + _ptrc_glLogicOp = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glLogicOp"); + if(!_ptrc_glLogicOp) numFailed++; + _ptrc_glPixelStoref = (void (CODEGEN_FUNCPTR *)(GLenum, GLfloat))IntGetProcAddress("glPixelStoref"); + if(!_ptrc_glPixelStoref) numFailed++; + _ptrc_glPixelStorei = (void (CODEGEN_FUNCPTR *)(GLenum, GLint))IntGetProcAddress("glPixelStorei"); + if(!_ptrc_glPixelStorei) numFailed++; + _ptrc_glPointSize = (void (CODEGEN_FUNCPTR *)(GLfloat))IntGetProcAddress("glPointSize"); + if(!_ptrc_glPointSize) numFailed++; + _ptrc_glPolygonMode = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glPolygonMode"); + if(!_ptrc_glPolygonMode) numFailed++; + _ptrc_glReadBuffer = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glReadBuffer"); + if(!_ptrc_glReadBuffer) numFailed++; + _ptrc_glReadPixels = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *))IntGetProcAddress("glReadPixels"); + if(!_ptrc_glReadPixels) numFailed++; + _ptrc_glScissor = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glScissor"); + if(!_ptrc_glScissor) numFailed++; + _ptrc_glStencilFunc = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLuint))IntGetProcAddress("glStencilFunc"); + if(!_ptrc_glStencilFunc) numFailed++; + _ptrc_glStencilMask = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glStencilMask"); + if(!_ptrc_glStencilMask) numFailed++; + _ptrc_glStencilOp = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum))IntGetProcAddress("glStencilOp"); + if(!_ptrc_glStencilOp) numFailed++; + _ptrc_glTexImage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *))IntGetProcAddress("glTexImage1D"); + if(!_ptrc_glTexImage1D) numFailed++; + _ptrc_glTexImage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *))IntGetProcAddress("glTexImage2D"); + if(!_ptrc_glTexImage2D) numFailed++; + _ptrc_glTexParameterf = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLfloat))IntGetProcAddress("glTexParameterf"); + if(!_ptrc_glTexParameterf) numFailed++; + _ptrc_glTexParameterfv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, const GLfloat *))IntGetProcAddress("glTexParameterfv"); + if(!_ptrc_glTexParameterfv) numFailed++; + _ptrc_glTexParameteri = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint))IntGetProcAddress("glTexParameteri"); + if(!_ptrc_glTexParameteri) numFailed++; + _ptrc_glTexParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, const GLint *))IntGetProcAddress("glTexParameteriv"); + if(!_ptrc_glTexParameteriv) numFailed++; + _ptrc_glViewport = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glViewport"); + if(!_ptrc_glViewport) numFailed++; + _ptrc_glBindTexture = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glBindTexture"); + if(!_ptrc_glBindTexture) numFailed++; + _ptrc_glCopyTexImage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint))IntGetProcAddress("glCopyTexImage1D"); + if(!_ptrc_glCopyTexImage1D) numFailed++; + _ptrc_glCopyTexImage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint))IntGetProcAddress("glCopyTexImage2D"); + if(!_ptrc_glCopyTexImage2D) numFailed++; + _ptrc_glCopyTexSubImage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLint, GLsizei))IntGetProcAddress("glCopyTexSubImage1D"); + if(!_ptrc_glCopyTexSubImage1D) numFailed++; + _ptrc_glCopyTexSubImage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glCopyTexSubImage2D"); + if(!_ptrc_glCopyTexSubImage2D) numFailed++; + _ptrc_glDeleteTextures = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteTextures"); + if(!_ptrc_glDeleteTextures) numFailed++; + _ptrc_glDrawArrays = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLsizei))IntGetProcAddress("glDrawArrays"); + if(!_ptrc_glDrawArrays) numFailed++; + _ptrc_glDrawElements = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, const GLvoid *))IntGetProcAddress("glDrawElements"); + if(!_ptrc_glDrawElements) numFailed++; + _ptrc_glGenTextures = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenTextures"); + if(!_ptrc_glGenTextures) numFailed++; + _ptrc_glIsTexture = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsTexture"); + if(!_ptrc_glIsTexture) numFailed++; + _ptrc_glPolygonOffset = (void (CODEGEN_FUNCPTR *)(GLfloat, GLfloat))IntGetProcAddress("glPolygonOffset"); + if(!_ptrc_glPolygonOffset) numFailed++; + _ptrc_glTexSubImage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *))IntGetProcAddress("glTexSubImage1D"); + if(!_ptrc_glTexSubImage1D) numFailed++; + _ptrc_glTexSubImage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))IntGetProcAddress("glTexSubImage2D"); + if(!_ptrc_glTexSubImage2D) numFailed++; + _ptrc_glBlendColor = (void (CODEGEN_FUNCPTR *)(GLfloat, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glBlendColor"); + if(!_ptrc_glBlendColor) numFailed++; + _ptrc_glBlendEquation = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glBlendEquation"); + if(!_ptrc_glBlendEquation) numFailed++; + _ptrc_glCopyTexSubImage3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glCopyTexSubImage3D"); + if(!_ptrc_glCopyTexSubImage3D) numFailed++; + _ptrc_glDrawRangeElements = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *))IntGetProcAddress("glDrawRangeElements"); + if(!_ptrc_glDrawRangeElements) numFailed++; + _ptrc_glTexImage3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *))IntGetProcAddress("glTexImage3D"); + if(!_ptrc_glTexImage3D) numFailed++; + _ptrc_glTexSubImage3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))IntGetProcAddress("glTexSubImage3D"); + if(!_ptrc_glTexSubImage3D) numFailed++; + _ptrc_glActiveTexture = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glActiveTexture"); + if(!_ptrc_glActiveTexture) numFailed++; + _ptrc_glCompressedTexImage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexImage1D"); + if(!_ptrc_glCompressedTexImage1D) numFailed++; + _ptrc_glCompressedTexImage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexImage2D"); + if(!_ptrc_glCompressedTexImage2D) numFailed++; + _ptrc_glCompressedTexImage3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexImage3D"); + if(!_ptrc_glCompressedTexImage3D) numFailed++; + _ptrc_glCompressedTexSubImage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexSubImage1D"); + if(!_ptrc_glCompressedTexSubImage1D) numFailed++; + _ptrc_glCompressedTexSubImage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexSubImage2D"); + if(!_ptrc_glCompressedTexSubImage2D) numFailed++; + _ptrc_glCompressedTexSubImage3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glCompressedTexSubImage3D"); + if(!_ptrc_glCompressedTexSubImage3D) numFailed++; + _ptrc_glGetCompressedTexImage = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLvoid *))IntGetProcAddress("glGetCompressedTexImage"); + if(!_ptrc_glGetCompressedTexImage) numFailed++; + _ptrc_glSampleCoverage = (void (CODEGEN_FUNCPTR *)(GLfloat, GLboolean))IntGetProcAddress("glSampleCoverage"); + if(!_ptrc_glSampleCoverage) numFailed++; + _ptrc_glBlendFuncSeparate = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLenum))IntGetProcAddress("glBlendFuncSeparate"); + if(!_ptrc_glBlendFuncSeparate) numFailed++; + _ptrc_glMultiDrawArrays = (void (CODEGEN_FUNCPTR *)(GLenum, const GLint *, const GLsizei *, GLsizei))IntGetProcAddress("glMultiDrawArrays"); + if(!_ptrc_glMultiDrawArrays) numFailed++; + _ptrc_glMultiDrawElements = (void (CODEGEN_FUNCPTR *)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei))IntGetProcAddress("glMultiDrawElements"); + if(!_ptrc_glMultiDrawElements) numFailed++; + _ptrc_glPointParameterf = (void (CODEGEN_FUNCPTR *)(GLenum, GLfloat))IntGetProcAddress("glPointParameterf"); + if(!_ptrc_glPointParameterf) numFailed++; + _ptrc_glPointParameterfv = (void (CODEGEN_FUNCPTR *)(GLenum, const GLfloat *))IntGetProcAddress("glPointParameterfv"); + if(!_ptrc_glPointParameterfv) numFailed++; + _ptrc_glPointParameteri = (void (CODEGEN_FUNCPTR *)(GLenum, GLint))IntGetProcAddress("glPointParameteri"); + if(!_ptrc_glPointParameteri) numFailed++; + _ptrc_glPointParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, const GLint *))IntGetProcAddress("glPointParameteriv"); + if(!_ptrc_glPointParameteriv) numFailed++; + _ptrc_glBeginQuery = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glBeginQuery"); + if(!_ptrc_glBeginQuery) numFailed++; + _ptrc_glBindBuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glBindBuffer"); + if(!_ptrc_glBindBuffer) numFailed++; + _ptrc_glBufferData = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizeiptr, const GLvoid *, GLenum))IntGetProcAddress("glBufferData"); + if(!_ptrc_glBufferData) numFailed++; + _ptrc_glBufferSubData = (void (CODEGEN_FUNCPTR *)(GLenum, GLintptr, GLsizeiptr, const GLvoid *))IntGetProcAddress("glBufferSubData"); + if(!_ptrc_glBufferSubData) numFailed++; + _ptrc_glDeleteBuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteBuffers"); + if(!_ptrc_glDeleteBuffers) numFailed++; + _ptrc_glDeleteQueries = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteQueries"); + if(!_ptrc_glDeleteQueries) numFailed++; + _ptrc_glEndQuery = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glEndQuery"); + if(!_ptrc_glEndQuery) numFailed++; + _ptrc_glGenBuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenBuffers"); + if(!_ptrc_glGenBuffers) numFailed++; + _ptrc_glGenQueries = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenQueries"); + if(!_ptrc_glGenQueries) numFailed++; + _ptrc_glGetBufferParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *))IntGetProcAddress("glGetBufferParameteriv"); + if(!_ptrc_glGetBufferParameteriv) numFailed++; + _ptrc_glGetBufferPointerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLvoid **))IntGetProcAddress("glGetBufferPointerv"); + if(!_ptrc_glGetBufferPointerv) numFailed++; + _ptrc_glGetBufferSubData = (void (CODEGEN_FUNCPTR *)(GLenum, GLintptr, GLsizeiptr, GLvoid *))IntGetProcAddress("glGetBufferSubData"); + if(!_ptrc_glGetBufferSubData) numFailed++; + _ptrc_glGetQueryObjectiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetQueryObjectiv"); + if(!_ptrc_glGetQueryObjectiv) numFailed++; + _ptrc_glGetQueryObjectuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint *))IntGetProcAddress("glGetQueryObjectuiv"); + if(!_ptrc_glGetQueryObjectuiv) numFailed++; + _ptrc_glGetQueryiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *))IntGetProcAddress("glGetQueryiv"); + if(!_ptrc_glGetQueryiv) numFailed++; + _ptrc_glIsBuffer = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsBuffer"); + if(!_ptrc_glIsBuffer) numFailed++; + _ptrc_glIsQuery = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsQuery"); + if(!_ptrc_glIsQuery) numFailed++; + _ptrc_glMapBuffer = (void * (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glMapBuffer"); + if(!_ptrc_glMapBuffer) numFailed++; + _ptrc_glUnmapBuffer = (GLboolean (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glUnmapBuffer"); + if(!_ptrc_glUnmapBuffer) numFailed++; + _ptrc_glAttachShader = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glAttachShader"); + if(!_ptrc_glAttachShader) numFailed++; + _ptrc_glBindAttribLocation = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, const GLchar *))IntGetProcAddress("glBindAttribLocation"); + if(!_ptrc_glBindAttribLocation) numFailed++; + _ptrc_glBlendEquationSeparate = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glBlendEquationSeparate"); + if(!_ptrc_glBlendEquationSeparate) numFailed++; + _ptrc_glCompileShader = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glCompileShader"); + if(!_ptrc_glCompileShader) numFailed++; + _ptrc_glCreateProgram = (GLuint (CODEGEN_FUNCPTR *)())IntGetProcAddress("glCreateProgram"); + if(!_ptrc_glCreateProgram) numFailed++; + _ptrc_glCreateShader = (GLuint (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glCreateShader"); + if(!_ptrc_glCreateShader) numFailed++; + _ptrc_glDeleteProgram = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glDeleteProgram"); + if(!_ptrc_glDeleteProgram) numFailed++; + _ptrc_glDeleteShader = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glDeleteShader"); + if(!_ptrc_glDeleteShader) numFailed++; + _ptrc_glDetachShader = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glDetachShader"); + if(!_ptrc_glDetachShader) numFailed++; + _ptrc_glDisableVertexAttribArray = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glDisableVertexAttribArray"); + if(!_ptrc_glDisableVertexAttribArray) numFailed++; + _ptrc_glDrawBuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLenum *))IntGetProcAddress("glDrawBuffers"); + if(!_ptrc_glDrawBuffers) numFailed++; + _ptrc_glEnableVertexAttribArray = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glEnableVertexAttribArray"); + if(!_ptrc_glEnableVertexAttribArray) numFailed++; + _ptrc_glGetActiveAttrib = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *))IntGetProcAddress("glGetActiveAttrib"); + if(!_ptrc_glGetActiveAttrib) numFailed++; + _ptrc_glGetActiveUniform = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *))IntGetProcAddress("glGetActiveUniform"); + if(!_ptrc_glGetActiveUniform) numFailed++; + _ptrc_glGetAttachedShaders = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLsizei *, GLuint *))IntGetProcAddress("glGetAttachedShaders"); + if(!_ptrc_glGetAttachedShaders) numFailed++; + _ptrc_glGetAttribLocation = (GLint (CODEGEN_FUNCPTR *)(GLuint, const GLchar *))IntGetProcAddress("glGetAttribLocation"); + if(!_ptrc_glGetAttribLocation) numFailed++; + _ptrc_glGetProgramInfoLog = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetProgramInfoLog"); + if(!_ptrc_glGetProgramInfoLog) numFailed++; + _ptrc_glGetProgramiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetProgramiv"); + if(!_ptrc_glGetProgramiv) numFailed++; + _ptrc_glGetShaderInfoLog = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetShaderInfoLog"); + if(!_ptrc_glGetShaderInfoLog) numFailed++; + _ptrc_glGetShaderSource = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetShaderSource"); + if(!_ptrc_glGetShaderSource) numFailed++; + _ptrc_glGetShaderiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetShaderiv"); + if(!_ptrc_glGetShaderiv) numFailed++; + _ptrc_glGetUniformLocation = (GLint (CODEGEN_FUNCPTR *)(GLuint, const GLchar *))IntGetProcAddress("glGetUniformLocation"); + if(!_ptrc_glGetUniformLocation) numFailed++; + _ptrc_glGetUniformfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLfloat *))IntGetProcAddress("glGetUniformfv"); + if(!_ptrc_glGetUniformfv) numFailed++; + _ptrc_glGetUniformiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint *))IntGetProcAddress("glGetUniformiv"); + if(!_ptrc_glGetUniformiv) numFailed++; + _ptrc_glGetVertexAttribPointerv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLvoid **))IntGetProcAddress("glGetVertexAttribPointerv"); + if(!_ptrc_glGetVertexAttribPointerv) numFailed++; + _ptrc_glGetVertexAttribdv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLdouble *))IntGetProcAddress("glGetVertexAttribdv"); + if(!_ptrc_glGetVertexAttribdv) numFailed++; + _ptrc_glGetVertexAttribfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLfloat *))IntGetProcAddress("glGetVertexAttribfv"); + if(!_ptrc_glGetVertexAttribfv) numFailed++; + _ptrc_glGetVertexAttribiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetVertexAttribiv"); + if(!_ptrc_glGetVertexAttribiv) numFailed++; + _ptrc_glIsProgram = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsProgram"); + if(!_ptrc_glIsProgram) numFailed++; + _ptrc_glIsShader = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsShader"); + if(!_ptrc_glIsShader) numFailed++; + _ptrc_glLinkProgram = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glLinkProgram"); + if(!_ptrc_glLinkProgram) numFailed++; + _ptrc_glShaderSource = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLchar *const*, const GLint *))IntGetProcAddress("glShaderSource"); + if(!_ptrc_glShaderSource) numFailed++; + _ptrc_glStencilFuncSeparate = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint, GLuint))IntGetProcAddress("glStencilFuncSeparate"); + if(!_ptrc_glStencilFuncSeparate) numFailed++; + _ptrc_glStencilMaskSeparate = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glStencilMaskSeparate"); + if(!_ptrc_glStencilMaskSeparate) numFailed++; + _ptrc_glStencilOpSeparate = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLenum))IntGetProcAddress("glStencilOpSeparate"); + if(!_ptrc_glStencilOpSeparate) numFailed++; + _ptrc_glUniform1f = (void (CODEGEN_FUNCPTR *)(GLint, GLfloat))IntGetProcAddress("glUniform1f"); + if(!_ptrc_glUniform1f) numFailed++; + _ptrc_glUniform1fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLfloat *))IntGetProcAddress("glUniform1fv"); + if(!_ptrc_glUniform1fv) numFailed++; + _ptrc_glUniform1i = (void (CODEGEN_FUNCPTR *)(GLint, GLint))IntGetProcAddress("glUniform1i"); + if(!_ptrc_glUniform1i) numFailed++; + _ptrc_glUniform1iv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLint *))IntGetProcAddress("glUniform1iv"); + if(!_ptrc_glUniform1iv) numFailed++; + _ptrc_glUniform2f = (void (CODEGEN_FUNCPTR *)(GLint, GLfloat, GLfloat))IntGetProcAddress("glUniform2f"); + if(!_ptrc_glUniform2f) numFailed++; + _ptrc_glUniform2fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLfloat *))IntGetProcAddress("glUniform2fv"); + if(!_ptrc_glUniform2fv) numFailed++; + _ptrc_glUniform2i = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLint))IntGetProcAddress("glUniform2i"); + if(!_ptrc_glUniform2i) numFailed++; + _ptrc_glUniform2iv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLint *))IntGetProcAddress("glUniform2iv"); + if(!_ptrc_glUniform2iv) numFailed++; + _ptrc_glUniform3f = (void (CODEGEN_FUNCPTR *)(GLint, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glUniform3f"); + if(!_ptrc_glUniform3f) numFailed++; + _ptrc_glUniform3fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLfloat *))IntGetProcAddress("glUniform3fv"); + if(!_ptrc_glUniform3fv) numFailed++; + _ptrc_glUniform3i = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLint, GLint))IntGetProcAddress("glUniform3i"); + if(!_ptrc_glUniform3i) numFailed++; + _ptrc_glUniform3iv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLint *))IntGetProcAddress("glUniform3iv"); + if(!_ptrc_glUniform3iv) numFailed++; + _ptrc_glUniform4f = (void (CODEGEN_FUNCPTR *)(GLint, GLfloat, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glUniform4f"); + if(!_ptrc_glUniform4f) numFailed++; + _ptrc_glUniform4fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLfloat *))IntGetProcAddress("glUniform4fv"); + if(!_ptrc_glUniform4fv) numFailed++; + _ptrc_glUniform4i = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLint, GLint, GLint))IntGetProcAddress("glUniform4i"); + if(!_ptrc_glUniform4i) numFailed++; + _ptrc_glUniform4iv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLint *))IntGetProcAddress("glUniform4iv"); + if(!_ptrc_glUniform4iv) numFailed++; + _ptrc_glUniformMatrix2fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix2fv"); + if(!_ptrc_glUniformMatrix2fv) numFailed++; + _ptrc_glUniformMatrix3fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix3fv"); + if(!_ptrc_glUniformMatrix3fv) numFailed++; + _ptrc_glUniformMatrix4fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix4fv"); + if(!_ptrc_glUniformMatrix4fv) numFailed++; + _ptrc_glUseProgram = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glUseProgram"); + if(!_ptrc_glUseProgram) numFailed++; + _ptrc_glValidateProgram = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glValidateProgram"); + if(!_ptrc_glValidateProgram) numFailed++; + _ptrc_glVertexAttrib1d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble))IntGetProcAddress("glVertexAttrib1d"); + if(!_ptrc_glVertexAttrib1d) numFailed++; + _ptrc_glVertexAttrib1dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttrib1dv"); + if(!_ptrc_glVertexAttrib1dv) numFailed++; + _ptrc_glVertexAttrib1f = (void (CODEGEN_FUNCPTR *)(GLuint, GLfloat))IntGetProcAddress("glVertexAttrib1f"); + if(!_ptrc_glVertexAttrib1f) numFailed++; + _ptrc_glVertexAttrib1fv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLfloat *))IntGetProcAddress("glVertexAttrib1fv"); + if(!_ptrc_glVertexAttrib1fv) numFailed++; + _ptrc_glVertexAttrib1s = (void (CODEGEN_FUNCPTR *)(GLuint, GLshort))IntGetProcAddress("glVertexAttrib1s"); + if(!_ptrc_glVertexAttrib1s) numFailed++; + _ptrc_glVertexAttrib1sv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLshort *))IntGetProcAddress("glVertexAttrib1sv"); + if(!_ptrc_glVertexAttrib1sv) numFailed++; + _ptrc_glVertexAttrib2d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble))IntGetProcAddress("glVertexAttrib2d"); + if(!_ptrc_glVertexAttrib2d) numFailed++; + _ptrc_glVertexAttrib2dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttrib2dv"); + if(!_ptrc_glVertexAttrib2dv) numFailed++; + _ptrc_glVertexAttrib2f = (void (CODEGEN_FUNCPTR *)(GLuint, GLfloat, GLfloat))IntGetProcAddress("glVertexAttrib2f"); + if(!_ptrc_glVertexAttrib2f) numFailed++; + _ptrc_glVertexAttrib2fv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLfloat *))IntGetProcAddress("glVertexAttrib2fv"); + if(!_ptrc_glVertexAttrib2fv) numFailed++; + _ptrc_glVertexAttrib2s = (void (CODEGEN_FUNCPTR *)(GLuint, GLshort, GLshort))IntGetProcAddress("glVertexAttrib2s"); + if(!_ptrc_glVertexAttrib2s) numFailed++; + _ptrc_glVertexAttrib2sv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLshort *))IntGetProcAddress("glVertexAttrib2sv"); + if(!_ptrc_glVertexAttrib2sv) numFailed++; + _ptrc_glVertexAttrib3d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glVertexAttrib3d"); + if(!_ptrc_glVertexAttrib3d) numFailed++; + _ptrc_glVertexAttrib3dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttrib3dv"); + if(!_ptrc_glVertexAttrib3dv) numFailed++; + _ptrc_glVertexAttrib3f = (void (CODEGEN_FUNCPTR *)(GLuint, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glVertexAttrib3f"); + if(!_ptrc_glVertexAttrib3f) numFailed++; + _ptrc_glVertexAttrib3fv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLfloat *))IntGetProcAddress("glVertexAttrib3fv"); + if(!_ptrc_glVertexAttrib3fv) numFailed++; + _ptrc_glVertexAttrib3s = (void (CODEGEN_FUNCPTR *)(GLuint, GLshort, GLshort, GLshort))IntGetProcAddress("glVertexAttrib3s"); + if(!_ptrc_glVertexAttrib3s) numFailed++; + _ptrc_glVertexAttrib3sv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLshort *))IntGetProcAddress("glVertexAttrib3sv"); + if(!_ptrc_glVertexAttrib3sv) numFailed++; + _ptrc_glVertexAttrib4Nbv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLbyte *))IntGetProcAddress("glVertexAttrib4Nbv"); + if(!_ptrc_glVertexAttrib4Nbv) numFailed++; + _ptrc_glVertexAttrib4Niv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glVertexAttrib4Niv"); + if(!_ptrc_glVertexAttrib4Niv) numFailed++; + _ptrc_glVertexAttrib4Nsv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLshort *))IntGetProcAddress("glVertexAttrib4Nsv"); + if(!_ptrc_glVertexAttrib4Nsv) numFailed++; + _ptrc_glVertexAttrib4Nub = (void (CODEGEN_FUNCPTR *)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte))IntGetProcAddress("glVertexAttrib4Nub"); + if(!_ptrc_glVertexAttrib4Nub) numFailed++; + _ptrc_glVertexAttrib4Nubv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLubyte *))IntGetProcAddress("glVertexAttrib4Nubv"); + if(!_ptrc_glVertexAttrib4Nubv) numFailed++; + _ptrc_glVertexAttrib4Nuiv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLuint *))IntGetProcAddress("glVertexAttrib4Nuiv"); + if(!_ptrc_glVertexAttrib4Nuiv) numFailed++; + _ptrc_glVertexAttrib4Nusv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLushort *))IntGetProcAddress("glVertexAttrib4Nusv"); + if(!_ptrc_glVertexAttrib4Nusv) numFailed++; + _ptrc_glVertexAttrib4bv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLbyte *))IntGetProcAddress("glVertexAttrib4bv"); + if(!_ptrc_glVertexAttrib4bv) numFailed++; + _ptrc_glVertexAttrib4d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glVertexAttrib4d"); + if(!_ptrc_glVertexAttrib4d) numFailed++; + _ptrc_glVertexAttrib4dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttrib4dv"); + if(!_ptrc_glVertexAttrib4dv) numFailed++; + _ptrc_glVertexAttrib4f = (void (CODEGEN_FUNCPTR *)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glVertexAttrib4f"); + if(!_ptrc_glVertexAttrib4f) numFailed++; + _ptrc_glVertexAttrib4fv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLfloat *))IntGetProcAddress("glVertexAttrib4fv"); + if(!_ptrc_glVertexAttrib4fv) numFailed++; + _ptrc_glVertexAttrib4iv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glVertexAttrib4iv"); + if(!_ptrc_glVertexAttrib4iv) numFailed++; + _ptrc_glVertexAttrib4s = (void (CODEGEN_FUNCPTR *)(GLuint, GLshort, GLshort, GLshort, GLshort))IntGetProcAddress("glVertexAttrib4s"); + if(!_ptrc_glVertexAttrib4s) numFailed++; + _ptrc_glVertexAttrib4sv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLshort *))IntGetProcAddress("glVertexAttrib4sv"); + if(!_ptrc_glVertexAttrib4sv) numFailed++; + _ptrc_glVertexAttrib4ubv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLubyte *))IntGetProcAddress("glVertexAttrib4ubv"); + if(!_ptrc_glVertexAttrib4ubv) numFailed++; + _ptrc_glVertexAttrib4uiv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLuint *))IntGetProcAddress("glVertexAttrib4uiv"); + if(!_ptrc_glVertexAttrib4uiv) numFailed++; + _ptrc_glVertexAttrib4usv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLushort *))IntGetProcAddress("glVertexAttrib4usv"); + if(!_ptrc_glVertexAttrib4usv) numFailed++; + _ptrc_glVertexAttribPointer = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *))IntGetProcAddress("glVertexAttribPointer"); + if(!_ptrc_glVertexAttribPointer) numFailed++; + _ptrc_glUniformMatrix2x3fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix2x3fv"); + if(!_ptrc_glUniformMatrix2x3fv) numFailed++; + _ptrc_glUniformMatrix2x4fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix2x4fv"); + if(!_ptrc_glUniformMatrix2x4fv) numFailed++; + _ptrc_glUniformMatrix3x2fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix3x2fv"); + if(!_ptrc_glUniformMatrix3x2fv) numFailed++; + _ptrc_glUniformMatrix3x4fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix3x4fv"); + if(!_ptrc_glUniformMatrix3x4fv) numFailed++; + _ptrc_glUniformMatrix4x2fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix4x2fv"); + if(!_ptrc_glUniformMatrix4x2fv) numFailed++; + _ptrc_glUniformMatrix4x3fv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glUniformMatrix4x3fv"); + if(!_ptrc_glUniformMatrix4x3fv) numFailed++; + _ptrc_glBeginConditionalRender = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glBeginConditionalRender"); + if(!_ptrc_glBeginConditionalRender) numFailed++; + _ptrc_glBeginTransformFeedback = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glBeginTransformFeedback"); + if(!_ptrc_glBeginTransformFeedback) numFailed++; + _ptrc_glBindBufferBase = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint))IntGetProcAddress("glBindBufferBase"); + if(!_ptrc_glBindBufferBase) numFailed++; + _ptrc_glBindBufferRange = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glBindBufferRange"); + if(!_ptrc_glBindBufferRange) numFailed++; + _ptrc_glBindFragDataLocation = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, const GLchar *))IntGetProcAddress("glBindFragDataLocation"); + if(!_ptrc_glBindFragDataLocation) numFailed++; + _ptrc_glBindFramebuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glBindFramebuffer"); + if(!_ptrc_glBindFramebuffer) numFailed++; + _ptrc_glBindRenderbuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glBindRenderbuffer"); + if(!_ptrc_glBindRenderbuffer) numFailed++; + _ptrc_glBindVertexArray = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glBindVertexArray"); + if(!_ptrc_glBindVertexArray) numFailed++; + _ptrc_glBlitFramebuffer = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum))IntGetProcAddress("glBlitFramebuffer"); + if(!_ptrc_glBlitFramebuffer) numFailed++; + _ptrc_glCheckFramebufferStatus = (GLenum (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glCheckFramebufferStatus"); + if(!_ptrc_glCheckFramebufferStatus) numFailed++; + _ptrc_glClampColor = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glClampColor"); + if(!_ptrc_glClampColor) numFailed++; + _ptrc_glClearBufferfi = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLfloat, GLint))IntGetProcAddress("glClearBufferfi"); + if(!_ptrc_glClearBufferfi) numFailed++; + _ptrc_glClearBufferfv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, const GLfloat *))IntGetProcAddress("glClearBufferfv"); + if(!_ptrc_glClearBufferfv) numFailed++; + _ptrc_glClearBufferiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, const GLint *))IntGetProcAddress("glClearBufferiv"); + if(!_ptrc_glClearBufferiv) numFailed++; + _ptrc_glClearBufferuiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, const GLuint *))IntGetProcAddress("glClearBufferuiv"); + if(!_ptrc_glClearBufferuiv) numFailed++; + _ptrc_glColorMaski = (void (CODEGEN_FUNCPTR *)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean))IntGetProcAddress("glColorMaski"); + if(!_ptrc_glColorMaski) numFailed++; + _ptrc_glDeleteFramebuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteFramebuffers"); + if(!_ptrc_glDeleteFramebuffers) numFailed++; + _ptrc_glDeleteRenderbuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteRenderbuffers"); + if(!_ptrc_glDeleteRenderbuffers) numFailed++; + _ptrc_glDeleteVertexArrays = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteVertexArrays"); + if(!_ptrc_glDeleteVertexArrays) numFailed++; + _ptrc_glDisablei = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glDisablei"); + if(!_ptrc_glDisablei) numFailed++; + _ptrc_glEnablei = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glEnablei"); + if(!_ptrc_glEnablei) numFailed++; + _ptrc_glEndConditionalRender = (void (CODEGEN_FUNCPTR *)())IntGetProcAddress("glEndConditionalRender"); + if(!_ptrc_glEndConditionalRender) numFailed++; + _ptrc_glEndTransformFeedback = (void (CODEGEN_FUNCPTR *)())IntGetProcAddress("glEndTransformFeedback"); + if(!_ptrc_glEndTransformFeedback) numFailed++; + _ptrc_glFlushMappedBufferRange = (void (CODEGEN_FUNCPTR *)(GLenum, GLintptr, GLsizeiptr))IntGetProcAddress("glFlushMappedBufferRange"); + if(!_ptrc_glFlushMappedBufferRange) numFailed++; + _ptrc_glFramebufferRenderbuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLuint))IntGetProcAddress("glFramebufferRenderbuffer"); + if(!_ptrc_glFramebufferRenderbuffer) numFailed++; + _ptrc_glFramebufferTexture1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLuint, GLint))IntGetProcAddress("glFramebufferTexture1D"); + if(!_ptrc_glFramebufferTexture1D) numFailed++; + _ptrc_glFramebufferTexture2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLuint, GLint))IntGetProcAddress("glFramebufferTexture2D"); + if(!_ptrc_glFramebufferTexture2D) numFailed++; + _ptrc_glFramebufferTexture3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLuint, GLint, GLint))IntGetProcAddress("glFramebufferTexture3D"); + if(!_ptrc_glFramebufferTexture3D) numFailed++; + _ptrc_glFramebufferTextureLayer = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint, GLint, GLint))IntGetProcAddress("glFramebufferTextureLayer"); + if(!_ptrc_glFramebufferTextureLayer) numFailed++; + _ptrc_glGenFramebuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenFramebuffers"); + if(!_ptrc_glGenFramebuffers) numFailed++; + _ptrc_glGenRenderbuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenRenderbuffers"); + if(!_ptrc_glGenRenderbuffers) numFailed++; + _ptrc_glGenVertexArrays = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenVertexArrays"); + if(!_ptrc_glGenVertexArrays) numFailed++; + _ptrc_glGenerateMipmap = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glGenerateMipmap"); + if(!_ptrc_glGenerateMipmap) numFailed++; + _ptrc_glGetBooleani_v = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLboolean *))IntGetProcAddress("glGetBooleani_v"); + if(!_ptrc_glGetBooleani_v) numFailed++; + _ptrc_glGetFragDataLocation = (GLint (CODEGEN_FUNCPTR *)(GLuint, const GLchar *))IntGetProcAddress("glGetFragDataLocation"); + if(!_ptrc_glGetFragDataLocation) numFailed++; + _ptrc_glGetFramebufferAttachmentParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLint *))IntGetProcAddress("glGetFramebufferAttachmentParameteriv"); + if(!_ptrc_glGetFramebufferAttachmentParameteriv) numFailed++; + _ptrc_glGetIntegeri_v = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLint *))IntGetProcAddress("glGetIntegeri_v"); + if(!_ptrc_glGetIntegeri_v) numFailed++; + _ptrc_glGetRenderbufferParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *))IntGetProcAddress("glGetRenderbufferParameteriv"); + if(!_ptrc_glGetRenderbufferParameteriv) numFailed++; + _ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi"); + if(!_ptrc_glGetStringi) numFailed++; + _ptrc_glGetTexParameterIiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *))IntGetProcAddress("glGetTexParameterIiv"); + if(!_ptrc_glGetTexParameterIiv) numFailed++; + _ptrc_glGetTexParameterIuiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint *))IntGetProcAddress("glGetTexParameterIuiv"); + if(!_ptrc_glGetTexParameterIuiv) numFailed++; + _ptrc_glGetTransformFeedbackVarying = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *))IntGetProcAddress("glGetTransformFeedbackVarying"); + if(!_ptrc_glGetTransformFeedbackVarying) numFailed++; + _ptrc_glGetUniformuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLuint *))IntGetProcAddress("glGetUniformuiv"); + if(!_ptrc_glGetUniformuiv) numFailed++; + _ptrc_glGetVertexAttribIiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetVertexAttribIiv"); + if(!_ptrc_glGetVertexAttribIiv) numFailed++; + _ptrc_glGetVertexAttribIuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint *))IntGetProcAddress("glGetVertexAttribIuiv"); + if(!_ptrc_glGetVertexAttribIuiv) numFailed++; + _ptrc_glIsEnabledi = (GLboolean (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glIsEnabledi"); + if(!_ptrc_glIsEnabledi) numFailed++; + _ptrc_glIsFramebuffer = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsFramebuffer"); + if(!_ptrc_glIsFramebuffer) numFailed++; + _ptrc_glIsRenderbuffer = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsRenderbuffer"); + if(!_ptrc_glIsRenderbuffer) numFailed++; + _ptrc_glIsVertexArray = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsVertexArray"); + if(!_ptrc_glIsVertexArray) numFailed++; + _ptrc_glMapBufferRange = (void * (CODEGEN_FUNCPTR *)(GLenum, GLintptr, GLsizeiptr, GLbitfield))IntGetProcAddress("glMapBufferRange"); + if(!_ptrc_glMapBufferRange) numFailed++; + _ptrc_glRenderbufferStorage = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLsizei, GLsizei))IntGetProcAddress("glRenderbufferStorage"); + if(!_ptrc_glRenderbufferStorage) numFailed++; + _ptrc_glRenderbufferStorageMultisample = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei, GLsizei))IntGetProcAddress("glRenderbufferStorageMultisample"); + if(!_ptrc_glRenderbufferStorageMultisample) numFailed++; + _ptrc_glTexParameterIiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, const GLint *))IntGetProcAddress("glTexParameterIiv"); + if(!_ptrc_glTexParameterIiv) numFailed++; + _ptrc_glTexParameterIuiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, const GLuint *))IntGetProcAddress("glTexParameterIuiv"); + if(!_ptrc_glTexParameterIuiv) numFailed++; + _ptrc_glTransformFeedbackVaryings = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLchar *const*, GLenum))IntGetProcAddress("glTransformFeedbackVaryings"); + if(!_ptrc_glTransformFeedbackVaryings) numFailed++; + _ptrc_glUniform1ui = (void (CODEGEN_FUNCPTR *)(GLint, GLuint))IntGetProcAddress("glUniform1ui"); + if(!_ptrc_glUniform1ui) numFailed++; + _ptrc_glUniform1uiv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLuint *))IntGetProcAddress("glUniform1uiv"); + if(!_ptrc_glUniform1uiv) numFailed++; + _ptrc_glUniform2ui = (void (CODEGEN_FUNCPTR *)(GLint, GLuint, GLuint))IntGetProcAddress("glUniform2ui"); + if(!_ptrc_glUniform2ui) numFailed++; + _ptrc_glUniform2uiv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLuint *))IntGetProcAddress("glUniform2uiv"); + if(!_ptrc_glUniform2uiv) numFailed++; + _ptrc_glUniform3ui = (void (CODEGEN_FUNCPTR *)(GLint, GLuint, GLuint, GLuint))IntGetProcAddress("glUniform3ui"); + if(!_ptrc_glUniform3ui) numFailed++; + _ptrc_glUniform3uiv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLuint *))IntGetProcAddress("glUniform3uiv"); + if(!_ptrc_glUniform3uiv) numFailed++; + _ptrc_glUniform4ui = (void (CODEGEN_FUNCPTR *)(GLint, GLuint, GLuint, GLuint, GLuint))IntGetProcAddress("glUniform4ui"); + if(!_ptrc_glUniform4ui) numFailed++; + _ptrc_glUniform4uiv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLuint *))IntGetProcAddress("glUniform4uiv"); + if(!_ptrc_glUniform4uiv) numFailed++; + _ptrc_glVertexAttribI1i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint))IntGetProcAddress("glVertexAttribI1i"); + if(!_ptrc_glVertexAttribI1i) numFailed++; + _ptrc_glVertexAttribI1iv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glVertexAttribI1iv"); + if(!_ptrc_glVertexAttribI1iv) numFailed++; + _ptrc_glVertexAttribI1ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glVertexAttribI1ui"); + if(!_ptrc_glVertexAttribI1ui) numFailed++; + _ptrc_glVertexAttribI1uiv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLuint *))IntGetProcAddress("glVertexAttribI1uiv"); + if(!_ptrc_glVertexAttribI1uiv) numFailed++; + _ptrc_glVertexAttribI2i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint))IntGetProcAddress("glVertexAttribI2i"); + if(!_ptrc_glVertexAttribI2i) numFailed++; + _ptrc_glVertexAttribI2iv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glVertexAttribI2iv"); + if(!_ptrc_glVertexAttribI2iv) numFailed++; + _ptrc_glVertexAttribI2ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glVertexAttribI2ui"); + if(!_ptrc_glVertexAttribI2ui) numFailed++; + _ptrc_glVertexAttribI2uiv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLuint *))IntGetProcAddress("glVertexAttribI2uiv"); + if(!_ptrc_glVertexAttribI2uiv) numFailed++; + _ptrc_glVertexAttribI3i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint))IntGetProcAddress("glVertexAttribI3i"); + if(!_ptrc_glVertexAttribI3i) numFailed++; + _ptrc_glVertexAttribI3iv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glVertexAttribI3iv"); + if(!_ptrc_glVertexAttribI3iv) numFailed++; + _ptrc_glVertexAttribI3ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint, GLuint))IntGetProcAddress("glVertexAttribI3ui"); + if(!_ptrc_glVertexAttribI3ui) numFailed++; + _ptrc_glVertexAttribI3uiv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLuint *))IntGetProcAddress("glVertexAttribI3uiv"); + if(!_ptrc_glVertexAttribI3uiv) numFailed++; + _ptrc_glVertexAttribI4bv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLbyte *))IntGetProcAddress("glVertexAttribI4bv"); + if(!_ptrc_glVertexAttribI4bv) numFailed++; + _ptrc_glVertexAttribI4i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint))IntGetProcAddress("glVertexAttribI4i"); + if(!_ptrc_glVertexAttribI4i) numFailed++; + _ptrc_glVertexAttribI4iv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glVertexAttribI4iv"); + if(!_ptrc_glVertexAttribI4iv) numFailed++; + _ptrc_glVertexAttribI4sv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLshort *))IntGetProcAddress("glVertexAttribI4sv"); + if(!_ptrc_glVertexAttribI4sv) numFailed++; + _ptrc_glVertexAttribI4ubv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLubyte *))IntGetProcAddress("glVertexAttribI4ubv"); + if(!_ptrc_glVertexAttribI4ubv) numFailed++; + _ptrc_glVertexAttribI4ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint, GLuint, GLuint))IntGetProcAddress("glVertexAttribI4ui"); + if(!_ptrc_glVertexAttribI4ui) numFailed++; + _ptrc_glVertexAttribI4uiv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLuint *))IntGetProcAddress("glVertexAttribI4uiv"); + if(!_ptrc_glVertexAttribI4uiv) numFailed++; + _ptrc_glVertexAttribI4usv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLushort *))IntGetProcAddress("glVertexAttribI4usv"); + if(!_ptrc_glVertexAttribI4usv) numFailed++; + _ptrc_glVertexAttribIPointer = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLsizei, const GLvoid *))IntGetProcAddress("glVertexAttribIPointer"); + if(!_ptrc_glVertexAttribIPointer) numFailed++; + _ptrc_glCopyBufferSubData = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr))IntGetProcAddress("glCopyBufferSubData"); + if(!_ptrc_glCopyBufferSubData) numFailed++; + _ptrc_glDrawArraysInstanced = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLsizei, GLsizei))IntGetProcAddress("glDrawArraysInstanced"); + if(!_ptrc_glDrawArraysInstanced) numFailed++; + _ptrc_glDrawElementsInstanced = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei))IntGetProcAddress("glDrawElementsInstanced"); + if(!_ptrc_glDrawElementsInstanced) numFailed++; + _ptrc_glGetActiveUniformBlockName = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetActiveUniformBlockName"); + if(!_ptrc_glGetActiveUniformBlockName) numFailed++; + _ptrc_glGetActiveUniformBlockiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLint *))IntGetProcAddress("glGetActiveUniformBlockiv"); + if(!_ptrc_glGetActiveUniformBlockiv) numFailed++; + _ptrc_glGetActiveUniformName = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetActiveUniformName"); + if(!_ptrc_glGetActiveUniformName) numFailed++; + _ptrc_glGetActiveUniformsiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLuint *, GLenum, GLint *))IntGetProcAddress("glGetActiveUniformsiv"); + if(!_ptrc_glGetActiveUniformsiv) numFailed++; + _ptrc_glGetUniformBlockIndex = (GLuint (CODEGEN_FUNCPTR *)(GLuint, const GLchar *))IntGetProcAddress("glGetUniformBlockIndex"); + if(!_ptrc_glGetUniformBlockIndex) numFailed++; + _ptrc_glGetUniformIndices = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLchar *const*, GLuint *))IntGetProcAddress("glGetUniformIndices"); + if(!_ptrc_glGetUniformIndices) numFailed++; + _ptrc_glPrimitiveRestartIndex = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glPrimitiveRestartIndex"); + if(!_ptrc_glPrimitiveRestartIndex) numFailed++; + _ptrc_glTexBuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint))IntGetProcAddress("glTexBuffer"); + if(!_ptrc_glTexBuffer) numFailed++; + _ptrc_glUniformBlockBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glUniformBlockBinding"); + if(!_ptrc_glUniformBlockBinding) numFailed++; + _ptrc_glClientWaitSync = (GLenum (CODEGEN_FUNCPTR *)(GLsync, GLbitfield, GLuint64))IntGetProcAddress("glClientWaitSync"); + if(!_ptrc_glClientWaitSync) numFailed++; + _ptrc_glDeleteSync = (void (CODEGEN_FUNCPTR *)(GLsync))IntGetProcAddress("glDeleteSync"); + if(!_ptrc_glDeleteSync) numFailed++; + _ptrc_glDrawElementsBaseVertex = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, const GLvoid *, GLint))IntGetProcAddress("glDrawElementsBaseVertex"); + if(!_ptrc_glDrawElementsBaseVertex) numFailed++; + _ptrc_glDrawElementsInstancedBaseVertex = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei, GLint))IntGetProcAddress("glDrawElementsInstancedBaseVertex"); + if(!_ptrc_glDrawElementsInstancedBaseVertex) numFailed++; + _ptrc_glDrawRangeElementsBaseVertex = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint))IntGetProcAddress("glDrawRangeElementsBaseVertex"); + if(!_ptrc_glDrawRangeElementsBaseVertex) numFailed++; + _ptrc_glFenceSync = (GLsync (CODEGEN_FUNCPTR *)(GLenum, GLbitfield))IntGetProcAddress("glFenceSync"); + if(!_ptrc_glFenceSync) numFailed++; + _ptrc_glFramebufferTexture = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint, GLint))IntGetProcAddress("glFramebufferTexture"); + if(!_ptrc_glFramebufferTexture) numFailed++; + _ptrc_glGetBufferParameteri64v = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint64 *))IntGetProcAddress("glGetBufferParameteri64v"); + if(!_ptrc_glGetBufferParameteri64v) numFailed++; + _ptrc_glGetInteger64i_v = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLint64 *))IntGetProcAddress("glGetInteger64i_v"); + if(!_ptrc_glGetInteger64i_v) numFailed++; + _ptrc_glGetInteger64v = (void (CODEGEN_FUNCPTR *)(GLenum, GLint64 *))IntGetProcAddress("glGetInteger64v"); + if(!_ptrc_glGetInteger64v) numFailed++; + _ptrc_glGetMultisamplefv = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLfloat *))IntGetProcAddress("glGetMultisamplefv"); + if(!_ptrc_glGetMultisamplefv) numFailed++; + _ptrc_glGetSynciv = (void (CODEGEN_FUNCPTR *)(GLsync, GLenum, GLsizei, GLsizei *, GLint *))IntGetProcAddress("glGetSynciv"); + if(!_ptrc_glGetSynciv) numFailed++; + _ptrc_glIsSync = (GLboolean (CODEGEN_FUNCPTR *)(GLsync))IntGetProcAddress("glIsSync"); + if(!_ptrc_glIsSync) numFailed++; + _ptrc_glMultiDrawElementsBaseVertex = (void (CODEGEN_FUNCPTR *)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *))IntGetProcAddress("glMultiDrawElementsBaseVertex"); + if(!_ptrc_glMultiDrawElementsBaseVertex) numFailed++; + _ptrc_glProvokingVertex = (void (CODEGEN_FUNCPTR *)(GLenum))IntGetProcAddress("glProvokingVertex"); + if(!_ptrc_glProvokingVertex) numFailed++; + _ptrc_glSampleMaski = (void (CODEGEN_FUNCPTR *)(GLuint, GLbitfield))IntGetProcAddress("glSampleMaski"); + if(!_ptrc_glSampleMaski) numFailed++; + _ptrc_glTexImage2DMultisample = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean))IntGetProcAddress("glTexImage2DMultisample"); + if(!_ptrc_glTexImage2DMultisample) numFailed++; + _ptrc_glTexImage3DMultisample = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean))IntGetProcAddress("glTexImage3DMultisample"); + if(!_ptrc_glTexImage3DMultisample) numFailed++; + _ptrc_glWaitSync = (void (CODEGEN_FUNCPTR *)(GLsync, GLbitfield, GLuint64))IntGetProcAddress("glWaitSync"); + if(!_ptrc_glWaitSync) numFailed++; + _ptrc_glBindFragDataLocationIndexed = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint, const GLchar *))IntGetProcAddress("glBindFragDataLocationIndexed"); + if(!_ptrc_glBindFragDataLocationIndexed) numFailed++; + _ptrc_glBindSampler = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glBindSampler"); + if(!_ptrc_glBindSampler) numFailed++; + _ptrc_glDeleteSamplers = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteSamplers"); + if(!_ptrc_glDeleteSamplers) numFailed++; + _ptrc_glGenSamplers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenSamplers"); + if(!_ptrc_glGenSamplers) numFailed++; + _ptrc_glGetFragDataIndex = (GLint (CODEGEN_FUNCPTR *)(GLuint, const GLchar *))IntGetProcAddress("glGetFragDataIndex"); + if(!_ptrc_glGetFragDataIndex) numFailed++; + _ptrc_glGetQueryObjecti64v = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint64 *))IntGetProcAddress("glGetQueryObjecti64v"); + if(!_ptrc_glGetQueryObjecti64v) numFailed++; + _ptrc_glGetQueryObjectui64v = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint64 *))IntGetProcAddress("glGetQueryObjectui64v"); + if(!_ptrc_glGetQueryObjectui64v) numFailed++; + _ptrc_glGetSamplerParameterIiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetSamplerParameterIiv"); + if(!_ptrc_glGetSamplerParameterIiv) numFailed++; + _ptrc_glGetSamplerParameterIuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint *))IntGetProcAddress("glGetSamplerParameterIuiv"); + if(!_ptrc_glGetSamplerParameterIuiv) numFailed++; + _ptrc_glGetSamplerParameterfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLfloat *))IntGetProcAddress("glGetSamplerParameterfv"); + if(!_ptrc_glGetSamplerParameterfv) numFailed++; + _ptrc_glGetSamplerParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetSamplerParameteriv"); + if(!_ptrc_glGetSamplerParameteriv) numFailed++; + _ptrc_glIsSampler = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsSampler"); + if(!_ptrc_glIsSampler) numFailed++; + _ptrc_glQueryCounter = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glQueryCounter"); + if(!_ptrc_glQueryCounter) numFailed++; + _ptrc_glSamplerParameterIiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLint *))IntGetProcAddress("glSamplerParameterIiv"); + if(!_ptrc_glSamplerParameterIiv) numFailed++; + _ptrc_glSamplerParameterIuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLuint *))IntGetProcAddress("glSamplerParameterIuiv"); + if(!_ptrc_glSamplerParameterIuiv) numFailed++; + _ptrc_glSamplerParameterf = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLfloat))IntGetProcAddress("glSamplerParameterf"); + if(!_ptrc_glSamplerParameterf) numFailed++; + _ptrc_glSamplerParameterfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLfloat *))IntGetProcAddress("glSamplerParameterfv"); + if(!_ptrc_glSamplerParameterfv) numFailed++; + _ptrc_glSamplerParameteri = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint))IntGetProcAddress("glSamplerParameteri"); + if(!_ptrc_glSamplerParameteri) numFailed++; + _ptrc_glSamplerParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLint *))IntGetProcAddress("glSamplerParameteriv"); + if(!_ptrc_glSamplerParameteriv) numFailed++; + _ptrc_glVertexAttribDivisor = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glVertexAttribDivisor"); + if(!_ptrc_glVertexAttribDivisor) numFailed++; + _ptrc_glVertexAttribP1ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, GLuint))IntGetProcAddress("glVertexAttribP1ui"); + if(!_ptrc_glVertexAttribP1ui) numFailed++; + _ptrc_glVertexAttribP1uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, const GLuint *))IntGetProcAddress("glVertexAttribP1uiv"); + if(!_ptrc_glVertexAttribP1uiv) numFailed++; + _ptrc_glVertexAttribP2ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, GLuint))IntGetProcAddress("glVertexAttribP2ui"); + if(!_ptrc_glVertexAttribP2ui) numFailed++; + _ptrc_glVertexAttribP2uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, const GLuint *))IntGetProcAddress("glVertexAttribP2uiv"); + if(!_ptrc_glVertexAttribP2uiv) numFailed++; + _ptrc_glVertexAttribP3ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, GLuint))IntGetProcAddress("glVertexAttribP3ui"); + if(!_ptrc_glVertexAttribP3ui) numFailed++; + _ptrc_glVertexAttribP3uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, const GLuint *))IntGetProcAddress("glVertexAttribP3uiv"); + if(!_ptrc_glVertexAttribP3uiv) numFailed++; + _ptrc_glVertexAttribP4ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, GLuint))IntGetProcAddress("glVertexAttribP4ui"); + if(!_ptrc_glVertexAttribP4ui) numFailed++; + _ptrc_glVertexAttribP4uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, const GLuint *))IntGetProcAddress("glVertexAttribP4uiv"); + if(!_ptrc_glVertexAttribP4uiv) numFailed++; + return numFailed; +} + +typedef int (*PFN_LOADFUNCPOINTERS)(); +typedef struct ogl_StrToExtMap_s +{ + char *extensionName; + int *extensionVariable; + PFN_LOADFUNCPOINTERS LoadExtension; +} ogl_StrToExtMap; + +static ogl_StrToExtMap ExtensionMap[6] = { + {"GL_ARB_texture_compression", &ogl_ext_ARB_texture_compression, Load_ARB_texture_compression}, + {"GL_EXT_texture_compression_s3tc", &ogl_ext_EXT_texture_compression_s3tc, NULL}, + {"GL_ARB_buffer_storage", &ogl_ext_ARB_buffer_storage, Load_ARB_buffer_storage}, + {"GL_ARB_shader_storage_buffer_object", &ogl_ext_ARB_shader_storage_buffer_object, Load_ARB_shader_storage_buffer_object}, + {"GL_EXT_texture_sRGB", &ogl_ext_EXT_texture_sRGB, NULL}, + {"GL_EXT_texture_filter_anisotropic", &ogl_ext_EXT_texture_filter_anisotropic, NULL}, +}; + +static int g_extensionMapSize = 6; + +static ogl_StrToExtMap *FindExtEntry(const char *extensionName) +{ + int loop; + ogl_StrToExtMap *currLoc = ExtensionMap; + for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc) + { + if(strcmp(extensionName, currLoc->extensionName) == 0) + return currLoc; + } + + return NULL; +} + +static void ClearExtensionVars() +{ + ogl_ext_ARB_texture_compression = ogl_LOAD_FAILED; + ogl_ext_EXT_texture_compression_s3tc = ogl_LOAD_FAILED; + ogl_ext_ARB_buffer_storage = ogl_LOAD_FAILED; + ogl_ext_ARB_shader_storage_buffer_object = ogl_LOAD_FAILED; + ogl_ext_EXT_texture_sRGB = ogl_LOAD_FAILED; + ogl_ext_EXT_texture_filter_anisotropic = ogl_LOAD_FAILED; +} + + +static void LoadExtByName(const char *extensionName) +{ + ogl_StrToExtMap *entry = NULL; + entry = FindExtEntry(extensionName); + if(entry) + { + if(entry->LoadExtension) + { + int numFailed = entry->LoadExtension(); + if(numFailed == 0) + { + *(entry->extensionVariable) = ogl_LOAD_SUCCEEDED; + } + else + { + *(entry->extensionVariable) = ogl_LOAD_SUCCEEDED + numFailed; + } + } + else + { + *(entry->extensionVariable) = ogl_LOAD_SUCCEEDED; + } + } +} + + +static void ProcExtsFromExtList() +{ + GLint iLoop; + GLint iNumExtensions = 0; + _ptrc_glGetIntegerv(GL_NUM_EXTENSIONS, &iNumExtensions); + + for(iLoop = 0; iLoop < iNumExtensions; iLoop++) + { + const char *strExtensionName = (const char *)_ptrc_glGetStringi(GL_EXTENSIONS, iLoop); + LoadExtByName(strExtensionName); + } +} + +int ogl_LoadFunctions() +{ + int numFailed = 0; + ClearExtensionVars(); + + _ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv"); + if(!_ptrc_glGetIntegerv) return ogl_LOAD_FAILED; + _ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi"); + if(!_ptrc_glGetStringi) return ogl_LOAD_FAILED; + + ProcExtsFromExtList(); + numFailed = Load_Version_3_3(); + + if(numFailed == 0) + return ogl_LOAD_SUCCEEDED; + else + return ogl_LOAD_SUCCEEDED + numFailed; +} + +static int g_major_version = 0; +static int g_minor_version = 0; + +static void GetGLVersion() +{ + glGetIntegerv(GL_MAJOR_VERSION, &g_major_version); + glGetIntegerv(GL_MINOR_VERSION, &g_minor_version); +} + +int ogl_GetMajorVersion() +{ + if(g_major_version == 0) + GetGLVersion(); + return g_major_version; +} + +int ogl_GetMinorVersion() +{ + if(g_major_version == 0) //Yes, check the major version to get the minor one. + GetGLVersion(); + return g_minor_version; +} + +int ogl_IsVersionGEQ(int majorVersion, int minorVersion) +{ + if(g_major_version == 0) + GetGLVersion(); + + if(majorVersion > g_major_version) return 1; + if(majorVersion < g_major_version) return 0; + if(minorVersion >= g_minor_version) return 1; + return 0; +} + diff --git a/src/gl/system/gl_load.h b/src/gl/system/gl_load.h new file mode 100644 index 000000000..307f3893a --- /dev/null +++ b/src/gl/system/gl_load.h @@ -0,0 +1,1793 @@ +#ifndef POINTER_C_GENERATED_HEADER_OPENGL_H +#define POINTER_C_GENERATED_HEADER_OPENGL_H + +#if defined(__glew_h__) || defined(__GLEW_H__) +#error Attempt to include auto-generated header after including glew.h +#endif +#if defined(__gl_h_) || defined(__GL_H__) +#error Attempt to include auto-generated header after including gl.h +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) +#error Attempt to include auto-generated header after including glext.h +#endif +#if defined(__gltypes_h_) +#error Attempt to include auto-generated header after gltypes.h +#endif +#if defined(__gl_ATI_h_) +#error Attempt to include auto-generated header after including glATI.h +#endif + +#define __glew_h__ +#define __GLEW_H__ +#define __gl_h_ +#define __GL_H__ +#define __glext_h_ +#define __GLEXT_H_ +#define __gltypes_h_ +#define __gl_ATI_h_ + +#ifndef APIENTRY + #if defined(__MINGW32__) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN 1 + #endif + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include + #elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN 1 + #endif + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include + #else + #define APIENTRY + #endif +#endif /*APIENTRY*/ + +#ifndef CODEGEN_FUNCPTR + #define CODEGEN_REMOVE_FUNCPTR + #if defined(_WIN32) + #define CODEGEN_FUNCPTR APIENTRY + #else + #define CODEGEN_FUNCPTR + #endif +#endif /*CODEGEN_FUNCPTR*/ + +#ifndef GLAPI + #define GLAPI extern +#endif + + +#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS +#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS + + +#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/ + + +#include +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif + typedef unsigned int GLenum; + typedef unsigned char GLboolean; + typedef unsigned int GLbitfield; + typedef void GLvoid; + typedef signed char GLbyte; + typedef short GLshort; + typedef int GLint; + typedef unsigned char GLubyte; + typedef unsigned short GLushort; + typedef unsigned int GLuint; + typedef int GLsizei; + typedef float GLfloat; + typedef float GLclampf; + typedef double GLdouble; + typedef double GLclampd; + typedef char GLchar; + typedef char GLcharARB; + #ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif + typedef unsigned short GLhalfARB; + typedef unsigned short GLhalf; + typedef GLint GLfixed; + typedef ptrdiff_t GLintptr; + typedef ptrdiff_t GLsizeiptr; + typedef int64_t GLint64; + typedef uint64_t GLuint64; + typedef ptrdiff_t GLintptrARB; + typedef ptrdiff_t GLsizeiptrARB; + typedef int64_t GLint64EXT; + typedef uint64_t GLuint64EXT; + typedef struct __GLsync *GLsync; + struct _cl_context; + struct _cl_event; + typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); + typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); + typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); + typedef unsigned short GLhalfNV; + typedef GLintptr GLvdpauSurfaceNV; + +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus*/ + +extern int ogl_ext_ARB_texture_compression; +extern int ogl_ext_EXT_texture_compression_s3tc; +extern int ogl_ext_ARB_buffer_storage; +extern int ogl_ext_ARB_shader_storage_buffer_object; +extern int ogl_ext_EXT_texture_sRGB; +extern int ogl_ext_EXT_texture_filter_anisotropic; + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF + +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 + +#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F +#define GL_BUFFER_STORAGE_FLAGS 0x8220 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000 +#define GL_CLIENT_STORAGE_BIT 0x0200 +#define GL_DYNAMIC_STORAGE_BIT 0x0100 +#define GL_MAP_COHERENT_BIT 0x0080 +#define GL_MAP_PERSISTENT_BIT 0x0040 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 + +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 + +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB_EXT 0x8C40 + +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE + +#define GL_ALPHA 0x1906 +#define GL_ALWAYS 0x0207 +#define GL_AND 0x1501 +#define GL_AND_INVERTED 0x1504 +#define GL_AND_REVERSE 0x1502 +#define GL_BACK 0x0405 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLUE 0x1905 +#define GL_BYTE 0x1400 +#define GL_CCW 0x0901 +#define GL_CLEAR 0x1500 +#define GL_COLOR 0x1800 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CW 0x0900 +#define GL_DECR 0x1E03 +#define GL_DEPTH 0x1801 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DITHER 0x0BD0 +#define GL_DONT_CARE 0x1100 +#define GL_DOUBLE 0x140A +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_EQUAL 0x0202 +#define GL_EQUIV 0x1509 +#define GL_EXTENSIONS 0x1F03 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FILL 0x1B02 +#define GL_FLOAT 0x1406 +#define GL_FRONT 0x0404 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_FRONT_FACE 0x0B46 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_GEQUAL 0x0206 +#define GL_GREATER 0x0204 +#define GL_GREEN 0x1904 +#define GL_INCR 0x1E02 +#define GL_INT 0x1404 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_KEEP 0x1E00 +#define GL_LEFT 0x0406 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LINE 0x1B01 +#define GL_LINEAR 0x2601 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_LINE_STRIP 0x0003 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_NAND 0x150E +#define GL_NEAREST 0x2600 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEVER 0x0200 +#define GL_NICEST 0x1102 +#define GL_NONE 0 +#define GL_NOOP 0x1505 +#define GL_NOR 0x1508 +#define GL_NOTEQUAL 0x0205 +#define GL_NO_ERROR 0 +#define GL_ONE 1 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_OR 0x1507 +#define GL_OR_INVERTED 0x150D +#define GL_OR_REVERSE 0x150B +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_POINT 0x1B00 +#define GL_POINTS 0x0000 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_QUADS 0x0007 +#define GL_R3_G3_B2 0x2A10 +#define GL_READ_BUFFER 0x0C02 +#define GL_RED 0x1903 +#define GL_RENDERER 0x1F01 +#define GL_REPEAT 0x2901 +#define GL_REPLACE 0x1E01 +#define GL_RGB 0x1907 +#define GL_RGB10 0x8052 +#define GL_RGB10_A2 0x8059 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8 0x8051 +#define GL_RGBA 0x1908 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGBA8 0x8058 +#define GL_RIGHT 0x0407 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SET 0x150F +#define GL_SHORT 0x1402 +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STEREO 0x0C33 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRUE 1 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_VENDOR 0x1F00 +#define GL_VERSION 0x1F02 +#define GL_VIEWPORT 0x0BA2 +#define GL_XOR 0x1506 +#define GL_ZERO 0 + +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 + +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MULTISAMPLE 0x809D +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 + +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_DECR_WRAP 0x8508 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_INCR_WRAP 0x8507 +#define GL_MAX 0x8008 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MIN 0x8007 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_LOD_BIAS 0x8501 + +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_QUERY 0x8865 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_READ_ONLY 0x88B8 +#define GL_READ_WRITE 0x88BA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STREAM_COPY 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_WRITE_ONLY 0x88B9 + +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_LINK_STATUS 0x8B82 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_SHADER 0x8B31 + +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SRGB_ALPHA 0x8C42 + +#define GL_BGRA_INTEGER 0x8D9B +#define GL_BGR_INTEGER 0x8D9A +#define GL_BLUE_INTEGER 0x8D96 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_RG 0x8226 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_CONTEXT_FLAGS 0x821E +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FIXED_ONLY 0x891D +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_GREEN_INTEGER 0x8D95 +#define GL_HALF_FLOAT 0x140B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_MAJOR_VERSION 0x821B +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +/*Copied GL_MAP_READ_BIT From: ARB_buffer_storage*/ +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +/*Copied GL_MAP_WRITE_BIT From: ARB_buffer_storage*/ +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MINOR_VERSION 0x821C +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_WAIT 0x8E13 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R16 0x822A +#define GL_R16F 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32F 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RED_INTEGER 0x8D94 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RG 0x8227 +#define GL_RG16 0x822C +#define GL_RG16F 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32F 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RGB16F 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB32F 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB8I 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB9_E5 0x8C3D +#define GL_RGBA16F 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RG_INTEGER 0x8228 +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD + +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_R16_SNORM 0x8F98 +#define GL_R8_SNORM 0x8F94 +#define GL_RG16_SNORM 0x8F99 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA16_SNORM 0x8F9B +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 + +#define GL_ALREADY_SIGNALED 0x911A +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_OBJECT_TYPE 0x9112 +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SIGNALED 0x9119 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_WAIT_FAILED 0x911D + +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_RGB10_A2UI 0x906F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SRC1_COLOR 0x88F9 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIMESTAMP 0x8E28 +#define GL_TIME_ELAPSED 0x88BF +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage1DARB)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +#define glCompressedTexImage1DARB _ptrc_glCompressedTexImage1DARB +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage2DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +#define glCompressedTexImage2DARB _ptrc_glCompressedTexImage2DARB +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage3DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +#define glCompressedTexImage3DARB _ptrc_glCompressedTexImage3DARB +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage1DARB)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +#define glCompressedTexSubImage1DARB _ptrc_glCompressedTexSubImage1DARB +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage2DARB)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +#define glCompressedTexSubImage2DARB _ptrc_glCompressedTexSubImage2DARB +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage3DARB)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +#define glCompressedTexSubImage3DARB _ptrc_glCompressedTexSubImage3DARB +extern void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTexImageARB)(GLenum, GLint, GLvoid *); +#define glGetCompressedTexImageARB _ptrc_glGetCompressedTexImageARB +#endif /*GL_ARB_texture_compression*/ + + +#ifndef GL_ARB_buffer_storage +#define GL_ARB_buffer_storage 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum, GLsizeiptr, const void *, GLbitfield); +#define glBufferStorage _ptrc_glBufferStorage +#endif /*GL_ARB_buffer_storage*/ + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +extern void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint, GLuint, GLuint); +#define glShaderStorageBlockBinding _ptrc_glShaderStorageBlockBinding +#endif /*GL_ARB_shader_storage_buffer_object*/ + + +extern void (CODEGEN_FUNCPTR *_ptrc_glBegin)(GLenum); +#define glBegin _ptrc_glBegin +extern void (CODEGEN_FUNCPTR *_ptrc_glEnd)(); +#define glEnd _ptrc_glEnd + + +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendFunc)(GLenum, GLenum); +#define glBlendFunc _ptrc_glBlendFunc +extern void (CODEGEN_FUNCPTR *_ptrc_glClear)(GLbitfield); +#define glClear _ptrc_glClear +extern void (CODEGEN_FUNCPTR *_ptrc_glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat); +#define glClearColor _ptrc_glClearColor +extern void (CODEGEN_FUNCPTR *_ptrc_glClearDepth)(GLdouble); +#define glClearDepth _ptrc_glClearDepth +extern void (CODEGEN_FUNCPTR *_ptrc_glClearStencil)(GLint); +#define glClearStencil _ptrc_glClearStencil +extern void (CODEGEN_FUNCPTR *_ptrc_glColorMask)(GLboolean, GLboolean, GLboolean, GLboolean); +#define glColorMask _ptrc_glColorMask +extern void (CODEGEN_FUNCPTR *_ptrc_glCullFace)(GLenum); +#define glCullFace _ptrc_glCullFace +extern void (CODEGEN_FUNCPTR *_ptrc_glDepthFunc)(GLenum); +#define glDepthFunc _ptrc_glDepthFunc +extern void (CODEGEN_FUNCPTR *_ptrc_glDepthMask)(GLboolean); +#define glDepthMask _ptrc_glDepthMask +extern void (CODEGEN_FUNCPTR *_ptrc_glDepthRange)(GLdouble, GLdouble); +#define glDepthRange _ptrc_glDepthRange +extern void (CODEGEN_FUNCPTR *_ptrc_glDisable)(GLenum); +#define glDisable _ptrc_glDisable +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawBuffer)(GLenum); +#define glDrawBuffer _ptrc_glDrawBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glEnable)(GLenum); +#define glEnable _ptrc_glEnable +extern void (CODEGEN_FUNCPTR *_ptrc_glFinish)(); +#define glFinish _ptrc_glFinish +extern void (CODEGEN_FUNCPTR *_ptrc_glFlush)(); +#define glFlush _ptrc_glFlush +extern void (CODEGEN_FUNCPTR *_ptrc_glFrontFace)(GLenum); +#define glFrontFace _ptrc_glFrontFace +extern void (CODEGEN_FUNCPTR *_ptrc_glGetBooleanv)(GLenum, GLboolean *); +#define glGetBooleanv _ptrc_glGetBooleanv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetDoublev)(GLenum, GLdouble *); +#define glGetDoublev _ptrc_glGetDoublev +extern GLenum (CODEGEN_FUNCPTR *_ptrc_glGetError)(); +#define glGetError _ptrc_glGetError +extern void (CODEGEN_FUNCPTR *_ptrc_glGetFloatv)(GLenum, GLfloat *); +#define glGetFloatv _ptrc_glGetFloatv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetIntegerv)(GLenum, GLint *); +#define glGetIntegerv _ptrc_glGetIntegerv +extern const GLubyte * (CODEGEN_FUNCPTR *_ptrc_glGetString)(GLenum); +#define glGetString _ptrc_glGetString +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexImage)(GLenum, GLint, GLenum, GLenum, GLvoid *); +#define glGetTexImage _ptrc_glGetTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexLevelParameterfv)(GLenum, GLint, GLenum, GLfloat *); +#define glGetTexLevelParameterfv _ptrc_glGetTexLevelParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexLevelParameteriv)(GLenum, GLint, GLenum, GLint *); +#define glGetTexLevelParameteriv _ptrc_glGetTexLevelParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameterfv)(GLenum, GLenum, GLfloat *); +#define glGetTexParameterfv _ptrc_glGetTexParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameteriv)(GLenum, GLenum, GLint *); +#define glGetTexParameteriv _ptrc_glGetTexParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glHint)(GLenum, GLenum); +#define glHint _ptrc_glHint +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsEnabled)(GLenum); +#define glIsEnabled _ptrc_glIsEnabled +extern void (CODEGEN_FUNCPTR *_ptrc_glLineWidth)(GLfloat); +#define glLineWidth _ptrc_glLineWidth +extern void (CODEGEN_FUNCPTR *_ptrc_glLogicOp)(GLenum); +#define glLogicOp _ptrc_glLogicOp +extern void (CODEGEN_FUNCPTR *_ptrc_glPixelStoref)(GLenum, GLfloat); +#define glPixelStoref _ptrc_glPixelStoref +extern void (CODEGEN_FUNCPTR *_ptrc_glPixelStorei)(GLenum, GLint); +#define glPixelStorei _ptrc_glPixelStorei +extern void (CODEGEN_FUNCPTR *_ptrc_glPointSize)(GLfloat); +#define glPointSize _ptrc_glPointSize +extern void (CODEGEN_FUNCPTR *_ptrc_glPolygonMode)(GLenum, GLenum); +#define glPolygonMode _ptrc_glPolygonMode +extern void (CODEGEN_FUNCPTR *_ptrc_glReadBuffer)(GLenum); +#define glReadBuffer _ptrc_glReadBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *); +#define glReadPixels _ptrc_glReadPixels +extern void (CODEGEN_FUNCPTR *_ptrc_glScissor)(GLint, GLint, GLsizei, GLsizei); +#define glScissor _ptrc_glScissor +extern void (CODEGEN_FUNCPTR *_ptrc_glStencilFunc)(GLenum, GLint, GLuint); +#define glStencilFunc _ptrc_glStencilFunc +extern void (CODEGEN_FUNCPTR *_ptrc_glStencilMask)(GLuint); +#define glStencilMask _ptrc_glStencilMask +extern void (CODEGEN_FUNCPTR *_ptrc_glStencilOp)(GLenum, GLenum, GLenum); +#define glStencilOp _ptrc_glStencilOp +extern void (CODEGEN_FUNCPTR *_ptrc_glTexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +#define glTexImage1D _ptrc_glTexImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +#define glTexImage2D _ptrc_glTexImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glTexParameterf)(GLenum, GLenum, GLfloat); +#define glTexParameterf _ptrc_glTexParameterf +extern void (CODEGEN_FUNCPTR *_ptrc_glTexParameterfv)(GLenum, GLenum, const GLfloat *); +#define glTexParameterfv _ptrc_glTexParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glTexParameteri)(GLenum, GLenum, GLint); +#define glTexParameteri _ptrc_glTexParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glTexParameteriv)(GLenum, GLenum, const GLint *); +#define glTexParameteriv _ptrc_glTexParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glViewport)(GLint, GLint, GLsizei, GLsizei); +#define glViewport _ptrc_glViewport + +extern void (CODEGEN_FUNCPTR *_ptrc_glBindTexture)(GLenum, GLuint); +#define glBindTexture _ptrc_glBindTexture +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTexImage1D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +#define glCopyTexImage1D _ptrc_glCopyTexImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTexImage2D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +#define glCopyTexImage2D _ptrc_glCopyTexImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTexSubImage1D)(GLenum, GLint, GLint, GLint, GLint, GLsizei); +#define glCopyTexSubImage1D _ptrc_glCopyTexSubImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTexSubImage2D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#define glCopyTexSubImage2D _ptrc_glCopyTexSubImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteTextures)(GLsizei, const GLuint *); +#define glDeleteTextures _ptrc_glDeleteTextures +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawArrays)(GLenum, GLint, GLsizei); +#define glDrawArrays _ptrc_glDrawArrays +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElements)(GLenum, GLsizei, GLenum, const GLvoid *); +#define glDrawElements _ptrc_glDrawElements +extern void (CODEGEN_FUNCPTR *_ptrc_glGenTextures)(GLsizei, GLuint *); +#define glGenTextures _ptrc_glGenTextures +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsTexture)(GLuint); +#define glIsTexture _ptrc_glIsTexture +extern void (CODEGEN_FUNCPTR *_ptrc_glPolygonOffset)(GLfloat, GLfloat); +#define glPolygonOffset _ptrc_glPolygonOffset +extern void (CODEGEN_FUNCPTR *_ptrc_glTexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +#define glTexSubImage1D _ptrc_glTexSubImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#define glTexSubImage2D _ptrc_glTexSubImage2D + +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendColor)(GLfloat, GLfloat, GLfloat, GLfloat); +#define glBlendColor _ptrc_glBlendColor +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendEquation)(GLenum); +#define glBlendEquation _ptrc_glBlendEquation +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTexSubImage3D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#define glCopyTexSubImage3D _ptrc_glCopyTexSubImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawRangeElements)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#define glDrawRangeElements _ptrc_glDrawRangeElements +extern void (CODEGEN_FUNCPTR *_ptrc_glTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +#define glTexImage3D _ptrc_glTexImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glTexSubImage3D)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#define glTexSubImage3D _ptrc_glTexSubImage3D + +extern void (CODEGEN_FUNCPTR *_ptrc_glActiveTexture)(GLenum); +#define glActiveTexture _ptrc_glActiveTexture +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage1D)(GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +#define glCompressedTexImage1D _ptrc_glCompressedTexImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage2D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +#define glCompressedTexImage2D _ptrc_glCompressedTexImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexImage3D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +#define glCompressedTexImage3D _ptrc_glCompressedTexImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage1D)(GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +#define glCompressedTexSubImage1D _ptrc_glCompressedTexSubImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +#define glCompressedTexSubImage2D _ptrc_glCompressedTexSubImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTexSubImage3D)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +#define glCompressedTexSubImage3D _ptrc_glCompressedTexSubImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTexImage)(GLenum, GLint, GLvoid *); +#define glGetCompressedTexImage _ptrc_glGetCompressedTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glSampleCoverage)(GLfloat, GLboolean); +#define glSampleCoverage _ptrc_glSampleCoverage + +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendFuncSeparate)(GLenum, GLenum, GLenum, GLenum); +#define glBlendFuncSeparate _ptrc_glBlendFuncSeparate +extern void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawArrays)(GLenum, const GLint *, const GLsizei *, GLsizei); +#define glMultiDrawArrays _ptrc_glMultiDrawArrays +extern void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawElements)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei); +#define glMultiDrawElements _ptrc_glMultiDrawElements +extern void (CODEGEN_FUNCPTR *_ptrc_glPointParameterf)(GLenum, GLfloat); +#define glPointParameterf _ptrc_glPointParameterf +extern void (CODEGEN_FUNCPTR *_ptrc_glPointParameterfv)(GLenum, const GLfloat *); +#define glPointParameterfv _ptrc_glPointParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glPointParameteri)(GLenum, GLint); +#define glPointParameteri _ptrc_glPointParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glPointParameteriv)(GLenum, const GLint *); +#define glPointParameteriv _ptrc_glPointParameteriv + +extern void (CODEGEN_FUNCPTR *_ptrc_glBeginQuery)(GLenum, GLuint); +#define glBeginQuery _ptrc_glBeginQuery +extern void (CODEGEN_FUNCPTR *_ptrc_glBindBuffer)(GLenum, GLuint); +#define glBindBuffer _ptrc_glBindBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glBufferData)(GLenum, GLsizeiptr, const GLvoid *, GLenum); +#define glBufferData _ptrc_glBufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glBufferSubData)(GLenum, GLintptr, GLsizeiptr, const GLvoid *); +#define glBufferSubData _ptrc_glBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteBuffers)(GLsizei, const GLuint *); +#define glDeleteBuffers _ptrc_glDeleteBuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteQueries)(GLsizei, const GLuint *); +#define glDeleteQueries _ptrc_glDeleteQueries +extern void (CODEGEN_FUNCPTR *_ptrc_glEndQuery)(GLenum); +#define glEndQuery _ptrc_glEndQuery +extern void (CODEGEN_FUNCPTR *_ptrc_glGenBuffers)(GLsizei, GLuint *); +#define glGenBuffers _ptrc_glGenBuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glGenQueries)(GLsizei, GLuint *); +#define glGenQueries _ptrc_glGenQueries +extern void (CODEGEN_FUNCPTR *_ptrc_glGetBufferParameteriv)(GLenum, GLenum, GLint *); +#define glGetBufferParameteriv _ptrc_glGetBufferParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetBufferPointerv)(GLenum, GLenum, GLvoid **); +#define glGetBufferPointerv _ptrc_glGetBufferPointerv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetBufferSubData)(GLenum, GLintptr, GLsizeiptr, GLvoid *); +#define glGetBufferSubData _ptrc_glGetBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjectiv)(GLuint, GLenum, GLint *); +#define glGetQueryObjectiv _ptrc_glGetQueryObjectiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjectuiv)(GLuint, GLenum, GLuint *); +#define glGetQueryObjectuiv _ptrc_glGetQueryObjectuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryiv)(GLenum, GLenum, GLint *); +#define glGetQueryiv _ptrc_glGetQueryiv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsBuffer)(GLuint); +#define glIsBuffer _ptrc_glIsBuffer +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsQuery)(GLuint); +#define glIsQuery _ptrc_glIsQuery +extern void * (CODEGEN_FUNCPTR *_ptrc_glMapBuffer)(GLenum, GLenum); +#define glMapBuffer _ptrc_glMapBuffer +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glUnmapBuffer)(GLenum); +#define glUnmapBuffer _ptrc_glUnmapBuffer + +extern void (CODEGEN_FUNCPTR *_ptrc_glAttachShader)(GLuint, GLuint); +#define glAttachShader _ptrc_glAttachShader +extern void (CODEGEN_FUNCPTR *_ptrc_glBindAttribLocation)(GLuint, GLuint, const GLchar *); +#define glBindAttribLocation _ptrc_glBindAttribLocation +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendEquationSeparate)(GLenum, GLenum); +#define glBlendEquationSeparate _ptrc_glBlendEquationSeparate +extern void (CODEGEN_FUNCPTR *_ptrc_glCompileShader)(GLuint); +#define glCompileShader _ptrc_glCompileShader +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glCreateProgram)(); +#define glCreateProgram _ptrc_glCreateProgram +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glCreateShader)(GLenum); +#define glCreateShader _ptrc_glCreateShader +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteProgram)(GLuint); +#define glDeleteProgram _ptrc_glDeleteProgram +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteShader)(GLuint); +#define glDeleteShader _ptrc_glDeleteShader +extern void (CODEGEN_FUNCPTR *_ptrc_glDetachShader)(GLuint, GLuint); +#define glDetachShader _ptrc_glDetachShader +extern void (CODEGEN_FUNCPTR *_ptrc_glDisableVertexAttribArray)(GLuint); +#define glDisableVertexAttribArray _ptrc_glDisableVertexAttribArray +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawBuffers)(GLsizei, const GLenum *); +#define glDrawBuffers _ptrc_glDrawBuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glEnableVertexAttribArray)(GLuint); +#define glEnableVertexAttribArray _ptrc_glEnableVertexAttribArray +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveAttrib)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +#define glGetActiveAttrib _ptrc_glGetActiveAttrib +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniform)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); +#define glGetActiveUniform _ptrc_glGetActiveUniform +extern void (CODEGEN_FUNCPTR *_ptrc_glGetAttachedShaders)(GLuint, GLsizei, GLsizei *, GLuint *); +#define glGetAttachedShaders _ptrc_glGetAttachedShaders +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetAttribLocation)(GLuint, const GLchar *); +#define glGetAttribLocation _ptrc_glGetAttribLocation +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *); +#define glGetProgramInfoLog _ptrc_glGetProgramInfoLog +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramiv)(GLuint, GLenum, GLint *); +#define glGetProgramiv _ptrc_glGetProgramiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetShaderInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *); +#define glGetShaderInfoLog _ptrc_glGetShaderInfoLog +extern void (CODEGEN_FUNCPTR *_ptrc_glGetShaderSource)(GLuint, GLsizei, GLsizei *, GLchar *); +#define glGetShaderSource _ptrc_glGetShaderSource +extern void (CODEGEN_FUNCPTR *_ptrc_glGetShaderiv)(GLuint, GLenum, GLint *); +#define glGetShaderiv _ptrc_glGetShaderiv +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetUniformLocation)(GLuint, const GLchar *); +#define glGetUniformLocation _ptrc_glGetUniformLocation +extern void (CODEGEN_FUNCPTR *_ptrc_glGetUniformfv)(GLuint, GLint, GLfloat *); +#define glGetUniformfv _ptrc_glGetUniformfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetUniformiv)(GLuint, GLint, GLint *); +#define glGetUniformiv _ptrc_glGetUniformiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribPointerv)(GLuint, GLenum, GLvoid **); +#define glGetVertexAttribPointerv _ptrc_glGetVertexAttribPointerv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribdv)(GLuint, GLenum, GLdouble *); +#define glGetVertexAttribdv _ptrc_glGetVertexAttribdv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribfv)(GLuint, GLenum, GLfloat *); +#define glGetVertexAttribfv _ptrc_glGetVertexAttribfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribiv)(GLuint, GLenum, GLint *); +#define glGetVertexAttribiv _ptrc_glGetVertexAttribiv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsProgram)(GLuint); +#define glIsProgram _ptrc_glIsProgram +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsShader)(GLuint); +#define glIsShader _ptrc_glIsShader +extern void (CODEGEN_FUNCPTR *_ptrc_glLinkProgram)(GLuint); +#define glLinkProgram _ptrc_glLinkProgram +extern void (CODEGEN_FUNCPTR *_ptrc_glShaderSource)(GLuint, GLsizei, const GLchar *const*, const GLint *); +#define glShaderSource _ptrc_glShaderSource +extern void (CODEGEN_FUNCPTR *_ptrc_glStencilFuncSeparate)(GLenum, GLenum, GLint, GLuint); +#define glStencilFuncSeparate _ptrc_glStencilFuncSeparate +extern void (CODEGEN_FUNCPTR *_ptrc_glStencilMaskSeparate)(GLenum, GLuint); +#define glStencilMaskSeparate _ptrc_glStencilMaskSeparate +extern void (CODEGEN_FUNCPTR *_ptrc_glStencilOpSeparate)(GLenum, GLenum, GLenum, GLenum); +#define glStencilOpSeparate _ptrc_glStencilOpSeparate +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1f)(GLint, GLfloat); +#define glUniform1f _ptrc_glUniform1f +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1fv)(GLint, GLsizei, const GLfloat *); +#define glUniform1fv _ptrc_glUniform1fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1i)(GLint, GLint); +#define glUniform1i _ptrc_glUniform1i +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1iv)(GLint, GLsizei, const GLint *); +#define glUniform1iv _ptrc_glUniform1iv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2f)(GLint, GLfloat, GLfloat); +#define glUniform2f _ptrc_glUniform2f +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2fv)(GLint, GLsizei, const GLfloat *); +#define glUniform2fv _ptrc_glUniform2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2i)(GLint, GLint, GLint); +#define glUniform2i _ptrc_glUniform2i +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2iv)(GLint, GLsizei, const GLint *); +#define glUniform2iv _ptrc_glUniform2iv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3f)(GLint, GLfloat, GLfloat, GLfloat); +#define glUniform3f _ptrc_glUniform3f +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3fv)(GLint, GLsizei, const GLfloat *); +#define glUniform3fv _ptrc_glUniform3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3i)(GLint, GLint, GLint, GLint); +#define glUniform3i _ptrc_glUniform3i +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3iv)(GLint, GLsizei, const GLint *); +#define glUniform3iv _ptrc_glUniform3iv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4f)(GLint, GLfloat, GLfloat, GLfloat, GLfloat); +#define glUniform4f _ptrc_glUniform4f +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4fv)(GLint, GLsizei, const GLfloat *); +#define glUniform4fv _ptrc_glUniform4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4i)(GLint, GLint, GLint, GLint, GLint); +#define glUniform4i _ptrc_glUniform4i +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4iv)(GLint, GLsizei, const GLint *); +#define glUniform4iv _ptrc_glUniform4iv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix2fv _ptrc_glUniformMatrix2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix3fv _ptrc_glUniformMatrix3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix4fv _ptrc_glUniformMatrix4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUseProgram)(GLuint); +#define glUseProgram _ptrc_glUseProgram +extern void (CODEGEN_FUNCPTR *_ptrc_glValidateProgram)(GLuint); +#define glValidateProgram _ptrc_glValidateProgram +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1d)(GLuint, GLdouble); +#define glVertexAttrib1d _ptrc_glVertexAttrib1d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1dv)(GLuint, const GLdouble *); +#define glVertexAttrib1dv _ptrc_glVertexAttrib1dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1f)(GLuint, GLfloat); +#define glVertexAttrib1f _ptrc_glVertexAttrib1f +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1fv)(GLuint, const GLfloat *); +#define glVertexAttrib1fv _ptrc_glVertexAttrib1fv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1s)(GLuint, GLshort); +#define glVertexAttrib1s _ptrc_glVertexAttrib1s +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib1sv)(GLuint, const GLshort *); +#define glVertexAttrib1sv _ptrc_glVertexAttrib1sv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2d)(GLuint, GLdouble, GLdouble); +#define glVertexAttrib2d _ptrc_glVertexAttrib2d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2dv)(GLuint, const GLdouble *); +#define glVertexAttrib2dv _ptrc_glVertexAttrib2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2f)(GLuint, GLfloat, GLfloat); +#define glVertexAttrib2f _ptrc_glVertexAttrib2f +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2fv)(GLuint, const GLfloat *); +#define glVertexAttrib2fv _ptrc_glVertexAttrib2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2s)(GLuint, GLshort, GLshort); +#define glVertexAttrib2s _ptrc_glVertexAttrib2s +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib2sv)(GLuint, const GLshort *); +#define glVertexAttrib2sv _ptrc_glVertexAttrib2sv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3d)(GLuint, GLdouble, GLdouble, GLdouble); +#define glVertexAttrib3d _ptrc_glVertexAttrib3d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3dv)(GLuint, const GLdouble *); +#define glVertexAttrib3dv _ptrc_glVertexAttrib3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3f)(GLuint, GLfloat, GLfloat, GLfloat); +#define glVertexAttrib3f _ptrc_glVertexAttrib3f +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3fv)(GLuint, const GLfloat *); +#define glVertexAttrib3fv _ptrc_glVertexAttrib3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3s)(GLuint, GLshort, GLshort, GLshort); +#define glVertexAttrib3s _ptrc_glVertexAttrib3s +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib3sv)(GLuint, const GLshort *); +#define glVertexAttrib3sv _ptrc_glVertexAttrib3sv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nbv)(GLuint, const GLbyte *); +#define glVertexAttrib4Nbv _ptrc_glVertexAttrib4Nbv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Niv)(GLuint, const GLint *); +#define glVertexAttrib4Niv _ptrc_glVertexAttrib4Niv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nsv)(GLuint, const GLshort *); +#define glVertexAttrib4Nsv _ptrc_glVertexAttrib4Nsv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nub)(GLuint, GLubyte, GLubyte, GLubyte, GLubyte); +#define glVertexAttrib4Nub _ptrc_glVertexAttrib4Nub +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nubv)(GLuint, const GLubyte *); +#define glVertexAttrib4Nubv _ptrc_glVertexAttrib4Nubv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nuiv)(GLuint, const GLuint *); +#define glVertexAttrib4Nuiv _ptrc_glVertexAttrib4Nuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4Nusv)(GLuint, const GLushort *); +#define glVertexAttrib4Nusv _ptrc_glVertexAttrib4Nusv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4bv)(GLuint, const GLbyte *); +#define glVertexAttrib4bv _ptrc_glVertexAttrib4bv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4d)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble); +#define glVertexAttrib4d _ptrc_glVertexAttrib4d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4dv)(GLuint, const GLdouble *); +#define glVertexAttrib4dv _ptrc_glVertexAttrib4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4f)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat); +#define glVertexAttrib4f _ptrc_glVertexAttrib4f +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4fv)(GLuint, const GLfloat *); +#define glVertexAttrib4fv _ptrc_glVertexAttrib4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4iv)(GLuint, const GLint *); +#define glVertexAttrib4iv _ptrc_glVertexAttrib4iv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4s)(GLuint, GLshort, GLshort, GLshort, GLshort); +#define glVertexAttrib4s _ptrc_glVertexAttrib4s +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4sv)(GLuint, const GLshort *); +#define glVertexAttrib4sv _ptrc_glVertexAttrib4sv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4ubv)(GLuint, const GLubyte *); +#define glVertexAttrib4ubv _ptrc_glVertexAttrib4ubv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4uiv)(GLuint, const GLuint *); +#define glVertexAttrib4uiv _ptrc_glVertexAttrib4uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttrib4usv)(GLuint, const GLushort *); +#define glVertexAttrib4usv _ptrc_glVertexAttrib4usv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +#define glVertexAttribPointer _ptrc_glVertexAttribPointer + +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x3fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix2x3fv _ptrc_glUniformMatrix2x3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x4fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix2x4fv _ptrc_glUniformMatrix2x4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x2fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix3x2fv _ptrc_glUniformMatrix3x2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x4fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix3x4fv _ptrc_glUniformMatrix3x4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x2fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix4x2fv _ptrc_glUniformMatrix4x2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x3fv)(GLint, GLsizei, GLboolean, const GLfloat *); +#define glUniformMatrix4x3fv _ptrc_glUniformMatrix4x3fv + +extern void (CODEGEN_FUNCPTR *_ptrc_glBeginConditionalRender)(GLuint, GLenum); +#define glBeginConditionalRender _ptrc_glBeginConditionalRender +extern void (CODEGEN_FUNCPTR *_ptrc_glBeginTransformFeedback)(GLenum); +#define glBeginTransformFeedback _ptrc_glBeginTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glBindBufferBase)(GLenum, GLuint, GLuint); +#define glBindBufferBase _ptrc_glBindBufferBase +extern void (CODEGEN_FUNCPTR *_ptrc_glBindBufferRange)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +#define glBindBufferRange _ptrc_glBindBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glBindFragDataLocation)(GLuint, GLuint, const GLchar *); +#define glBindFragDataLocation _ptrc_glBindFragDataLocation +extern void (CODEGEN_FUNCPTR *_ptrc_glBindFramebuffer)(GLenum, GLuint); +#define glBindFramebuffer _ptrc_glBindFramebuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glBindRenderbuffer)(GLenum, GLuint); +#define glBindRenderbuffer _ptrc_glBindRenderbuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glBindVertexArray)(GLuint); +#define glBindVertexArray _ptrc_glBindVertexArray +extern void (CODEGEN_FUNCPTR *_ptrc_glBlitFramebuffer)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); +#define glBlitFramebuffer _ptrc_glBlitFramebuffer +extern GLenum (CODEGEN_FUNCPTR *_ptrc_glCheckFramebufferStatus)(GLenum); +#define glCheckFramebufferStatus _ptrc_glCheckFramebufferStatus +extern void (CODEGEN_FUNCPTR *_ptrc_glClampColor)(GLenum, GLenum); +#define glClampColor _ptrc_glClampColor +extern void (CODEGEN_FUNCPTR *_ptrc_glClearBufferfi)(GLenum, GLint, GLfloat, GLint); +#define glClearBufferfi _ptrc_glClearBufferfi +extern void (CODEGEN_FUNCPTR *_ptrc_glClearBufferfv)(GLenum, GLint, const GLfloat *); +#define glClearBufferfv _ptrc_glClearBufferfv +extern void (CODEGEN_FUNCPTR *_ptrc_glClearBufferiv)(GLenum, GLint, const GLint *); +#define glClearBufferiv _ptrc_glClearBufferiv +extern void (CODEGEN_FUNCPTR *_ptrc_glClearBufferuiv)(GLenum, GLint, const GLuint *); +#define glClearBufferuiv _ptrc_glClearBufferuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glColorMaski)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +#define glColorMaski _ptrc_glColorMaski +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteFramebuffers)(GLsizei, const GLuint *); +#define glDeleteFramebuffers _ptrc_glDeleteFramebuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteRenderbuffers)(GLsizei, const GLuint *); +#define glDeleteRenderbuffers _ptrc_glDeleteRenderbuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteVertexArrays)(GLsizei, const GLuint *); +#define glDeleteVertexArrays _ptrc_glDeleteVertexArrays +extern void (CODEGEN_FUNCPTR *_ptrc_glDisablei)(GLenum, GLuint); +#define glDisablei _ptrc_glDisablei +extern void (CODEGEN_FUNCPTR *_ptrc_glEnablei)(GLenum, GLuint); +#define glEnablei _ptrc_glEnablei +extern void (CODEGEN_FUNCPTR *_ptrc_glEndConditionalRender)(); +#define glEndConditionalRender _ptrc_glEndConditionalRender +extern void (CODEGEN_FUNCPTR *_ptrc_glEndTransformFeedback)(); +#define glEndTransformFeedback _ptrc_glEndTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glFlushMappedBufferRange)(GLenum, GLintptr, GLsizeiptr); +#define glFlushMappedBufferRange _ptrc_glFlushMappedBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferRenderbuffer)(GLenum, GLenum, GLenum, GLuint); +#define glFramebufferRenderbuffer _ptrc_glFramebufferRenderbuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture1D)(GLenum, GLenum, GLenum, GLuint, GLint); +#define glFramebufferTexture1D _ptrc_glFramebufferTexture1D +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture2D)(GLenum, GLenum, GLenum, GLuint, GLint); +#define glFramebufferTexture2D _ptrc_glFramebufferTexture2D +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture3D)(GLenum, GLenum, GLenum, GLuint, GLint, GLint); +#define glFramebufferTexture3D _ptrc_glFramebufferTexture3D +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTextureLayer)(GLenum, GLenum, GLuint, GLint, GLint); +#define glFramebufferTextureLayer _ptrc_glFramebufferTextureLayer +extern void (CODEGEN_FUNCPTR *_ptrc_glGenFramebuffers)(GLsizei, GLuint *); +#define glGenFramebuffers _ptrc_glGenFramebuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glGenRenderbuffers)(GLsizei, GLuint *); +#define glGenRenderbuffers _ptrc_glGenRenderbuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glGenVertexArrays)(GLsizei, GLuint *); +#define glGenVertexArrays _ptrc_glGenVertexArrays +extern void (CODEGEN_FUNCPTR *_ptrc_glGenerateMipmap)(GLenum); +#define glGenerateMipmap _ptrc_glGenerateMipmap +extern void (CODEGEN_FUNCPTR *_ptrc_glGetBooleani_v)(GLenum, GLuint, GLboolean *); +#define glGetBooleani_v _ptrc_glGetBooleani_v +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetFragDataLocation)(GLuint, const GLchar *); +#define glGetFragDataLocation _ptrc_glGetFragDataLocation +extern void (CODEGEN_FUNCPTR *_ptrc_glGetFramebufferAttachmentParameteriv)(GLenum, GLenum, GLenum, GLint *); +#define glGetFramebufferAttachmentParameteriv _ptrc_glGetFramebufferAttachmentParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetIntegeri_v)(GLenum, GLuint, GLint *); +#define glGetIntegeri_v _ptrc_glGetIntegeri_v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetRenderbufferParameteriv)(GLenum, GLenum, GLint *); +#define glGetRenderbufferParameteriv _ptrc_glGetRenderbufferParameteriv +extern const GLubyte * (CODEGEN_FUNCPTR *_ptrc_glGetStringi)(GLenum, GLuint); +#define glGetStringi _ptrc_glGetStringi +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameterIiv)(GLenum, GLenum, GLint *); +#define glGetTexParameterIiv _ptrc_glGetTexParameterIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTexParameterIuiv)(GLenum, GLenum, GLuint *); +#define glGetTexParameterIuiv _ptrc_glGetTexParameterIuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbackVarying)(GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); +#define glGetTransformFeedbackVarying _ptrc_glGetTransformFeedbackVarying +extern void (CODEGEN_FUNCPTR *_ptrc_glGetUniformuiv)(GLuint, GLint, GLuint *); +#define glGetUniformuiv _ptrc_glGetUniformuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribIiv)(GLuint, GLenum, GLint *); +#define glGetVertexAttribIiv _ptrc_glGetVertexAttribIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribIuiv)(GLuint, GLenum, GLuint *); +#define glGetVertexAttribIuiv _ptrc_glGetVertexAttribIuiv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsEnabledi)(GLenum, GLuint); +#define glIsEnabledi _ptrc_glIsEnabledi +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsFramebuffer)(GLuint); +#define glIsFramebuffer _ptrc_glIsFramebuffer +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsRenderbuffer)(GLuint); +#define glIsRenderbuffer _ptrc_glIsRenderbuffer +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsVertexArray)(GLuint); +#define glIsVertexArray _ptrc_glIsVertexArray +extern void * (CODEGEN_FUNCPTR *_ptrc_glMapBufferRange)(GLenum, GLintptr, GLsizeiptr, GLbitfield); +#define glMapBufferRange _ptrc_glMapBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glRenderbufferStorage)(GLenum, GLenum, GLsizei, GLsizei); +#define glRenderbufferStorage _ptrc_glRenderbufferStorage +extern void (CODEGEN_FUNCPTR *_ptrc_glRenderbufferStorageMultisample)(GLenum, GLsizei, GLenum, GLsizei, GLsizei); +#define glRenderbufferStorageMultisample _ptrc_glRenderbufferStorageMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glTexParameterIiv)(GLenum, GLenum, const GLint *); +#define glTexParameterIiv _ptrc_glTexParameterIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glTexParameterIuiv)(GLenum, GLenum, const GLuint *); +#define glTexParameterIuiv _ptrc_glTexParameterIuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glTransformFeedbackVaryings)(GLuint, GLsizei, const GLchar *const*, GLenum); +#define glTransformFeedbackVaryings _ptrc_glTransformFeedbackVaryings +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1ui)(GLint, GLuint); +#define glUniform1ui _ptrc_glUniform1ui +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1uiv)(GLint, GLsizei, const GLuint *); +#define glUniform1uiv _ptrc_glUniform1uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2ui)(GLint, GLuint, GLuint); +#define glUniform2ui _ptrc_glUniform2ui +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2uiv)(GLint, GLsizei, const GLuint *); +#define glUniform2uiv _ptrc_glUniform2uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3ui)(GLint, GLuint, GLuint, GLuint); +#define glUniform3ui _ptrc_glUniform3ui +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3uiv)(GLint, GLsizei, const GLuint *); +#define glUniform3uiv _ptrc_glUniform3uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4ui)(GLint, GLuint, GLuint, GLuint, GLuint); +#define glUniform4ui _ptrc_glUniform4ui +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4uiv)(GLint, GLsizei, const GLuint *); +#define glUniform4uiv _ptrc_glUniform4uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1i)(GLuint, GLint); +#define glVertexAttribI1i _ptrc_glVertexAttribI1i +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1iv)(GLuint, const GLint *); +#define glVertexAttribI1iv _ptrc_glVertexAttribI1iv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1ui)(GLuint, GLuint); +#define glVertexAttribI1ui _ptrc_glVertexAttribI1ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI1uiv)(GLuint, const GLuint *); +#define glVertexAttribI1uiv _ptrc_glVertexAttribI1uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2i)(GLuint, GLint, GLint); +#define glVertexAttribI2i _ptrc_glVertexAttribI2i +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2iv)(GLuint, const GLint *); +#define glVertexAttribI2iv _ptrc_glVertexAttribI2iv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2ui)(GLuint, GLuint, GLuint); +#define glVertexAttribI2ui _ptrc_glVertexAttribI2ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI2uiv)(GLuint, const GLuint *); +#define glVertexAttribI2uiv _ptrc_glVertexAttribI2uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3i)(GLuint, GLint, GLint, GLint); +#define glVertexAttribI3i _ptrc_glVertexAttribI3i +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3iv)(GLuint, const GLint *); +#define glVertexAttribI3iv _ptrc_glVertexAttribI3iv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3ui)(GLuint, GLuint, GLuint, GLuint); +#define glVertexAttribI3ui _ptrc_glVertexAttribI3ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI3uiv)(GLuint, const GLuint *); +#define glVertexAttribI3uiv _ptrc_glVertexAttribI3uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4bv)(GLuint, const GLbyte *); +#define glVertexAttribI4bv _ptrc_glVertexAttribI4bv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4i)(GLuint, GLint, GLint, GLint, GLint); +#define glVertexAttribI4i _ptrc_glVertexAttribI4i +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4iv)(GLuint, const GLint *); +#define glVertexAttribI4iv _ptrc_glVertexAttribI4iv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4sv)(GLuint, const GLshort *); +#define glVertexAttribI4sv _ptrc_glVertexAttribI4sv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4ubv)(GLuint, const GLubyte *); +#define glVertexAttribI4ubv _ptrc_glVertexAttribI4ubv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4ui)(GLuint, GLuint, GLuint, GLuint, GLuint); +#define glVertexAttribI4ui _ptrc_glVertexAttribI4ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4uiv)(GLuint, const GLuint *); +#define glVertexAttribI4uiv _ptrc_glVertexAttribI4uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribI4usv)(GLuint, const GLushort *); +#define glVertexAttribI4usv _ptrc_glVertexAttribI4usv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribIPointer)(GLuint, GLint, GLenum, GLsizei, const GLvoid *); +#define glVertexAttribIPointer _ptrc_glVertexAttribIPointer + +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyBufferSubData)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr); +#define glCopyBufferSubData _ptrc_glCopyBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawArraysInstanced)(GLenum, GLint, GLsizei, GLsizei); +#define glDrawArraysInstanced _ptrc_glDrawArraysInstanced +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstanced)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); +#define glDrawElementsInstanced _ptrc_glDrawElementsInstanced +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformBlockName)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *); +#define glGetActiveUniformBlockName _ptrc_glGetActiveUniformBlockName +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformBlockiv)(GLuint, GLuint, GLenum, GLint *); +#define glGetActiveUniformBlockiv _ptrc_glGetActiveUniformBlockiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformName)(GLuint, GLuint, GLsizei, GLsizei *, GLchar *); +#define glGetActiveUniformName _ptrc_glGetActiveUniformName +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveUniformsiv)(GLuint, GLsizei, const GLuint *, GLenum, GLint *); +#define glGetActiveUniformsiv _ptrc_glGetActiveUniformsiv +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glGetUniformBlockIndex)(GLuint, const GLchar *); +#define glGetUniformBlockIndex _ptrc_glGetUniformBlockIndex +extern void (CODEGEN_FUNCPTR *_ptrc_glGetUniformIndices)(GLuint, GLsizei, const GLchar *const*, GLuint *); +#define glGetUniformIndices _ptrc_glGetUniformIndices +extern void (CODEGEN_FUNCPTR *_ptrc_glPrimitiveRestartIndex)(GLuint); +#define glPrimitiveRestartIndex _ptrc_glPrimitiveRestartIndex +extern void (CODEGEN_FUNCPTR *_ptrc_glTexBuffer)(GLenum, GLenum, GLuint); +#define glTexBuffer _ptrc_glTexBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformBlockBinding)(GLuint, GLuint, GLuint); +#define glUniformBlockBinding _ptrc_glUniformBlockBinding + +extern GLenum (CODEGEN_FUNCPTR *_ptrc_glClientWaitSync)(GLsync, GLbitfield, GLuint64); +#define glClientWaitSync _ptrc_glClientWaitSync +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteSync)(GLsync); +#define glDeleteSync _ptrc_glDeleteSync +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsBaseVertex)(GLenum, GLsizei, GLenum, const GLvoid *, GLint); +#define glDrawElementsBaseVertex _ptrc_glDrawElementsBaseVertex +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstancedBaseVertex)(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei, GLint); +#define glDrawElementsInstancedBaseVertex _ptrc_glDrawElementsInstancedBaseVertex +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawRangeElementsBaseVertex)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint); +#define glDrawRangeElementsBaseVertex _ptrc_glDrawRangeElementsBaseVertex +extern GLsync (CODEGEN_FUNCPTR *_ptrc_glFenceSync)(GLenum, GLbitfield); +#define glFenceSync _ptrc_glFenceSync +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferTexture)(GLenum, GLenum, GLuint, GLint); +#define glFramebufferTexture _ptrc_glFramebufferTexture +extern void (CODEGEN_FUNCPTR *_ptrc_glGetBufferParameteri64v)(GLenum, GLenum, GLint64 *); +#define glGetBufferParameteri64v _ptrc_glGetBufferParameteri64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetInteger64i_v)(GLenum, GLuint, GLint64 *); +#define glGetInteger64i_v _ptrc_glGetInteger64i_v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetInteger64v)(GLenum, GLint64 *); +#define glGetInteger64v _ptrc_glGetInteger64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetMultisamplefv)(GLenum, GLuint, GLfloat *); +#define glGetMultisamplefv _ptrc_glGetMultisamplefv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetSynciv)(GLsync, GLenum, GLsizei, GLsizei *, GLint *); +#define glGetSynciv _ptrc_glGetSynciv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsSync)(GLsync); +#define glIsSync _ptrc_glIsSync +extern void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawElementsBaseVertex)(GLenum, const GLsizei *, GLenum, const GLvoid *const*, GLsizei, const GLint *); +#define glMultiDrawElementsBaseVertex _ptrc_glMultiDrawElementsBaseVertex +extern void (CODEGEN_FUNCPTR *_ptrc_glProvokingVertex)(GLenum); +#define glProvokingVertex _ptrc_glProvokingVertex +extern void (CODEGEN_FUNCPTR *_ptrc_glSampleMaski)(GLuint, GLbitfield); +#define glSampleMaski _ptrc_glSampleMaski +extern void (CODEGEN_FUNCPTR *_ptrc_glTexImage2DMultisample)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean); +#define glTexImage2DMultisample _ptrc_glTexImage2DMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glTexImage3DMultisample)(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean); +#define glTexImage3DMultisample _ptrc_glTexImage3DMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glWaitSync)(GLsync, GLbitfield, GLuint64); +#define glWaitSync _ptrc_glWaitSync + +extern void (CODEGEN_FUNCPTR *_ptrc_glBindFragDataLocationIndexed)(GLuint, GLuint, GLuint, const GLchar *); +#define glBindFragDataLocationIndexed _ptrc_glBindFragDataLocationIndexed +extern void (CODEGEN_FUNCPTR *_ptrc_glBindSampler)(GLuint, GLuint); +#define glBindSampler _ptrc_glBindSampler +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteSamplers)(GLsizei, const GLuint *); +#define glDeleteSamplers _ptrc_glDeleteSamplers +extern void (CODEGEN_FUNCPTR *_ptrc_glGenSamplers)(GLsizei, GLuint *); +#define glGenSamplers _ptrc_glGenSamplers +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetFragDataIndex)(GLuint, const GLchar *); +#define glGetFragDataIndex _ptrc_glGetFragDataIndex +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjecti64v)(GLuint, GLenum, GLint64 *); +#define glGetQueryObjecti64v _ptrc_glGetQueryObjecti64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryObjectui64v)(GLuint, GLenum, GLuint64 *); +#define glGetQueryObjectui64v _ptrc_glGetQueryObjectui64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameterIiv)(GLuint, GLenum, GLint *); +#define glGetSamplerParameterIiv _ptrc_glGetSamplerParameterIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameterIuiv)(GLuint, GLenum, GLuint *); +#define glGetSamplerParameterIuiv _ptrc_glGetSamplerParameterIuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameterfv)(GLuint, GLenum, GLfloat *); +#define glGetSamplerParameterfv _ptrc_glGetSamplerParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetSamplerParameteriv)(GLuint, GLenum, GLint *); +#define glGetSamplerParameteriv _ptrc_glGetSamplerParameteriv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsSampler)(GLuint); +#define glIsSampler _ptrc_glIsSampler +extern void (CODEGEN_FUNCPTR *_ptrc_glQueryCounter)(GLuint, GLenum); +#define glQueryCounter _ptrc_glQueryCounter +extern void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterIiv)(GLuint, GLenum, const GLint *); +#define glSamplerParameterIiv _ptrc_glSamplerParameterIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterIuiv)(GLuint, GLenum, const GLuint *); +#define glSamplerParameterIuiv _ptrc_glSamplerParameterIuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterf)(GLuint, GLenum, GLfloat); +#define glSamplerParameterf _ptrc_glSamplerParameterf +extern void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameterfv)(GLuint, GLenum, const GLfloat *); +#define glSamplerParameterfv _ptrc_glSamplerParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameteri)(GLuint, GLenum, GLint); +#define glSamplerParameteri _ptrc_glSamplerParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glSamplerParameteriv)(GLuint, GLenum, const GLint *); +#define glSamplerParameteriv _ptrc_glSamplerParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribDivisor)(GLuint, GLuint); +#define glVertexAttribDivisor _ptrc_glVertexAttribDivisor +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP1ui)(GLuint, GLenum, GLboolean, GLuint); +#define glVertexAttribP1ui _ptrc_glVertexAttribP1ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP1uiv)(GLuint, GLenum, GLboolean, const GLuint *); +#define glVertexAttribP1uiv _ptrc_glVertexAttribP1uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP2ui)(GLuint, GLenum, GLboolean, GLuint); +#define glVertexAttribP2ui _ptrc_glVertexAttribP2ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP2uiv)(GLuint, GLenum, GLboolean, const GLuint *); +#define glVertexAttribP2uiv _ptrc_glVertexAttribP2uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP3ui)(GLuint, GLenum, GLboolean, GLuint); +#define glVertexAttribP3ui _ptrc_glVertexAttribP3ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP3uiv)(GLuint, GLenum, GLboolean, const GLuint *); +#define glVertexAttribP3uiv _ptrc_glVertexAttribP3uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4ui)(GLuint, GLenum, GLboolean, GLuint); +#define glVertexAttribP4ui _ptrc_glVertexAttribP4ui +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4uiv)(GLuint, GLenum, GLboolean, const GLuint *); +#define glVertexAttribP4uiv _ptrc_glVertexAttribP4uiv + +enum ogl_LoadStatus +{ + ogl_LOAD_FAILED = 0, + ogl_LOAD_SUCCEEDED = 1, +}; + +int ogl_LoadFunctions(); + +int ogl_GetMinorVersion(); +int ogl_GetMajorVersion(); +int ogl_IsVersionGEQ(int majorVersion, int minorVersion); + +#ifdef __cplusplus +} +#endif /*__cplusplus*/ + +#endif //POINTER_C_GENERATED_HEADER_OPENGL_H diff --git a/src/gl/system/gl_menu.cpp b/src/gl/system/gl_menu.cpp index 2ec515300..a9167b7a6 100644 --- a/src/gl/system/gl_menu.cpp +++ b/src/gl/system/gl_menu.cpp @@ -57,64 +57,4 @@ CUSTOM_CVAR (Float, vid_contrast, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // when they are actually valid. void gl_SetupMenu() { - if (gl.shadermodel < 4) - { - // Radial fog and Doom lighting are not available in SM < 4 cards - // The way they are implemented does not work well on older hardware. - - FOptionValues **opt = OptionValues.CheckKey("LightingModes"); - if (opt != NULL) - { - for(int i = (*opt)->mValues.Size()-1; i>=0; i--) - { - // Delete 'Doom' lighting mode - if ((*opt)->mValues[i].Value == 2.0 || (*opt)->mValues[i].Value == 8.0) - { - (*opt)->mValues.Delete(i); - } - } - } - - opt = OptionValues.CheckKey("FogMode"); - if (opt != NULL) - { - for(int i = (*opt)->mValues.Size()-1; i>=0; i--) - { - // Delete 'Radial' fog mode - if ((*opt)->mValues[i].Value == 2.0) - { - (*opt)->mValues.Delete(i); - } - } - } - - // disable features that don't work without shaders. - if (gl_lightmode == 2 || gl_lightmode == 8) gl_lightmode = 3; - if (gl_fogmode == 2) gl_fogmode = 1; - if (gl_dynlight_shader) gl_dynlight_shader = false; - } - - if (gl.shadermodel != 3) - { - // The shader menu will only be visible on SM3. - // SM2 won't use shaders unless unavoidable (and then it's automatic) and SM4 will always use shaders. - // Find the OpenGLOptions menu and remove the item named GLShaderOptions. - - FMenuDescriptor **desc = MenuDescriptors.CheckKey("OpenGLOptions"); - if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) - { - FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; - - FName shader = "GLShaderOptions"; - for(unsigned i=0;imItems.Size();i++) - { - FName nm = opt->mItems[i]->GetAction(NULL); - if (nm == shader) - { - delete opt->mItems[i]; - opt->mItems.Delete(i); - } - } - } - } } diff --git a/src/gl/system/gl_system.h b/src/gl/system/gl_system.h index 8140904a2..5cfd7fe5c 100644 --- a/src/gl/system/gl_system.h +++ b/src/gl/system/gl_system.h @@ -67,16 +67,10 @@ #include //GL headers -#include +#include "gl_load.h" #if defined(__APPLE__) #include -#elif defined(__unix__) - //#include -#else // !__APPLE__ && !__unix__ - #define DWORD WINDOWS_DWORD // I don't want to depend on this throughout the GL code! - #include - #undef DWORD #endif #ifdef _WIN32 diff --git a/src/gl/system/gl_threads.h b/src/gl/system/gl_threads.h deleted file mode 100644 index 68919776c..000000000 --- a/src/gl/system/gl_threads.h +++ /dev/null @@ -1,247 +0,0 @@ -#if 0 //ndef __GL_THREADS_H -#define __GL_THREADS_H - -#ifdef WIN32 -#include -#endif - -#include "critsec.h" - -// system specific Base classes - should be externalized to a separate header later. -#ifdef WIN32 -class FEvent -{ - HANDLE mEvent; - -public: - - FEvent(bool manual = true, bool initial = false) - { - mEvent = CreateEvent(NULL, manual, initial, NULL); - } - - ~FEvent() - { - CloseHandle(mEvent); - } - - void Set() - { - SetEvent(mEvent); - } - - void Reset() - { - ResetEvent(mEvent); - } -}; - -class FThread -{ -protected: - uintptr_t hThread; - bool mTerminateRequest; -public: - - FThread(int stacksize) - { - hThread = _beginthreadex(NULL, stacksize, StaticRun, this, 0, NULL); - } - - virtual ~FThread() - { - CloseHandle((HANDLE)hThread); - } - - void SignalTerminate() - { - mTerminateRequest = true; - } - - virtual void Run() = 0; - -private: - static unsigned __stdcall StaticRun(void *param) - { - FThread *thread = (FThread*)param; - thread->Run(); - return 0; - } - -}; - -#else -class FEvent -{ -public: - - FEvent(bool manual = true, bool initial = false) - { - } - - ~FEvent() - { - } - - void Set() - { - } - - void Reset() - { - } -}; - -class FThread -{ -protected: - bool mTerminateRequest; -public: - - FThread(int stacksize) - { - } - - virtual ~FThread() - { - } - - void SignalTerminate() - { - mTerminateRequest = true; - } - - virtual void Run() = 0; -}; - -#endif - - - -enum -{ - CS_ValidateTexture, - CS_Hacks, - CS_Drawlist, - CS_Portals, - - MAX_GL_CRITICAL_SECTIONS -}; - -class FJob -{ - friend class FJobQueue; - FJob *pNext; - FJob *pPrev; - -public: - FJob() { pNext = pPrev = NULL; } - virtual ~FJob(); - virtual void Run() = 0; -}; - -class FJobQueue -{ - FCriticalSection mCritSec; // for limiting access - FEvent mEvent; // signals that the queue is emoty or not - FJob *pFirst; - FJob *pLast; - -public: - FJobQueue(); - ~FJobQueue(); - - void AddJob(FJob *job); - FJob *GetJob(); -}; - -class FJobThread : public FThread -{ - FJobQueue *mQueue; - -public: - FJobThread(FJobQueue *queue); - ~FJobThread(); - void Run(); -}; - -class FGLJobProcessWall : public FJob -{ - seg_t *mSeg; - subsector_t *mSub; - int mFrontsector, mBacksector; -public: - FGLJobProcessWall(seg_t *seg, subsector_t *sub, int frontsector, int backsector) - { - mSeg = seg; - mSub = sub; - mFrontsector = frontsector; - mBacksector = backsector; - } - - void Run(); -}; - -class FGLJobProcessSprites : public FJob -{ - sector_t *mSector; -public: - FGLJobProcessSprites(sector_t *sector); - void Run(); -}; - -class FGLJobProcessParticles : public FJob -{ - subsector_t *mSubsector; -public: - FGLJobProcessParticles(subsector_t *subsector); - void Run(); -}; - -class FGLJobProcessFlats : public FJob -{ - subsector_t *mSubsector; -public: - FGLJobProcessFlats(subsector_t *subsector); - void Run(); -}; - - -class FGLThreadManager -{ -#if 0 - FCriticalSection mCritSecs[MAX_GL_CRITICAL_SECTIONS]; - FJobQueue mJobs; - FJobThread *mThreads[2]; - -public: - FGLThreadManager() {} - ~FGLThreadManager() {} - - void StartJobs(); - - void PauseJobs(); - - void EnterCS(int index) - { - mCritSecs[index].Enter(); - } - - void LeaveCS(int index) - { - mCritSecs[index].Leave(); - } - - void AddJob(FJob *job) - { - mJobs.AddJob(job); - } - - FJob *GetJob() - { - return mJobs.GetJob(); - } -#endif -}; - -#endif \ No newline at end of file diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index c41a1fb24..30a996816 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -53,9 +53,12 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/system/gl_framebuffer.h" +#include "gl/shaders/gl_shader.h" #include "gl/textures/gl_translate.h" #include "gl/textures/gl_material.h" +#include "gl/textures/gl_samplers.h" #include "gl/utility/gl_templates.h" +#include "gl/data/gl_vertexbuffer.h" #ifndef _WIN32 struct POINT { @@ -144,13 +147,13 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) return false; } - wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true); - wipestartscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT); + wipestartscreen = new FHardwareTexture(Width, Height, true); + wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0); + GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); + GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE); glFinish(); - wipestartscreen->Bind(0, CM_DEFAULT); + wipestartscreen->Bind(0, false, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -167,10 +170,11 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) void OpenGLFrameBuffer::WipeEndScreen() { - wipeendscreen = new FHardwareTexture(Width, Height, false, false, false, true); - wipeendscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT); - glFlush(); - wipeendscreen->Bind(0, CM_DEFAULT); + wipeendscreen = new FHardwareTexture(Width, Height, true); + wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0); + GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); + glFinish(); + wipeendscreen->Bind(0, false, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -237,6 +241,7 @@ void OpenGLFrameBuffer::WipeCleanup() delete wipeendscreen; wipeendscreen = NULL; } + FMaterial::ClearLastTexture(); } //========================================================================== @@ -278,34 +283,29 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight()); gl_RenderState.SetTextureMode(TM_OPAQUE); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, CM_DEFAULT); - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0, vb); - glVertex2i(0, 0); - glTexCoord2f(0, 0); - glVertex2i(0, fb->Height); - glTexCoord2f(ur, vb); - glVertex2i(fb->Width, 0); - glTexCoord2f(ur, 0); - glVertex2i(fb->Width, fb->Height); - glEnd(); + fb->wipestartscreen->Bind(0, 0, false); - fb->wipeendscreen->Bind(0, CM_DEFAULT); - glColor4f(1.f, 1.f, 1.f, clamp(Clock/32.f, 0.f, 1.f)); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0, vb); - glVertex2i(0, 0); - glTexCoord2f(0, 0); - glVertex2i(0, fb->Height); - glTexCoord2f(ur, vb); - glVertex2i(fb->Width, 0); - glTexCoord2f(ur, 0); - glVertex2i(fb->Width, fb->Height); - glEnd(); - gl_RenderState.EnableAlphaTest(true); + FFlatVertex *ptr; + unsigned int offset, count; + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(0, 0, 0, 0, vb); + ptr++; + ptr->Set(0, fb->Height, 0, 0, 0); + ptr++; + ptr->Set(fb->Width, 0, 0, ur, vb); + ptr++; + ptr->Set(fb->Width, fb->Height, 0, ur, 0); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); + + fb->wipeendscreen->Bind(0, 0, false); + gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f)); + gl_RenderState.Apply(); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); gl_RenderState.SetTextureMode(TM_MODULATE); return Clock >= 32; @@ -346,24 +346,25 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) // Draw the new screen on the bottom. gl_RenderState.SetTextureMode(TM_OPAQUE); + gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipeendscreen->Bind(0, CM_DEFAULT); - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0, vb); - glVertex2i(0, 0); - glTexCoord2f(0, 0); - glVertex2i(0, fb->Height); - glTexCoord2f(ur, vb); - glVertex2i(fb->Width, 0); - glTexCoord2f(ur, 0); - glVertex2i(fb->Width, fb->Height); - glEnd(); + fb->wipeendscreen->Bind(0, 0, false); + FFlatVertex *ptr; + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(0, 0, 0, 0, vb); + ptr++; + ptr->Set(0, fb->Height, 0, 0, 0); + ptr++; + ptr->Set(fb->Width, 0, 0, ur, vb); + ptr++; + ptr->Set(fb->Width, fb->Height, 0, ur, 0); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); int i, dy; bool done = false; - fb->wipestartscreen->Bind(0, CM_DEFAULT); + fb->wipestartscreen->Bind(0, 0, false); // Copy the old screen in vertical strips on top of the new one. while (ticks--) { @@ -382,7 +383,9 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) done = false; } if (ticks == 0) - { // Only draw for the final tick. + { + // Only draw for the final tick. + // No need for optimization. Wipes won't ever be drawn with anything else. RECT rect; POINT dpt; @@ -398,17 +401,17 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) float th = (float)FHardwareTexture::GetTexDimension(fb->Height); rect.bottom = fb->Height - rect.bottom; rect.top = fb->Height - rect.top; - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(rect.left / tw, rect.top / th); - glVertex2i(rect.left, rect.bottom); - glTexCoord2f(rect.left / tw, rect.bottom / th); - glVertex2i(rect.left, rect.top); - glTexCoord2f(rect.right / tw, rect.top / th); - glVertex2i(rect.right, rect.bottom); - glTexCoord2f(rect.right / tw, rect.bottom / th); - glVertex2i(rect.right, rect.top); - glEnd(); + + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(rect.left, rect.bottom, 0, rect.left / tw, rect.top / th); + ptr++; + ptr->Set(rect.left, rect.top, 0, rect.left / tw, rect.bottom / th); + ptr++; + ptr->Set(rect.right, rect.bottom, 0, rect.right / tw, rect.top / th); + ptr++; + ptr->Set(rect.right, rect.top, 0, rect.right / tw, rect.bottom / th); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } } } @@ -468,7 +471,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) } if (BurnTexture != NULL) delete BurnTexture; - BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, false, false, false, true); + BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, true); // Update the burn texture with the new burn data BYTE rgb_buffer[WIDTH*HEIGHT*4]; @@ -490,68 +493,35 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) // Put the initial screen back to the buffer. gl_RenderState.SetTextureMode(TM_OPAQUE); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, CM_DEFAULT); - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0, vb); - glVertex2i(0, 0); - glTexCoord2f(0, 0); - glVertex2i(0, fb->Height); - glTexCoord2f(ur, vb); - glVertex2i(fb->Width, 0); - glTexCoord2f(ur, 0); - glVertex2i(fb->Width, fb->Height); - glEnd(); + fb->wipestartscreen->Bind(0, 0, false); + FFlatVertex *ptr; + unsigned int offset, count; + ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(0, 0, 0, 0, vb); + ptr++; + ptr->Set(0, fb->Height, 0, 0, 0); + ptr++; + ptr->Set(fb->Width, 0, 0, ur, vb); + ptr++; + ptr->Set(fb->Width, fb->Height, 0, ur, 0); + ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); gl_RenderState.SetTextureMode(TM_MODULATE); - gl_RenderState.Apply(true); - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - - // mask out the alpha channel of the wipeendscreen. - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - - glActiveTexture(GL_TEXTURE0); + gl_RenderState.SetEffect(EFF_BURN); + gl_RenderState.ResetColor(); + gl_RenderState.Apply(); // Burn the new screen on top of it. - glColor4f(1.f, 1.f, 1.f, 1.f); - fb->wipeendscreen->Bind(1, CM_DEFAULT); - //BurnTexture->Bind(0, CM_DEFAULT); + fb->wipeendscreen->Bind(0, 0, false); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0, CM_DEFAULT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0); - - glBegin(GL_TRIANGLE_STRIP); - glMultiTexCoord2f(GL_TEXTURE0, 0, 0); - glMultiTexCoord2f(GL_TEXTURE1, 0, vb); - glVertex2i(0, 0); - glMultiTexCoord2f(GL_TEXTURE0, 0, 1); - glMultiTexCoord2f(GL_TEXTURE1, 0, 0); - glVertex2i(0, fb->Height); - glMultiTexCoord2f(GL_TEXTURE0, 1, 0); - glMultiTexCoord2f(GL_TEXTURE1, ur, vb); - glVertex2i(fb->Width, 0); - glMultiTexCoord2f(GL_TEXTURE0, 1, 1); - glMultiTexCoord2f(GL_TEXTURE1, ur, 0); - glVertex2i(fb->Width, fb->Height); - glEnd(); - - glActiveTexture(GL_TEXTURE1); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); + gl_RenderState.SetEffect(EFF_NONE); // The fire may not always stabilize, so the wipe is forced to end // after an arbitrary maximum time. diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index d90fd36b7..a2319f67c 100644 --- a/src/gl/textures/gl_bitmap.cpp +++ b/src/gl/textures/gl_bitmap.cpp @@ -42,6 +42,7 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/textures/gl_translate.h" #include "gl/textures/gl_bitmap.h" +#include "gl/system/gl_interface.h" //=========================================================================== // @@ -50,74 +51,25 @@ // //=========================================================================== template -void iCopyColors(unsigned char * pout, const unsigned char * pin, int cm, int count, int step) +void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step) { int i; - int fac; - if (cm == CM_DEFAULT) + for(i=0;i= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size())) - { - for(i=0;i, @@ -147,57 +99,11 @@ void FGLBitmap::CopyPixelDataRGB(int originx, int originy, BYTE *buffer = GetPixels() + 4*originx + Pitch*originy; for (int y=0;y= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size())) - { - for(i=0;i> 8; - // This can be done in place so we cannot copy the color directly. - PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[gray]; - pout[i].r = pe.r; - pout[i].g = pe.g; - pout[i].b = pe.b; - pout[i].a = pin[i].a; - } - } - else if (cm<=CM_DESAT31) - { - // Desaturated light settings. - fac=cm-CM_DESAT0; - for(i=0;i>8; - gl_Desaturate(gray, pin[i].r, pin[i].g, pin[i].b, pout[i].r, pout[i].g, pout[i].b, fac); - pout[i].a = pin[i].a; - } - } - else if (pin!=pout) - { - memcpy(pout, pin, count * sizeof(PalEntry)); - } -} - - //=========================================================================== // // Paletted to True Color texture copy function @@ -214,48 +120,21 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int { BYTE *buffer = GetPixels() + 4*originx + Pitch*originy; - // CM_SHADE is an alpha map with 0==transparent and 1==opaque - if (cm == CM_SHADE) + if (translation > 0) { - for(int i=0;i<256;i++) + PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); + if (ptrans) { - if (palette[i].a != 0) - penew[i]=PalEntry(i, 255,255,255); - else - penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them. + for (i = 0; i < 256; i++) + { + penew[i] = (ptrans[i] & 0xffffff) | (palette[i] & 0xff000000); + } } } else { - // apply any translation. - // The ice and blood color translations are done directly - // because that yields better results. - switch(translation) - { - default: - { - PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); - if (ptrans) - { - for(i = 0; i < 256; i++) - { - penew[i] = (ptrans[i]&0xffffff) | (palette[i]&0xff000000); - } - break; - } - } - - case 0: - memcpy(penew, palette, 256*sizeof(PalEntry)); - break; - } - if (cm!=0) - { - // Apply color modifications like invulnerability, desaturation and Boom colormaps - ModifyPalette(penew, penew, cm, 256); - } + memcpy(penew, palette, 256*sizeof(PalEntry)); } - // Now penew contains the actual palette that is to be used for creating the image. // convert the image according to the translated palette. for (y=0;y(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-penew[v].a))/255, 0, 255); - } - */ } } } diff --git a/src/gl/textures/gl_bitmap.h b/src/gl/textures/gl_bitmap.h index db3722a6e..6aea6d008 100644 --- a/src/gl/textures/gl_bitmap.h +++ b/src/gl/textures/gl_bitmap.h @@ -5,22 +5,23 @@ #include "gl/textures/gl_material.h" -void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count); - class FGLBitmap : public FBitmap { - int cm; int translation; public: - FGLBitmap() { cm = CM_DEFAULT; translation = 0; } + FGLBitmap() + { + translation = 0; + } FGLBitmap(BYTE *buffer, int pitch, int width, int height) : FBitmap(buffer, pitch, width, height) - { cm = CM_DEFAULT; translation = 0; } - - void SetTranslationInfo(int _cm, int _trans=-1337) { - if (_cm != -1) cm = _cm; + translation = 0; + } + + void SetTranslationInfo(int _trans) + { if (_trans != -1337) translation = _trans; } diff --git a/src/gl/textures/gl_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp index 2c5f831f1..a4f192ce8 100644 --- a/src/gl/textures/gl_hqresize.cpp +++ b/src/gl/textures/gl_hqresize.cpp @@ -40,6 +40,9 @@ #include "gl/textures/gl_texture.h" #include "c_cvars.h" #include "gl/hqnx/hqx.h" +#ifdef _MSC_VER +#include "gl/hqnx_asm/hqnx_asm.h" +#endif CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { @@ -179,6 +182,38 @@ static unsigned char *scaleNxHelper( void (*scaleNxFunction) ( uint32* , uint32* return newBuffer; } +// [BB] hqnx scaling is only supported with the MS compiler. +#ifdef _MSC_VER +static unsigned char *hqNxAsmHelper( void (*hqNxFunction) ( int*, unsigned char*, int, int, int ), + const int N, + unsigned char *inputBuffer, + const int inWidth, + const int inHeight, + int &outWidth, + int &outHeight ) +{ + outWidth = N * inWidth; + outHeight = N *inHeight; + + static int initdone = false; + + if (!initdone) + { + HQnX_asm::InitLUTs(); + initdone = true; + } + + HQnX_asm::CImage cImageIn; + cImageIn.SetImage(inputBuffer, inWidth, inHeight, 32); + cImageIn.Convert32To17(); + + unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4]; + hqNxFunction( reinterpret_cast(cImageIn.m_pBitmap), newBuffer, cImageIn.m_Xres, cImageIn.m_Yres, outWidth*4 ); + delete[] inputBuffer; + return newBuffer; +} +#endif + static unsigned char *hqNxHelper( void (*hqNxFunction) ( unsigned*, unsigned*, int, int ), const int N, unsigned char *inputBuffer, @@ -203,6 +238,7 @@ static unsigned char *hqNxHelper( void (*hqNxFunction) ( unsigned*, unsigned*, i return newBuffer; } + //=========================================================================== // // [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns @@ -224,10 +260,6 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u if ( inputTexture->bHasCanvas ) return inputBuffer; - // [BB] Don't upsample non-shader handled warped textures. Needs too much memory and time - if (gl.shadermodel == 2 || (gl.shadermodel == 3 && inputTexture->bWarped)) - return inputBuffer; - switch (inputTexture->UseType) { case FTexture::TEX_Sprite: @@ -249,11 +281,11 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u outWidth = inWidth; outHeight = inHeight; int type = gl_texture_hqresize; -#if 0 - // hqNx does not preserve the alpha channel so fall back to ScaleNx for such textures - if (hasAlpha && type > 3) +#ifdef _MSC_VER + // ASM-hqNx does not preserve the alpha channel so fall back to C-version for such textures + if (!hasAlpha && type > 3 && type <= 6) { - type -= 3; + type += 3; } #endif @@ -271,6 +303,14 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u return hqNxHelper( &hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); case 6: return hqNxHelper( &hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); +#ifdef _MSC_VER + case 7: + return hqNxAsmHelper( &HQnX_asm::hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + case 8: + return hqNxAsmHelper( &HQnX_asm::hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + case 9: + return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); +#endif } } return inputBuffer; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 648bac770..c855ef285 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -4,7 +4,7 @@ ** containers for the various translations a texture can have. ** **--------------------------------------------------------------------------- -** Copyright 2004-2005 Christoph Oelckers +** Copyright 2004-2014 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -54,7 +54,6 @@ extern TexFilter_s TexFilter[]; extern int TexFormat[]; -EXTERN_CVAR(Bool, gl_clamp_per_texture) //=========================================================================== @@ -174,6 +173,7 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un } + //=========================================================================== // // Loads the texture image into the hardware @@ -183,18 +183,22 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un // strange crashes deep inside the GL driver when I didn't do it! // //=========================================================================== -void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit) + +unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation) { int rh,rw; int texformat=TexFormat[gl_texture_format]; bool deletebuffer=false; - bool use_mipmapping = TexFilter[gl_texture_filter].mipmapping; - if (alphatexture) texformat=GL_ALPHA8; - else if (forcenocompression) texformat = GL_RGBA8; - if (glTexID==0) glGenTextures(1,&glTexID); - glBindTexture(GL_TEXTURE_2D, glTexID); - lastbound[texunit]=glTexID; + if (forcenocompression) + { + texformat = GL_RGBA8; + } + TranslatedTexture * glTex=GetTexID(translation); + if (glTex->glTexID==0) glGenTextures(1,&glTex->glTexID); + if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); + glBindTexture(GL_TEXTURE_2D, glTex->glTexID); + lastbound[texunit] = glTex->glTexID; if (!buffer) { @@ -204,8 +208,7 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i rh = GetTexDimension (h); // The texture must at least be initialized if no data is present. - mipmap=false; - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, false); + glTex->mipmapped = false; buffer=(unsigned char *)calloc(4,rw * (rh+1)); deletebuffer=true; //texheight=-h; @@ -215,8 +218,6 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i rw = GetTexDimension (w); rh = GetTexDimension (h); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (mipmap && use_mipmapping && !forcenofiltering)); - if (rw < w || rh < h) { // The texture is larger than what the hardware can handle so scale it down. @@ -233,35 +234,14 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i if (deletebuffer) free(buffer); - // When using separate samplers the stuff below is not needed. - // if (gl.flags & RFL_SAMPLER_OBJECTS) return; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapparam==GL_CLAMP? GL_CLAMP_TO_EDGE : GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapparam==GL_CLAMP? GL_CLAMP_TO_EDGE : GL_REPEAT); - clampmode = wrapparam==GL_CLAMP? GLT_CLAMPX|GLT_CLAMPY : 0; - - if (forcenofiltering) + if (mipmap && TexFilter[gl_texture_filter].mipmapping) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); - } - else - { - if (mipmap && use_mipmapping) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - if (gl_texture_filter_anisotropic) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); - } - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glGenerateMipmap(GL_TEXTURE_2D); + glTex->mipmapped = true; } + + if (texunit != 0) glActiveTexture(GL_TEXTURE0); + return glTex->glTexID; } @@ -270,19 +250,16 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i // Creates a texture // //=========================================================================== -FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool wrap, bool nofilter, bool nocompression) +FHardwareTexture::FHardwareTexture(int _width, int _height, bool nocompression) { forcenocompression = nocompression; - mipmap=_mipmap; texwidth=_width; texheight=_height; - int cm_arraysize = CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size(); - glTexID = new unsigned[cm_arraysize]; - memset(glTexID,0,sizeof(unsigned int)*cm_arraysize); - clampmode=0; + glDefTex.glTexID = 0; + glDefTex.translation = 0; + glDefTex.mipmapped = false; glDepthID = 0; - forcenofiltering = nofilter; } @@ -291,18 +268,20 @@ FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool w // Deletes a texture id and unbinds it from the texture units // //=========================================================================== -void FHardwareTexture::DeleteTexture(unsigned int texid) +void FHardwareTexture::TranslatedTexture::Delete() { - if (texid != 0) + if (glTexID != 0) { for(int i = 0; i < MAX_TEXTURES; i++) { - if (lastbound[i] == texid) + if (lastbound[i] == glTexID) { lastbound[i] = 0; } } - glDeleteTextures(1, &texid); + glDeleteTextures(1, &glTexID); + glTexID = 0; + mipmapped = false; } } @@ -317,27 +296,13 @@ void FHardwareTexture::Clean(bool all) if (all) { - for (int i=0;i= CM_MAXCOLORMAP) cm=CM_DEFAULT; - - if (translation==0) + if (translation == 0) { - return &glTexID[cm]; + return &glDefTex; } // normally there aren't more than very few different // translations here so this isn't performance critical. - for(unsigned int i=0;iglTexID != 0) { - if (lastbound[texunit]==*pTexID) return *pTexID; - lastbound[texunit]=*pTexID; - if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); - glBindTexture(GL_TEXTURE_2D, *pTexID); + if (lastbound[texunit] == pTex->glTexID) return pTex->glTexID; + lastbound[texunit] = pTex->glTexID; + if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit); + glBindTexture(GL_TEXTURE_2D, pTex->glTexID); + // Check if we need mipmaps on a texture that was creted without them. + if (needmipmap && !pTex->mipmapped && TexFilter[gl_texture_filter].mipmapping) + { + glGenerateMipmap(GL_TEXTURE_2D); + pTex->mipmapped = true; + } if (texunit != 0) glActiveTexture(GL_TEXTURE0); - return *pTexID; + return pTex->glTexID; } return 0; } @@ -425,6 +392,7 @@ void FHardwareTexture::UnbindAll() { Unbind(texunit); } + FMaterial::ClearLastTexture(); } //=========================================================================== @@ -435,19 +403,15 @@ void FHardwareTexture::UnbindAll() int FHardwareTexture::GetDepthBuffer() { - if (gl.flags & RFL_FRAMEBUFFER) + if (glDepthID == 0) { - if (glDepthID == 0) - { - glGenRenderbuffers(1, &glDepthID); - glBindRenderbuffer(GL_RENDERBUFFER, glDepthID); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, - GetTexDimension(texwidth), GetTexDimension(texheight)); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - } - return glDepthID; + glGenRenderbuffers(1, &glDepthID); + glBindRenderbuffer(GL_RENDERBUFFER, glDepthID); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, + GetTexDimension(texwidth), GetTexDimension(texheight)); + glBindRenderbuffer(GL_RENDERBUFFER, 0); } - return 0; + return glDepthID; } @@ -459,30 +423,7 @@ int FHardwareTexture::GetDepthBuffer() void FHardwareTexture::BindToFrameBuffer() { - if (gl.flags & RFL_FRAMEBUFFER) - { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexID[0], 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); - } + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTex.glTexID, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); } - -//=========================================================================== -// -// (re-)creates the texture -// -//=========================================================================== -unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, bool wrap, int texunit, - int cm, int translation) -{ - if (cm < 0 || cm >= CM_MAXCOLORMAP) cm=CM_DEFAULT; - - unsigned int * pTexID=GetTexID(cm, translation); - - if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); - LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, cm==CM_SHADE, texunit); - if (texunit != 0) glActiveTexture(GL_TEXTURE0); - return *pTexID; -} - - diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 5b5e55ac5..7fa0f0580 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -2,6 +2,10 @@ #ifndef __GLTEXTURE_H #define __GLTEXTURE_H +#ifdef LoadImage +#undef LoadImage +#endif + #define SHADED_TEXTURE -1 #define DIRECT_PALETTE -2 @@ -10,6 +14,12 @@ class FCanvasTexture; class AActor; +// For error catching while changing parameters. +enum EInvalid +{ + Invalid = 0 +}; + enum { GLT_CLAMPX=1, @@ -18,23 +28,26 @@ enum class FHardwareTexture { +public: enum { MAX_TEXTURES = 16 }; +private: struct TranslatedTexture { unsigned int glTexID; int translation; - int cm; + bool mipmapped; + + void Delete(); }; public: static unsigned int lastbound[MAX_TEXTURES]; static int lastactivetexture; - static bool supportsNonPower2; static int max_texturesize; static int GetTexDimension(int value); @@ -42,25 +55,19 @@ public: private: short texwidth, texheight; - //float scalexfac, scaleyfac; - bool mipmap; - BYTE clampmode; - bool forcenofiltering; bool forcenocompression; - unsigned int * glTexID; - TArray glTexID_Translated; + TranslatedTexture glDefTex; + TArray glTex_Translated; unsigned int glDepthID; // only used by camera textures - void LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit); - unsigned * GetTexID(int cm, int translation); + TranslatedTexture * GetTexID(int translation); int GetDepthBuffer(); - void DeleteTexture(unsigned int texid); void Resize(int width, int height, unsigned char *src_data, unsigned char *dst_data); public: - FHardwareTexture(int w, int h, bool mip, bool wrap, bool nofilter, bool nocompress); + FHardwareTexture(int w, int h, bool nocompress); ~FHardwareTexture(); static void Unbind(int texunit); @@ -68,9 +75,8 @@ public: void BindToFrameBuffer(); - unsigned int Bind(int texunit, int cm, int translation=0); - unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int cm, int translation=0); - void Resize(int _width, int _height) ; + unsigned int Bind(int texunit, int translation, bool needmipmap); + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation); void Clean(bool all); }; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 500a0afab..6b22e0a5e 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -53,11 +53,13 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/renderer/gl_lightdata.h" +#include "gl/renderer/gl_renderer.h" #include "gl/data/gl_data.h" #include "gl/textures/gl_texture.h" #include "gl/textures/gl_translate.h" #include "gl/textures/gl_bitmap.h" #include "gl/textures/gl_material.h" +#include "gl/textures/gl_samplers.h" #include "gl/shaders/gl_shader.h" EXTERN_CVAR(Bool, gl_render_precise) @@ -78,18 +80,16 @@ EXTERN_CVAR(Bool, gl_texture_usehires) //=========================================================================== FGLTexture::FGLTexture(FTexture * tx, bool expandpatches) { - assert(tx->gl_info.SystemTexture == NULL); + assert(tx->gl_info.SystemTexture[expandpatches] == NULL); tex = tx; - glpatch=NULL; - for(int i=0;i<5;i++) gltexture[i]=NULL; - HiresLump=-1; + mHwTexture = NULL; + HiresLump = -1; hirestexture = NULL; - currentwarp = 0; bHasColorkey = false; bIsTransparent = -1; bExpand = expandpatches; - tex->gl_info.SystemTexture = this; + tex->gl_info.SystemTexture[expandpatches] = this; } //=========================================================================== @@ -109,7 +109,7 @@ FGLTexture::~FGLTexture() // Checks for the presence of a hires texture replacement and loads it // //========================================================================== -unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height, int cm) +unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height) { if (HiresLump==-1) { @@ -131,8 +131,6 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig memset(buffer, 0, w * (h+1) * 4); FGLBitmap bmp(buffer, w*4, w, h); - bmp.SetTranslationInfo(cm); - int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); hirestexture->CheckTrans(buffer, w*h, trans); @@ -163,107 +161,17 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig void FGLTexture::Clean(bool all) { - for(int i=0;i<5;i++) + if (mHwTexture) { - if (gltexture[i]) - { - if (!all) gltexture[i]->Clean(false); - else - { - delete gltexture[i]; - gltexture[i]=NULL; - } - } - } - if (glpatch) - { - if (!all) glpatch->Clean(false); + if (!all) mHwTexture->Clean(false); else { - delete glpatch; - glpatch=NULL; + delete mHwTexture; + mHwTexture = NULL; } } } -//=========================================================================== -// -// FGLTex::WarpBuffer -// -//=========================================================================== - -BYTE *FGLTexture::WarpBuffer(BYTE *buffer, int Width, int Height, int warp) -{ - if (Width > 256 || Height > 256) return buffer; - - DWORD *in = (DWORD*)buffer; - DWORD *out = (DWORD*)new BYTE[4*Width*Height]; - float Speed = static_cast(tex)->GetSpeed(); - - static_cast(tex)->GenTime = r_FrameTime; - - static DWORD linebuffer[256]; // anything larger will bring down performance so it is excluded above. - DWORD timebase = DWORD(r_FrameTime*Speed*23/28); - int xsize = Width; - int ysize = Height; - int xmask = xsize - 1; - int ymask = ysize - 1; - int ds_xbits; - int i,x; - - if (warp == 1) - { - for(ds_xbits=-1,i=Width; i; i>>=1, ds_xbits++); - - for (x = xsize-1; x >= 0; x--) - { - int yt, yf = (finesine[(timebase+(x+17)*128)&FINEMASK]>>13) & ymask; - const DWORD *source = in + x; - DWORD *dest = out + x; - for (yt = ysize; yt; yt--, yf = (yf+1)&ymask, dest += xsize) - { - *dest = *(source+(yf<= 0; y--) - { - int xt, xf = (finesine[(timebase+y*128)&FINEMASK]>>13) & xmask; - DWORD *source = out + (y<>=1, ybits++); - - DWORD timebase = (r_FrameTime * Speed * 40 / 28); - for (x = xsize-1; x >= 0; x--) - { - for (int y = ysize-1; y >= 0; y--) - { - int xt = (x + 128 - + ((finesine[(y*128 + timebase*5 + 900) & 8191]*2)>>FRACBITS) - + ((finesine[(x*256 + timebase*4 + 300) & 8191]*2)>>FRACBITS)) & xmask; - int yt = (y + 128 - + ((finesine[(y*128 + timebase*3 + 700) & 8191]*2)>>FRACBITS) - + ((finesine[(x*256 + timebase*4 + 1200) & 8191]*2)>>FRACBITS)) & ymask; - const DWORD *source = in + (xt << ybits) + yt; - DWORD *dest = out + (x << ybits) + y; - *dest = *source; - } - } - } - delete [] buffer; - return (BYTE*)out; -} //=========================================================================== // @@ -271,7 +179,7 @@ BYTE *FGLTexture::WarpBuffer(BYTE *buffer, int Width, int Height, int warp) // //=========================================================================== -unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp) +unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck) { unsigned char * buffer; int W, H; @@ -281,22 +189,22 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in // by hires textures if (gl_texture_usehires && hirescheck != NULL) { - buffer = LoadHiresTexture (hirescheck, &w, &h, cm); + buffer = LoadHiresTexture (hirescheck, &w, &h); if (buffer) { return buffer; } } - W = w = tex->GetWidth() + expand*2; - H = h = tex->GetHeight() + expand*2; + W = w = tex->GetWidth() + bExpand*2; + H = h = tex->GetHeight() + bExpand*2; buffer=new unsigned char[W*(H+1)*4]; memset(buffer, 0, W * (H+1) * 4); FGLBitmap bmp(buffer, W*4, W, H); - bmp.SetTranslationInfo(cm, translation); + bmp.SetTranslationInfo(translation); if (tex->bComplex) { @@ -307,7 +215,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in if (imgCreate.Create(W, H)) { memset(imgCreate.GetPixels(), 0, W * H * 4); - int trans = tex->CopyTrueColorPixels(&imgCreate, expand, expand); + int trans = tex->CopyTrueColorPixels(&imgCreate, bExpand, bExpand); bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA); tex->CheckTrans(buffer, W*H, trans); bIsTransparent = tex->gl_info.mIsTransparent; @@ -315,7 +223,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in } else if (translation<=0) { - int trans = tex->CopyTrueColorPixels(&bmp, expand, expand); + int trans = tex->CopyTrueColorPixels(&bmp, bExpand, bExpand); tex->CheckTrans(buffer, W*H, trans); bIsTransparent = tex->gl_info.mIsTransparent; } @@ -324,25 +232,13 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in // When using translations everything must be mapped to the base palette. // Since FTexture's method is doing exactly that by calling GetPixels let's use that here // to do all the dirty work for us. ;) - tex->FTexture::CopyTrueColorPixels(&bmp, expand, expand); + tex->FTexture::CopyTrueColorPixels(&bmp, bExpand, bExpand); bIsTransparent = 0; } - if (warp != 0) - { - buffer = WarpBuffer(buffer, W, H, warp); - } // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. - // Also don't upsample warped textures. - else //if (bIsTransparent != 1) - { - // [BB] Potentially upsample the buffer. - buffer = gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || cm == CM_SHADE ); - } - currentwarp = warp; - currentwarptime = gl_frameMS; - - return buffer; + // [BB] Potentially upsample the buffer. + return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, !!bIsTransparent); } @@ -352,83 +248,44 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in // //=========================================================================== -FHardwareTexture *FGLTexture::CreateTexture(int clampmode) +FHardwareTexture *FGLTexture::CreateHwTexture() { if (tex->UseType==FTexture::TEX_Null) return NULL; // Cannot register a NULL texture - if (!gltexture[clampmode]) + if (mHwTexture == NULL) { - gltexture[clampmode] = new FHardwareTexture(tex->GetWidth(), tex->GetHeight(), true, true, false, tex->gl_info.bNoCompress); + mHwTexture = new FHardwareTexture(tex->GetWidth() + bExpand*2, tex->GetHeight() + bExpand*2, tex->gl_info.bNoCompress); } - return gltexture[clampmode]; + return mHwTexture; } -//=========================================================================== -// -// Create Hardware texture for patch use -// -//=========================================================================== - -bool FGLTexture::CreatePatch() -{ - if (tex->UseType==FTexture::TEX_Null) return false; // Cannot register a NULL texture - if (!glpatch) - { - glpatch=new FHardwareTexture(tex->GetWidth() + bExpand, tex->GetHeight() + bExpand, false, false, tex->gl_info.bNoFilter, tex->gl_info.bNoCompress); - } - if (glpatch) return true; - return false; -} - - //=========================================================================== // // Binds a texture to the renderer // //=========================================================================== -const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int translation, FTexture *hirescheck, int warp) +const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck) { int usebright = false; if (translation <= 0) translation = -translation; else translation = GLTranslationPalette::GetInternalTranslation(translation); - FHardwareTexture *hwtex; - - if (gltexture[4] != NULL && clampmode < 4 && gltexture[clampmode] == NULL) - { - hwtex = gltexture[clampmode] = gltexture[4]; - gltexture[4] = NULL; + bool needmipmap = (clampmode <= CLAMP_XY); - if (hwtex->Bind(texunit, cm, translation)) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT); - } - } - else - { - hwtex = CreateTexture(clampmode); - } + FHardwareTexture *hwtex = CreateHwTexture(); if (hwtex) { - if ((warp != 0 || currentwarp != warp) && currentwarptime != gl_frameMS) - { - // must recreate the texture - Clean(true); - hwtex = CreateTexture(clampmode); - } - - // Texture has become invalid - this is only for special textures, not the regular warping, which is handled above - else if ((warp == 0 && !tex->bHasCanvas && !tex->bWarped) && tex->CheckModified()) + // Texture has become invalid + if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified()) { Clean(true); - hwtex = CreateTexture(clampmode); + hwtex = CreateHwTexture(); } // Bind it to the system. - if (!hwtex->Bind(texunit, cm, translation)) + if (!hwtex->Bind(texunit, translation, needmipmap)) { int w=0, h=0; @@ -438,80 +295,25 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(cm, translation, w, h, false, hirescheck, warp); + buffer = CreateTexBuffer(translation, w, h, hirescheck); tex->ProcessData(buffer, w, h, false); } - if (!hwtex->CreateTexture(buffer, w, h, true, texunit, cm, translation)) + if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation)) { // could not create texture delete[] buffer; return NULL; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT); delete[] buffer; } if (tex->bHasCanvas) static_cast(tex)->NeedUpdate(); + GLRenderer->mSamplerManager->Bind(texunit, clampmode); return hwtex; } return NULL; } -//=========================================================================== -// -// Binds a sprite to the renderer -// -//=========================================================================== -const FHardwareTexture * FGLTexture::BindPatch(int texunit, int cm, int translation, int warp) -{ - bool usebright = false; - int transparm = translation; - - if (translation <= 0) translation = -translation; - else translation = GLTranslationPalette::GetInternalTranslation(translation); - - if (CreatePatch()) - { - if (warp != 0 || currentwarp != warp) - { - // must recreate the texture - Clean(true); - CreatePatch(); - } - - // Texture has become invalid - this is only for special textures, not the regular warping, which is handled above - else if ((warp == 0 && !tex->bHasCanvas && !tex->bWarped) && tex->CheckModified()) - { - Clean(true); - CreatePatch(); - } - - - // Bind it to the system. - if (!glpatch->Bind(texunit, cm, translation)) - { - int w, h; - - // Create this texture - unsigned char * buffer = CreateTexBuffer(cm, translation, w, h, bExpand, NULL, warp); - tex->ProcessData(buffer, w, h, true); - if (!glpatch->CreateTexture(buffer, w, h, false, texunit, cm, translation)) - { - // could not create texture - delete[] buffer; - return NULL; - } - delete[] buffer; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - return glpatch; - } - return NULL; -} - - //=========================================================================== // // @@ -579,7 +381,7 @@ FGLTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand) { if (tex && tex->UseType!=FTexture::TEX_Null) { - FGLTexture *gltex = tex->gl_info.SystemTexture; + FGLTexture *gltex = tex->gl_info.SystemTexture[expand]; if (gltex == NULL) { gltex = new FGLTexture(tex, expand); @@ -597,16 +399,10 @@ FGLTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand) TArray FMaterial::mMaterials; int FMaterial::mMaxBound; -FMaterial::FMaterial(FTexture * tx, bool forceexpand) +FMaterial::FMaterial(FTexture * tx, bool expanded) { - assert(tx->gl_info.Material == NULL); - - bool expanded = tx->UseType == FTexture::TEX_Sprite || - tx->UseType == FTexture::TEX_SkinSprite || - tx->UseType == FTexture::TEX_Decal || - forceexpand; - mShaderIndex = 0; + tex = tx; // TODO: apply custom shader object here /* if (tx->CustomShaderDefinition) @@ -624,7 +420,7 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand) { expanded = false; } - else if (gl.shadermodel > 2) + else { if (tx->gl_info.shaderindex >= FIRST_USER_SHADER) { @@ -643,83 +439,61 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand) } } } + assert(tx->gl_info.Material[expanded] == NULL); + mBaseLayer = ValidateSysTexture(tx, true); - for (int i=GLUSE_PATCH; i<=GLUSE_TEXTURE; i++) - { - Width[i] = tx->GetWidth(); - Height[i] = tx->GetHeight(); - LeftOffset[i] = tx->LeftOffset; - TopOffset[i] = tx->TopOffset; - RenderWidth[i] = tx->GetScaledWidth(); - RenderHeight[i] = tx->GetScaledHeight(); - } - Width[GLUSE_SPRITE] = Width[GLUSE_PATCH]; - Height[GLUSE_SPRITE] = Height[GLUSE_PATCH]; - LeftOffset[GLUSE_SPRITE] = LeftOffset[GLUSE_PATCH]; - TopOffset[GLUSE_SPRITE] = TopOffset[GLUSE_PATCH]; - SpriteU[0] = SpriteV[0] = 0; - spriteright = SpriteU[1] = Width[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Width[GLUSE_PATCH]); - spritebottom = SpriteV[1] = Height[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Height[GLUSE_PATCH]); + mWidth = tx->GetWidth(); + mHeight = tx->GetHeight(); + mLeftOffset = tx->LeftOffset; + mTopOffset = tx->TopOffset; + mRenderWidth = tx->GetScaledWidth(); + mRenderHeight = tx->GetScaledHeight(); + mSpriteU[0] = mSpriteV[0] = 0.f; + mSpriteU[1] = mSpriteV[1] = 1.f; - mTextureLayers.ShrinkToFit(); - mMaxBound = -1; - mMaterials.Push(this); - tx->gl_info.Material = this; - if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0; - tex = tx; + FTexture *basetex = tx->GetRedirect(false); + mBaseLayer = ValidateSysTexture(basetex, expanded); - tx->gl_info.mExpanded = expanded; - FTexture *basetex = tx->GetRedirect(gl.shadermodel < 4); - if (!expanded && !basetex->gl_info.mExpanded && basetex->UseType != FTexture::TEX_Sprite) - { - // check if the texture is just a simple redirect to a patch - // If so we should use the patch for texture creation to - // avoid eventual redundancies. - // This may only be done if both textures use the same expansion mode - // Redirects to sprites are not permitted because sprites get expanded, however, this won't have been set - // if the sprite hadn't been used yet. - mBaseLayer = ValidateSysTexture(basetex, false); - } - else if (!expanded) - { - // if we got a non-expanded texture that redirects to an expanded one - mBaseLayer = ValidateSysTexture(tx, false); - } - else + // mSpriteRect is for positioning the sprite in the scene. + mSpriteRect.left = -mLeftOffset / FIXED2FLOAT(tx->xScale); + mSpriteRect.top = -mTopOffset / FIXED2FLOAT(tx->yScale); + mSpriteRect.width = mWidth / FIXED2FLOAT(tx->xScale); + mSpriteRect.height = mHeight / FIXED2FLOAT(tx->yScale); + + if (expanded) { // a little adjustment to make sprites look better with texture filtering: // create a 1 pixel wide empty frame around them. - RenderWidth[GLUSE_PATCH]+=2; - RenderHeight[GLUSE_PATCH]+=2; - Width[GLUSE_PATCH]+=2; - Height[GLUSE_PATCH]+=2; - LeftOffset[GLUSE_PATCH]+=1; - TopOffset[GLUSE_PATCH]+=1; - Width[GLUSE_SPRITE] += 2; - Height[GLUSE_SPRITE] += 2; - LeftOffset[GLUSE_SPRITE] += 1; - TopOffset[GLUSE_SPRITE] += 1; - spriteright = SpriteU[1] = Width[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Width[GLUSE_PATCH]); - spritebottom = SpriteV[1] = Height[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Height[GLUSE_PATCH]); - - mBaseLayer = ValidateSysTexture(tx, true); + mWidth+=2; + mHeight+=2; + mLeftOffset+=1; + mTopOffset+=1; + mRenderWidth = mRenderWidth * mWidth / (mWidth-2); + mRenderHeight = mRenderHeight * mHeight / (mHeight-2); int trim[4]; if (TrimBorders(trim)) { - Width[GLUSE_SPRITE] = trim[2] + 2; - Height[GLUSE_SPRITE] = trim[3] + 2; - LeftOffset[GLUSE_SPRITE] -= trim[0]; - TopOffset[GLUSE_SPRITE] -= trim[1]; + mSpriteRect.left = -(mLeftOffset - trim[0]) / FIXED2FLOAT(tx->xScale); + mSpriteRect.top = -(mTopOffset - trim[1]) / FIXED2FLOAT(tx->yScale); + mSpriteRect.width = (trim[2] + 2) / FIXED2FLOAT(tx->xScale); + mSpriteRect.height = (trim[3] + 2) / FIXED2FLOAT(tx->yScale); - SpriteU[0] = SpriteU[1] * (trim[0] / (float)Width[GLUSE_PATCH]); - SpriteV[0] = SpriteV[1] * (trim[1] / (float)Height[GLUSE_PATCH]); - SpriteU[1] *= (trim[0]+trim[2]+2) / (float)Width[GLUSE_PATCH]; - SpriteV[1] *= (trim[1]+trim[3]+2) / (float)Height[GLUSE_PATCH]; + mSpriteU[0] = trim[0] / (float)mWidth; + mSpriteV[0] = trim[1] / (float)mHeight; + mSpriteU[1] *= (trim[0]+trim[2]+2) / (float)mWidth; + mSpriteV[1] *= (trim[1]+trim[3]+2) / (float)mHeight; } } + + mTextureLayers.ShrinkToFit(); + mMaxBound = -1; + mMaterials.Push(this); + tx->gl_info.Material[expanded] = this; + if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0; + mExpanded = expanded; } //=========================================================================== @@ -755,13 +529,13 @@ bool FMaterial::TrimBorders(int *rect) int w; int h; - unsigned char *buffer = CreateTexBuffer(CM_DEFAULT, 0, w, h); + unsigned char *buffer = CreateTexBuffer(0, w, h); if (buffer == NULL) { return false; } - if (w != Width[GLUSE_TEXTURE] || h != Height[GLUSE_TEXTURE]) + if (w != mWidth || h != mHeight) { // external Hires replacements cannot be trimmed. delete [] buffer; @@ -834,21 +608,28 @@ outl: // //=========================================================================== -void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) +static FMaterial *last; +static int lastclamp; +static int lasttrans; + + +void FMaterial::Bind(int clampmode, int translation) { + // avoid rebinding the same texture multiple times. + if (this == last && lastclamp == clampmode && translation == lasttrans) return; + last = this; + lastclamp = clampmode; + lasttrans = translation; + int usebright = false; - int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; - bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT; + bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT && clampmode <= CLAMP_XY && !mExpanded; - int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed); + if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; + else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; - if (tex->bHasCanvas || tex->bWarped) clampmode = 0; - else if (clampmode != -1) clampmode &= 3; - else clampmode = 4; - - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, cm, clampmode, translation, allowhires? tex:NULL, softwarewarp); - if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL); + if (gltexture != NULL) { for(unsigned i=0;iid; layer = TexMan(id); - ValidateSysTexture(layer, false); + ValidateSysTexture(layer, mExpanded); } else { layer = mTextureLayers[i].texture; } - layer->gl_info.SystemTexture->Bind(i+1, CM_DEFAULT, clampmode, 0, NULL, false); + layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, NULL); maxbound = i+1; } } @@ -876,36 +657,6 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) } -//=========================================================================== -// -// Binds a texture to the renderer -// -//=========================================================================== - -void FMaterial::BindPatch(int cm, int translation, int overrideshader) -{ - int usebright = false; - int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; - int maxbound = 0; - - int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed); - - const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, cm, translation, softwarewarp); - // The only multitexture effect usable on sprites is the brightmap. - if (glpatch != NULL && shaderindex == 3) - { - mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, CM_DEFAULT, 0, 0); - maxbound = 1; - } - // unbind everything from the last texture that's still active - for(int i=maxbound+1; i<=mMaxBound;i++) - { - FHardwareTexture::Unbind(i); - mMaxBound = maxbound; - } -} - - //=========================================================================== // // @@ -913,31 +664,12 @@ void FMaterial::BindPatch(int cm, int translation, int overrideshader) //=========================================================================== void FMaterial::Precache() { - if (tex->UseType==FTexture::TEX_Sprite) - { - BindPatch(CM_DEFAULT, 0); - } - else - { - int cached = 0; - for(int i=0;i<4;i++) - { - if (mBaseLayer->gltexture[i] != 0) - { - Bind (CM_DEFAULT, i, 0); - cached++; - } - if (cached == 0) Bind(CM_DEFAULT, -1, 0); - } - } + Bind(0, 0); } //=========================================================================== // -// This function is needed here to temporarily manipulate the texture -// for per-wall scaling so that the coordinate functions return proper -// results. Doing this here is much easier than having the calling code -// make these calculations. +// Retrieve texture coordinate info for per-wall scaling // //=========================================================================== @@ -945,14 +677,14 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const { if (x == FRACUNIT) { - tci->mRenderWidth = RenderWidth[GLUSE_TEXTURE]; + tci->mRenderWidth = mRenderWidth; tci->mScaleX = tex->xScale; tci->mTempScaleX = FRACUNIT; } else { fixed_t scale_x = FixedMul(x, tex->xScale); - int foo = (Width[GLUSE_TEXTURE] << 17) / scale_x; + int foo = (mWidth << 17) / scale_x; tci->mRenderWidth = (foo >> 1) + (foo & 1); tci->mScaleX = scale_x; tci->mTempScaleX = x; @@ -960,14 +692,14 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const if (y == FRACUNIT) { - tci->mRenderHeight = RenderHeight[GLUSE_TEXTURE]; + tci->mRenderHeight = mRenderHeight; tci->mScaleY = tex->yScale; tci->mTempScaleY = FRACUNIT; } else { fixed_t scale_y = FixedMul(y, tex->yScale); - int foo = (Height[GLUSE_TEXTURE] << 17) / scale_y; + int foo = (mHeight << 17) / scale_y; tci->mRenderHeight = (foo >> 1) + (foo & 1); tci->mScaleY = scale_y; tci->mTempScaleY = y; @@ -978,7 +710,7 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const tci->mRenderHeight = -tci->mRenderHeight; } tci->mWorldPanning = tex->bWorldPanning; - tci->mWidth = Width[GLUSE_TEXTURE]; + tci->mWidth = mWidth; } //=========================================================================== @@ -1009,30 +741,16 @@ int FMaterial::GetAreas(FloatRect **pAreas) const void FMaterial::BindToFrameBuffer() { - if (mBaseLayer->gltexture[0] == NULL) + if (mBaseLayer->mHwTexture == NULL) { // must create the hardware texture first - mBaseLayer->Bind(0, CM_DEFAULT, 0, 0, NULL, 0); + mBaseLayer->Bind(0, 0, 0, NULL); FHardwareTexture::Unbind(0); + ClearLastTexture(); } - mBaseLayer->gltexture[0]->BindToFrameBuffer(); + mBaseLayer->mHwTexture->BindToFrameBuffer(); } -//=========================================================================== -// -// GetRect -// -//=========================================================================== - -void FMaterial::GetRect(FloatRect * r, ETexUse i) const -{ - r->left = -GetScaledLeftOffsetFloat(i); - r->top = -GetScaledTopOffsetFloat(i); - r->width = GetScaledWidthFloat(i); - r->height = GetScaledHeightFloat(i); -} - - //========================================================================== // // Gets a texture from the texture manager and checks its validity for @@ -1040,23 +758,23 @@ void FMaterial::GetRect(FloatRect * r, ETexUse i) const // //========================================================================== -FMaterial * FMaterial::ValidateTexture(FTexture * tex) +FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand) { if (tex && tex->UseType!=FTexture::TEX_Null) { - FMaterial *gltex = tex->gl_info.Material; + FMaterial *gltex = tex->gl_info.Material[expand]; if (gltex == NULL) { - gltex = new FMaterial(tex, false); + gltex = new FMaterial(tex, expand); } return gltex; } return NULL; } -FMaterial * FMaterial::ValidateTexture(FTextureID no, bool translate) +FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate) { - return ValidateTexture(translate? TexMan(no) : TexMan[no]); + return ValidateTexture(translate? TexMan(no) : TexMan[no], expand); } @@ -1076,47 +794,15 @@ void FMaterial::FlushAll() // so this will catch everything. for(int i=TexMan.NumTextures()-1;i>=0;i--) { - FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture; - if (gltex != NULL) gltex->Clean(true); - } -} - -//========================================================================== -// -// Prints some texture info -// -//========================================================================== - -int FGLTexture::Dump(int i) -{ - int cnt = 0; - int lump = tex->GetSourceLump(); - Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name.GetChars(), i, lump, Wads.GetLumpFullName(lump)); - if (hirestexture) Printf(PRINT_LOG, "\tHirestexture\n"); - if (glpatch) Printf(PRINT_LOG, "\tPatch\n"),cnt++; - if (gltexture[0]) Printf(PRINT_LOG, "\tTexture (x:no, y:no )\n"),cnt++; - if (gltexture[1]) Printf(PRINT_LOG, "\tTexture (x:yes, y:no )\n"),cnt++; - if (gltexture[2]) Printf(PRINT_LOG, "\tTexture (x:no, y:yes)\n"),cnt++; - if (gltexture[3]) Printf(PRINT_LOG, "\tTexture (x:yes, y:yes)\n"),cnt++; - if (gltexture[4]) Printf(PRINT_LOG, "\tTexture precache\n"),cnt++; - return cnt; -} - -CCMD(textureinfo) -{ - int cnth = 0, cntt = 0, pix = 0; - for(int i=0; igl_info.SystemTexture; - if (systex != NULL) + for (int j = 0; j < 2; j++) { - int cnt = systex->Dump(i); - cnth+=cnt; - cntt++; - pix += cnt * tex->GetWidth() * tex->GetHeight(); + FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture[j]; + if (gltex != NULL) gltex->Clean(true); } } - Printf(PRINT_LOG, "%d system textures, %d hardware textures, %d pixels\n", cntt, cnth, pix); } +void FMaterial::ClearLastTexture() +{ + last = NULL; +} diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 3754e9337..b5f055d24 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -13,6 +13,17 @@ EXTERN_CVAR(Bool, gl_precache) struct FRemapTable; class FTextureShader; +enum +{ + CLAMP_NONE = 0, + CLAMP_X = 1, + CLAMP_Y = 2, + CLAMP_XY = 3, + CLAMP_XY_NOMIP = 4, + CLAMP_NOFILTER = 5, + CLAMP_CAMTEX = 6, +}; + struct FTexCoordInfo @@ -40,15 +51,8 @@ struct FTexCoordInfo //=========================================================================== class FMaterial; -enum ETexUse -{ - GLUSE_PATCH, - GLUSE_TEXTURE, - GLUSE_SPRITE, -}; - -class FGLTexture //: protected WorldTextureInfo, protected PatchTextureInfo +class FGLTexture { friend class FMaterial; public: @@ -58,31 +62,22 @@ public: int HiresLump; private: - FHardwareTexture *gltexture[5]; - FHardwareTexture *glpatch; - - int currentwarp; - int currentwarptime; + FHardwareTexture *mHwTexture; bool bHasColorkey; // only for hires bool bExpand; - float AlphaThreshold; - unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, int cm); - BYTE *WarpBuffer(BYTE *buffer, int Width, int Height, int warp); + unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height); - FHardwareTexture *CreateTexture(int clampmode); - //bool CreateTexture(); - bool CreatePatch(); - - const FHardwareTexture *Bind(int texunit, int cm, int clamp, int translation, FTexture *hirescheck, int warp); - const FHardwareTexture *BindPatch(int texunit, int cm, int translation, int warp); + FHardwareTexture *CreateHwTexture(); + const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck); + public: FGLTexture(FTexture * tx, bool expandpatches); ~FGLTexture(); - unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp); + unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck); void Clean(bool all); int Dump(int i); @@ -97,6 +92,8 @@ public: class FMaterial { + friend class FRenderState; + struct FTextureLayer { FTexture *texture; @@ -110,17 +107,17 @@ class FMaterial TArray mTextureLayers; int mShaderIndex; - short LeftOffset[3]; - short TopOffset[3]; - short Width[3]; - short Height[3]; - short RenderWidth[2]; - short RenderHeight[2]; + short mLeftOffset; + short mTopOffset; + short mWidth; + short mHeight; + short mRenderWidth; + short mRenderHeight; + bool mExpanded; - float SpriteU[2], SpriteV[2]; - float spriteright, spritebottom; + float mSpriteU[2], mSpriteV[2]; + FloatRect mSpriteRect; - void SetupShader(int shaderindex, int &cm); FGLTexture * ValidateSysTexture(FTexture * tex, bool expand); bool TrimBorders(int *rect); @@ -135,12 +132,16 @@ public: return !!mBaseLayer->tex->bMasked; } - void Bind(int cm, int clamp = 0, int translation = 0, int overrideshader = 0); - void BindPatch(int cm, int translation = 0, int overrideshader = 0); - - unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand = false, bool allowhires=true) const + int GetLayers() const { - return mBaseLayer->CreateTexBuffer(cm, translation, w, h, expand, allowhires? tex:NULL, 0); + return mTextureLayers.Size() + 1; + } + + void Bind(int clamp, int translation); + + unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true) const + { + return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex : NULL); } void Clean(bool f) @@ -151,78 +152,82 @@ public: void BindToFrameBuffer(); // Patch drawing utilities - void GetRect(FloatRect *r, ETexUse i) const; + void GetSpriteRect(FloatRect * r) const + { + *r = mSpriteRect; + } + void GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const; // This is scaled size in integer units as needed by walls and flats - int TextureHeight(ETexUse i) const { return RenderHeight[i]; } - int TextureWidth(ETexUse i) const { return RenderWidth[i]; } + int TextureHeight() const { return mRenderHeight; } + int TextureWidth() const { return mRenderWidth; } int GetAreas(FloatRect **pAreas) const; - int GetWidth(ETexUse i) const + int GetWidth() const { - return Width[i]; + return mWidth; } - int GetHeight(ETexUse i) const + int GetHeight() const { - return Height[i]; + return mHeight; } - int GetLeftOffset(ETexUse i) const + int GetLeftOffset() const { - return LeftOffset[i]; + return mLeftOffset; } - int GetTopOffset(ETexUse i) const + int GetTopOffset() const { - return TopOffset[i]; + return mTopOffset; } - int GetScaledLeftOffset(ETexUse i) const + int GetScaledLeftOffset() const { - return DivScale16(LeftOffset[i], tex->xScale); + return DivScale16(mLeftOffset, tex->xScale); } - int GetScaledTopOffset(ETexUse i) const + int GetScaledTopOffset() const { - return DivScale16(TopOffset[i], tex->yScale); + return DivScale16(mTopOffset, tex->yScale); } - float GetScaledLeftOffsetFloat(ETexUse i) const + float GetScaledLeftOffsetFloat() const { - return LeftOffset[i] / FIXED2FLOAT(tex->xScale); + return mLeftOffset / FIXED2FLOAT(tex->xScale); } - float GetScaledTopOffsetFloat(ETexUse i) const + float GetScaledTopOffsetFloat() const { - return TopOffset[i] / FIXED2FLOAT(tex->yScale); + return mTopOffset/ FIXED2FLOAT(tex->yScale); } // This is scaled size in floating point as needed by sprites - float GetScaledWidthFloat(ETexUse i) const + float GetScaledWidthFloat() const { - return Width[i] / FIXED2FLOAT(tex->xScale); + return mWidth / FIXED2FLOAT(tex->xScale); } - float GetScaledHeightFloat(ETexUse i) const + float GetScaledHeightFloat() const { - return Height[i] / FIXED2FLOAT(tex->yScale); + return mHeight / FIXED2FLOAT(tex->yScale); } // Get right/bottom UV coordinates for patch drawing float GetUL() const { return 0; } float GetVT() const { return 0; } - float GetUR() const { return spriteright; } - float GetVB() const { return spritebottom; } - float GetU(float upix) const { return upix/(float)Width[GLUSE_PATCH] * spriteright; } - float GetV(float vpix) const { return vpix/(float)Height[GLUSE_PATCH] * spritebottom; } + float GetUR() const { return 1; } + float GetVB() const { return 1; } + float GetU(float upix) const { return upix/(float)mWidth; } + float GetV(float vpix) const { return vpix/(float)mHeight; } - float GetSpriteUL() const { return SpriteU[0]; } - float GetSpriteVT() const { return SpriteV[0]; } - float GetSpriteUR() const { return SpriteU[1]; } - float GetSpriteVB() const { return SpriteV[1]; } + float GetSpriteUL() const { return mSpriteU[0]; } + float GetSpriteVT() const { return mSpriteV[0]; } + float GetSpriteUR() const { return mSpriteU[1]; } + float GetSpriteVB() const { return mSpriteV[1]; } @@ -233,7 +238,7 @@ public: if (!mBaseLayer->tex->bHasCanvas) { int w, h; - unsigned char *buffer = CreateTexBuffer(CM_DEFAULT, 0, w, h); + unsigned char *buffer = CreateTexBuffer(0, w, h); delete [] buffer; } else @@ -246,8 +251,9 @@ public: static void DeleteAll(); static void FlushAll(); - static FMaterial *ValidateTexture(FTexture * tex); - static FMaterial *ValidateTexture(FTextureID no, bool trans); + static FMaterial *ValidateTexture(FTexture * tex, bool expand); + static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans); + static void ClearLastTexture(); }; diff --git a/src/gl/textures/gl_samplers.cpp b/src/gl/textures/gl_samplers.cpp new file mode 100644 index 000000000..1eb54ff10 --- /dev/null +++ b/src/gl/textures/gl_samplers.cpp @@ -0,0 +1,112 @@ +/* +** gl_samplers.cpp +** +**--------------------------------------------------------------------------- +** Copyright 2014 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be +** covered by the terms of the GNU Lesser General Public License as published +** by the Free Software Foundation; either version 2.1 of the License, or (at +** your option) any later version. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "gl/system/gl_system.h" +#include "templates.h" +#include "c_cvars.h" +#include "c_dispatch.h" + +#include "gl/system/gl_interface.h" +#include "gl/system/gl_cvars.h" +#include "gl/renderer/gl_renderer.h" +#include "gl_samplers.h" + +extern TexFilter_s TexFilter[]; + + +FSamplerManager::FSamplerManager() +{ + glGenSamplers(6, mSamplers); + SetTextureFilterMode(); + glSamplerParameteri(mSamplers[5], GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glSamplerParameteri(mSamplers[5], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameterf(mSamplers[5], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glSamplerParameterf(mSamplers[4], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glSamplerParameterf(mSamplers[6], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + + glSamplerParameteri(mSamplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[2], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + +} + +FSamplerManager::~FSamplerManager() +{ + UnbindAll(); + glDeleteSamplers(6, mSamplers); +} + +void FSamplerManager::UnbindAll() +{ + for (int i = 0; i < FHardwareTexture::MAX_TEXTURES; i++) + { + mLastBound[i] = 0; + glBindSampler(i, 0); + } +} + +void FSamplerManager::Bind(int texunit, int num) +{ + unsigned int samp = mSamplers[num]; + //if (samp != mLastBound[texunit]) + { + glBindSampler(texunit, samp); + mLastBound[texunit] = samp; + } +} + + +void FSamplerManager::SetTextureFilterMode() +{ + UnbindAll(); + + for (int i = 0; i < 4; i++) + { + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameterf(mSamplers[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); + } + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); +} + + diff --git a/src/gl/textures/gl_samplers.h b/src/gl/textures/gl_samplers.h new file mode 100644 index 000000000..a9802674f --- /dev/null +++ b/src/gl/textures/gl_samplers.h @@ -0,0 +1,28 @@ +#ifndef __GL_SAMPLERS_H +#define __GL_SAMPLERS_H + +#include "gl_hwtexture.h" + +class FSamplerManager +{ + // We need 6 different samplers: 4 for the different clamping modes, + // one for 2D-textures and one for voxel textures + unsigned int mSamplers[6]; + unsigned int mLastBound[FHardwareTexture::MAX_TEXTURES]; + + void UnbindAll(); + +public: + + FSamplerManager(); + ~FSamplerManager(); + + void Bind(int texunit, int num); + void SetTextureFilterMode(); + + +}; + + +#endif + diff --git a/src/gl/textures/gl_skyboxtexture.cpp b/src/gl/textures/gl_skyboxtexture.cpp index 658eb2004..71f5be8f4 100644 --- a/src/gl/textures/gl_skyboxtexture.cpp +++ b/src/gl/textures/gl_skyboxtexture.cpp @@ -132,9 +132,15 @@ void FSkyBox::Unload () // //----------------------------------------------------------------------------- -void FSkyBox::PrecacheGL() +void FSkyBox::PrecacheGL(int cache) { - //for(int i=0;i<6;i++) if (faces[i]) faces[i]->PrecacheGL(); + for (int i = 0; i < 6; i++) + { + if (faces[i]) + { + faces[i]->PrecacheGL(cache); + } + } } //----------------------------------------------------------------------------- diff --git a/src/gl/textures/gl_skyboxtexture.h b/src/gl/textures/gl_skyboxtexture.h index a85e14190..ce58308a1 100644 --- a/src/gl/textures/gl_skyboxtexture.h +++ b/src/gl/textures/gl_skyboxtexture.h @@ -21,7 +21,7 @@ public: int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); void Unload (); - void PrecacheGL(); + void PrecacheGL(int cache); void SetSize() { diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index d74314e99..53a07d437 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -52,6 +52,7 @@ #include "gl/renderer/gl_renderer.h" #include "gl/textures/gl_texture.h" #include "gl/textures/gl_material.h" +#include "gl/textures/gl_samplers.h" //========================================================================== // @@ -60,7 +61,7 @@ //========================================================================== CUSTOM_CVAR(Float,gl_texture_filter_anisotropic,8.0f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) { - if (GLRenderer != NULL) GLRenderer->FlushTextures(); + if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode(); } CCMD(gl_flush) @@ -71,7 +72,7 @@ CCMD(gl_flush) CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) { if (self < 0 || self > 5) self=4; - if (GLRenderer != NULL) GLRenderer->FlushTextures(); + if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode(); } CUSTOM_CVAR(Int, gl_texture_format, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) @@ -94,7 +95,6 @@ CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL) } CVAR(Bool, gl_precache, false, CVAR_ARCHIVE) -CVAR(Bool, gl_clamp_per_texture, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, gl_trimsprites, true, CVAR_ARCHIVE); @@ -210,7 +210,7 @@ PalEntry averageColor(const DWORD *data, int size, fixed_t maxout_factor) g = Scale(g, maxout_factor, maxv); b = Scale(b, maxout_factor, maxv); } - return PalEntry(r,g,b); + return PalEntry(255,r,g,b); } @@ -236,37 +236,34 @@ FTexture::MiscGLInfo::MiscGLInfo() throw() bBrightmapDisablesFullbright = false; bNoFilter = false; bNoCompress = false; - mExpanded = false; areas = NULL; areacount = 0; mIsTransparent = -1; shaderspeed = 1.f; shaderindex = 0; + precacheTime = 0; - Material = NULL; - SystemTexture = NULL; + Material[1] = Material[0] = NULL; + SystemTexture[1] = SystemTexture[0] = NULL; Brightmap = NULL; - DecalTexture = NULL; } FTexture::MiscGLInfo::~MiscGLInfo() { - if (Material != NULL) delete Material; - Material = NULL; + for (int i = 0; i < 2; i++) + { + if (Material[i] != NULL) delete Material[i]; + Material[i] = NULL; - if (SystemTexture != NULL) delete SystemTexture; - SystemTexture = NULL; + if (SystemTexture[i] != NULL) delete SystemTexture[i]; + SystemTexture[i] = NULL; + } - // this is managed by the texture manager so it may not be deleted here. - //if (Brightmap != NULL) delete Brightmap; + // this is just a reference to another texture in the texture manager. Brightmap = NULL; if (areas != NULL) delete [] areas; areas = NULL; - - if (DecalTexture != NULL) delete DecalTexture; - DecalTexture = NULL; - } //=========================================================================== @@ -320,12 +317,21 @@ void FTexture::CreateDefaultBrightmap() // //========================================================================== -void FTexture::PrecacheGL() +void FTexture::PrecacheGL(int cache) { if (gl_precache) { - FMaterial * gltex = FMaterial::ValidateTexture(this); - if (gltex) gltex->Precache(); + if (cache & 2) + { + FMaterial * gltex = FMaterial::ValidateTexture(this, false); + if (gltex) gltex->Precache(); + } + if (cache & 4) + { + FMaterial * gltex = FMaterial::ValidateTexture(this, true); + if (gltex) gltex->Precache(); + } + gl_info.precacheTime = TexMan.precacheTime; } } @@ -337,7 +343,12 @@ void FTexture::PrecacheGL() void FTexture::UncacheGL() { - if (gl_info.Material) gl_info.Material->Clean(true); + if (gl_info.precacheTime != TexMan.precacheTime) + { + if (gl_info.Material[0]) gl_info.Material[0]->Clean(true); + if (gl_info.Material[1]) gl_info.Material[1]->Clean(true); + gl_info.precacheTime = 0; + } } //========================================================================== @@ -641,49 +652,6 @@ int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotat } -//=========================================================================== -// -// A cloned texture. This is needed by the decal code which needs to assign -// a different texture type to some of its graphics. -// -//=========================================================================== - -FCloneTexture::FCloneTexture (FTexture *source, int usetype) -{ - Name = ""; - SourcePic = source; - CopySize(source); - bNoDecals = source->bNoDecals; - Rotations = source->Rotations; - UseType = usetype; - gl_info.bBrightmap = false; - id.SetInvalid(); - SourceLump = -1; -} - -FCloneTexture::~FCloneTexture () -{ -} - -const BYTE *FCloneTexture::GetColumn (unsigned int column, const Span **spans_out) -{ - return NULL; -} - -const BYTE *FCloneTexture::GetPixels () -{ - return NULL; -} - -void FCloneTexture::Unload () -{ -} - -int FCloneTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) -{ - return SourcePic->CopyTrueColorPixels(bmp, x, y, rotate, inf); -} - //========================================================================== // // Parses a brightmap definition @@ -830,3 +798,42 @@ void gl_ParseDetailTexture(FScanner &sc) } } + +//========================================================================== +// +// Prints some texture info +// +//========================================================================== + +CCMD(textureinfo) +{ + int cntt = 0; + for (int i = 0; i < TexMan.NumTextures(); i++) + { + FTexture *tex = TexMan.ByIndex(i); + if (tex->gl_info.SystemTexture[0] || tex->gl_info.SystemTexture[1] || tex->gl_info.Material[0] || tex->gl_info.Material[1]) + { + int lump = tex->GetSourceLump(); + Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name.GetChars(), i, lump, Wads.GetLumpFullName(lump)); + if (tex->gl_info.Material[0]) + { + Printf(PRINT_LOG, "in use (normal)\n"); + } + else if (tex->gl_info.SystemTexture[0]) + { + Printf(PRINT_LOG, "referenced (normal)\n"); + } + if (tex->gl_info.Material[1]) + { + Printf(PRINT_LOG, "in use (expanded)\n"); + } + else if (tex->gl_info.SystemTexture[1]) + { + Printf(PRINT_LOG, "referenced (normal)\n"); + } + cntt++; + } + } + Printf(PRINT_LOG, "%d system textures\n", cntt); +} + diff --git a/src/gl/textures/gl_texture.h b/src/gl/textures/gl_texture.h index afb812ff0..a70ccebc5 100644 --- a/src/gl/textures/gl_texture.h +++ b/src/gl/textures/gl_texture.h @@ -56,23 +56,6 @@ protected: //Span **Spans; }; -class FCloneTexture : public FTexture -{ -public: - FCloneTexture (FTexture *source, int usetype); - ~FCloneTexture (); - - const BYTE *GetColumn (unsigned int column, const Span **spans_out); - const BYTE *GetPixels (); - void Unload (); - - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); - bool UseBasePalette() { return false; } - -protected: - FTexture *SourcePic; -}; - void gl_GenerateGlobalBrightmapFromColormap(); PalEntry averageColor(const DWORD *data, int size, fixed_t maxout); diff --git a/src/gl/utility/gl_clock.cpp b/src/gl/utility/gl_clock.cpp index 7759f5582..48c21dde2 100644 --- a/src/gl/utility/gl_clock.cpp +++ b/src/gl/utility/gl_clock.cpp @@ -23,6 +23,7 @@ glcycle_t All, Finish, PortalAll, Bsp; glcycle_t ProcessAll; glcycle_t RenderAll; glcycle_t Dirty; +glcycle_t drawcalls; int vertexcount, flatvertices, flatprimitives; int rendered_lines,rendered_flats,rendered_sprites,render_vertexsplit,render_texsplit,rendered_decals, rendered_portals; @@ -96,6 +97,7 @@ void ResetProfilingData() SetupFlat.Reset(); RenderSprite.Reset(); SetupSprite.Reset(); + drawcalls.Reset(); flatvertices=flatprimitives=vertexcount=0; render_texsplit=render_vertexsplit=rendered_lines=rendered_flats=rendered_sprites=rendered_decals=rendered_portals = 0; @@ -116,10 +118,10 @@ static void AppendRenderTimes(FString &str) str.AppendFormat("W: Render=%2.3f, Split = %2.3f, Setup=%2.3f, Clip=%2.3f\n" "F: Render=%2.3f, Setup=%2.3f\n" "S: Render=%2.3f, Setup=%2.3f\n" - "All=%2.3f, Render=%2.3f, Setup=%2.3f, BSP = %2.3f, Portal=%2.3f, Finish=%2.3f\n", + "All=%2.3f, Render=%2.3f, Setup=%2.3f, BSP = %2.3f, Portal=%2.3f, Drawcalls=%2.3f, Finish=%2.3f\n", RenderWall.TimeMS(), SplitWall.TimeMS(), setupwall, clipwall, RenderFlat.TimeMS(), SetupFlat.TimeMS(), RenderSprite.TimeMS(), SetupSprite.TimeMS(), All.TimeMS() + Finish.TimeMS(), RenderAll.TimeMS(), - ProcessAll.TimeMS(), bsp, PortalAll.TimeMS(), Finish.TimeMS()); + ProcessAll.TimeMS(), bsp, PortalAll.TimeMS(), drawcalls.TimeMS(), Finish.TimeMS()); } static void AppendRenderStats(FString &out) @@ -219,4 +221,13 @@ CCMD(bench) switchfps = false; } C_HideConsole (); -} \ No newline at end of file +} + +bool gl_benching = false; + +void checkBenchActive() +{ + FStat *stat = FStat::FindStat("rendertimes"); + gl_benching = ((stat != NULL && stat->isActive()) || printstats); +} + diff --git a/src/gl/utility/gl_clock.h b/src/gl/utility/gl_clock.h index cb9d0173e..46a01d1e4 100644 --- a/src/gl/utility/gl_clock.h +++ b/src/gl/utility/gl_clock.h @@ -5,12 +5,13 @@ #include "x86.h" #include "m_fixed.h" +extern bool gl_benching; + #ifdef _MSC_VER extern double gl_SecondsPerCycle; extern double gl_MillisecPerCycle; - __forceinline long long GetClockCycle () { #if _M_X64 @@ -75,13 +76,13 @@ public: // Not using QueryPerformanceCounter directly, so we don't need // to pull in the Windows headers for every single file that // wants to do some profiling. - long long time = GetClockCycle(); + long long time = (gl_benching? GetClockCycle() : 0); Counter -= time; } __forceinline void Unclock() { - long long time = GetClockCycle(); + long long time = (gl_benching? GetClockCycle() : 0); Counter += time; } @@ -108,6 +109,7 @@ extern glcycle_t All, Finish, PortalAll, Bsp; extern glcycle_t ProcessAll; extern glcycle_t RenderAll; extern glcycle_t Dirty; +extern glcycle_t drawcalls; extern int iter_dlightf, iter_dlight, draw_dlight, draw_dlightf; extern int rendered_lines,rendered_flats,rendered_sprites,rendered_decals,render_vertexsplit,render_texsplit; @@ -117,6 +119,7 @@ extern int vertexcount, flatvertices, flatprimitives; void ResetProfilingData(); void CheckBench(); +void checkBenchActive(); #endif \ No newline at end of file diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index d11388e6e..8d867f25f 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -824,6 +824,15 @@ void R_InitTranslationTables () remap->Remap[i] = IcePaletteRemap[v]; remap->Palette[i] = PalEntry(255, IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]); } + + // The alphatexture translation. Since alphatextures use the red channel this is just a standard grayscale mapping. + PushIdentityTable(TRANSLATION_Standard); + remap = translationtables[TRANSLATION_Standard][8]; + for (i = 0; i < 256; i++) + { + remap->Remap[i] = i; + remap->Palette[i] = PalEntry(255, i, i, i); + } } //---------------------------------------------------------------------------- diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index ebf4699da..ccf808a2f 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -15,6 +15,8 @@ #include "r_data/voxels.h" #include "textures/textures.h" +void gl_InitModels(); + // variables used to look up // and range check thing_t sprites patches TArray sprites; @@ -986,6 +988,8 @@ void R_InitSprites () // [RH] Sort the skins, but leave base as skin 0 //qsort (&skins[PlayerClasses.Size ()], numskins-PlayerClasses.Size (), sizeof(FPlayerSkin), skinsorter); + + gl_InitModels(); } void R_DeinitSpriteData() diff --git a/src/r_defs.h b/src/r_defs.h index a759edeb5..14d58e4b9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -786,6 +786,7 @@ struct sector_t int subsectorcount; // list of subsectors subsector_t ** subsectors; FPortal * portals[2]; // floor and ceiling portals + FLightNode * lighthead; enum { @@ -962,7 +963,7 @@ struct side_t vertex_t *V2() const; //For GL - FLightNode * lighthead[2]; // all blended lights that may affect this wall + FLightNode * lighthead; // all blended lights that may affect this wall seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering int numsegs; @@ -1082,7 +1083,7 @@ struct subsector_t void BuildPolyBSP(); // subsector related GL data - FLightNode * lighthead[2]; // Light nodes (blended and additive) + FLightNode * lighthead; // Light nodes (blended and additive) int validcount; short mapsection; char hacked; // 1: is part of a render hack diff --git a/src/stats.h b/src/stats.h index ed493188b..24ab24cdf 100644 --- a/src/stats.h +++ b/src/stats.h @@ -267,6 +267,10 @@ public: virtual FString GetStats () = 0; void ToggleStat (); + bool isActive() const + { + return m_Active; + } static void PrintStat (); static FStat *FindStat (const char *name); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index b8256bc65..b4df6a045 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1239,6 +1239,8 @@ void FTextureManager::PrecacheLevel (void) if (demoplayback) return; + precacheTime = I_MSTime(); + hitlist = new BYTE[cnt]; memset (hitlist, 0, cnt); diff --git a/src/textures/textures.h b/src/textures/textures.h index ff0e22c0c..df2707401 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -329,10 +329,9 @@ public: struct MiscGLInfo { - FMaterial *Material; - FGLTexture *SystemTexture; + FMaterial *Material[2]; + FGLTexture *SystemTexture[2]; FTexture *Brightmap; - FTexture *DecalTexture; // This is needed for decals of UseType TEX_MiscPatch- PalEntry GlowColor; PalEntry FloorSkyColor; PalEntry CeilingSkyColor; @@ -340,6 +339,7 @@ public: FloatRect *areas; int areacount; int shaderindex; + unsigned int precacheTime; float shaderspeed; int mIsTransparent:2; bool bGlowing:1; // Texture glows @@ -351,14 +351,13 @@ public: bool bBrightmapDisablesFullbright:1; // This disables fullbright display bool bNoFilter:1; bool bNoCompress:1; - bool mExpanded:1; MiscGLInfo() throw (); ~MiscGLInfo(); }; MiscGLInfo gl_info; - virtual void PrecacheGL(); + virtual void PrecacheGL(int cache); virtual void UncacheGL(); void GetGlowColor(float *data); PalEntry GetSkyCapColor(bool bottom); @@ -479,6 +478,8 @@ public: FSwitchDef *FindSwitch (FTextureID texture); FDoorAnimation *FindAnimatedDoor (FTextureID picnum); + unsigned int precacheTime; + private: // texture counting diff --git a/src/v_video.cpp b/src/v_video.cpp index fa94cd49f..c6994d974 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1245,7 +1245,7 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist) FTextureID pic = frame->Texture[k]; if (pic.isValid()) { - hitlist[pic.GetIndex()] = 1; + hitlist[pic.GetIndex()] = 5; } } } @@ -1264,7 +1264,7 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist) { hitlist[sides[i].GetTexture(side_t::top).GetIndex()] = hitlist[sides[i].GetTexture(side_t::mid).GetIndex()] = - hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= 1; + hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= 3; } // Sky texture is always present. @@ -1276,11 +1276,11 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist) if (sky1texture.isValid()) { - hitlist[sky1texture.GetIndex()] |= 1; + hitlist[sky1texture.GetIndex()] |= 3; } if (sky2texture.isValid()) { - hitlist[sky2texture.GetIndex()] |= 1; + hitlist[sky2texture.GetIndex()] |= 3; } } diff --git a/src/version.h b/src/version.h index 2c07c4ef3..f6bd916ee 100644 --- a/src/version.h +++ b/src/version.h @@ -41,12 +41,12 @@ const char *GetVersionString(); /** Lots of different version numbers **/ -#define VERSIONSTR "1.9pre" +#define VERSIONSTR "2.1pre" // The version as seen in the Windows resource -#define RC_FILEVERSION 1,8,9999,0 -#define RC_PRODUCTVERSION 1,8,9999,0 -#define RC_PRODUCTVERSION2 "1.9pre" +#define RC_FILEVERSION 2,0,9999,0 +#define RC_PRODUCTVERSION 2,0,9999,0 +#define RC_PRODUCTVERSION2 "2.1pre" // Version identifier for network games. // Bump it every time you do a release unless you're certain you diff --git a/src/win32/wglext.h b/src/win32/wglext.h new file mode 100644 index 000000000..daba41091 --- /dev/null +++ b/src/win32/wglext.h @@ -0,0 +1,840 @@ +#ifndef __wglext_h_ +#define __wglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2014 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $ +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#define WGL_WGLEXT_VERSION 20140810 + +/* Generated C header for: + * API: wgl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: wgl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#ifdef WGL_WGLEXT_PROTOTYPES +HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType); +VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion); +BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height); +BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif +#endif /* WGL_ARB_buffer_region */ + +#ifndef WGL_ARB_context_flush_control +#define WGL_ARB_context_flush_control 1 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#endif /* WGL_ARB_context_flush_control */ + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); +#ifdef WGL_WGLEXT_PROTOTYPES +HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList); +#endif +#endif /* WGL_ARB_create_context */ + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define ERROR_INVALID_PROFILE_ARB 0x2096 +#endif /* WGL_ARB_create_context_profile */ + +#ifndef WGL_ARB_create_context_robustness +#define WGL_ARB_create_context_robustness 1 +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 +#endif /* WGL_ARB_create_context_robustness */ + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#ifdef WGL_WGLEXT_PROTOTYPES +const char *WINAPI wglGetExtensionsStringARB (HDC hdc); +#endif +#endif /* WGL_ARB_extensions_string */ + +#ifndef WGL_ARB_framebuffer_sRGB +#define WGL_ARB_framebuffer_sRGB 1 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 +#endif /* WGL_ARB_framebuffer_sRGB */ + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +HDC WINAPI wglGetCurrentReadDCARB (void); +#endif +#endif /* WGL_ARB_make_current_read */ + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif /* WGL_ARB_multisample */ + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +DECLARE_HANDLE(HPBUFFERARB); +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer); +int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC); +BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer); +BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif +#endif /* WGL_ARB_pbuffer */ + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif +#endif /* WGL_ARB_pixel_format */ + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif /* WGL_ARB_pixel_format_float */ + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); +BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); +BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif +#endif /* WGL_ARB_render_texture */ + +#ifndef WGL_ARB_robustness_application_isolation +#define WGL_ARB_robustness_application_isolation 1 +#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 +#endif /* WGL_ARB_robustness_application_isolation */ + +#ifndef WGL_ARB_robustness_share_group_isolation +#define WGL_ARB_robustness_share_group_isolation 1 +#endif /* WGL_ARB_robustness_share_group_isolation */ + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif /* WGL_3DFX_multisample */ + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState); +#endif +#endif /* WGL_3DL_stereo_control */ + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association 1 +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 +typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); +typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); +typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); +typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); +typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef WGL_WGLEXT_PROTOTYPES +UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids); +INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data); +UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc); +HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id); +HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList); +BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc); +BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc); +HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); +VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* WGL_AMD_gpu_association */ + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#endif /* WGL_ATI_pixel_format_float */ + +#ifndef WGL_EXT_create_context_es2_profile +#define WGL_EXT_create_context_es2_profile 1 +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#endif /* WGL_EXT_create_context_es2_profile */ + +#ifndef WGL_EXT_create_context_es_profile +#define WGL_EXT_create_context_es_profile 1 +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#endif /* WGL_EXT_create_context_es_profile */ + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif /* WGL_EXT_depth_float */ + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#ifdef WGL_WGLEXT_PROTOTYPES +GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id); +GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length); +GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id); +VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id); +#endif +#endif /* WGL_EXT_display_color_table */ + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +const char *WINAPI wglGetExtensionsStringEXT (void); +#endif +#endif /* WGL_EXT_extensions_string */ + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif /* WGL_EXT_framebuffer_sRGB */ + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif +#endif /* WGL_EXT_make_current_read */ + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif /* WGL_EXT_multisample */ + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +DECLARE_HANDLE(HPBUFFEREXT); +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer); +int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC); +BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer); +BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif +#endif /* WGL_EXT_pbuffer */ + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif +#endif /* WGL_EXT_pixel_format */ + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 +#endif /* WGL_EXT_pixel_format_packed_float */ + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglSwapIntervalEXT (int interval); +int WINAPI wglGetSwapIntervalEXT (void); +#endif +#endif /* WGL_EXT_swap_control */ + +#ifndef WGL_EXT_swap_control_tear +#define WGL_EXT_swap_control_tear 1 +#endif /* WGL_EXT_swap_control_tear */ + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue); +BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue); +#endif +#endif /* WGL_I3D_digital_video_control */ + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue); +BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue); +BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif +#endif /* WGL_I3D_gamma */ + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglEnableGenlockI3D (HDC hDC); +BOOL WINAPI wglDisableGenlockI3D (HDC hDC); +BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag); +BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource); +BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource); +BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge); +BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge); +BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate); +BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate); +BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay); +BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay); +BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif +#endif /* WGL_I3D_genlock */ + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#ifdef WGL_WGLEXT_PROTOTYPES +LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags); +BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress); +BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count); +#endif +#endif /* WGL_I3D_image_buffer */ + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglEnableFrameLockI3D (void); +BOOL WINAPI wglDisableFrameLockI3D (void); +BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag); +BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag); +#endif +#endif /* WGL_I3D_swap_frame_lock */ + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetFrameUsageI3D (float *pUsage); +BOOL WINAPI wglBeginFrameTrackingI3D (void); +BOOL WINAPI wglEndFrameTrackingI3D (void); +BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif +#endif /* WGL_I3D_swap_frame_usage */ + +#ifndef WGL_NV_DX_interop +#define WGL_NV_DX_interop 1 +#define WGL_ACCESS_READ_ONLY_NV 0x00000000 +#define WGL_ACCESS_READ_WRITE_NV 0x00000001 +#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 +typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle); +typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice); +typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); +typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); +typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); +typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); +typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle); +HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice); +BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice); +HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); +BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject); +BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access); +BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); +BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); +#endif +#endif /* WGL_NV_DX_interop */ + +#ifndef WGL_NV_DX_interop2 +#define WGL_NV_DX_interop2 1 +#endif /* WGL_NV_DX_interop2 */ + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image 1 +typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* WGL_NV_copy_image */ + +#ifndef WGL_NV_delay_before_swap +#define WGL_NV_delay_before_swap 1 +typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds); +#endif +#endif /* WGL_NV_delay_before_swap */ + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif /* WGL_NV_float_buffer */ + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 +DECLARE_HANDLE(HGPUNV); +struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +}; +typedef struct _GPU_DEVICE *PGPU_DEVICE; +#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu); +BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList); +BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +BOOL WINAPI wglDeleteDCNV (HDC hdc); +#endif +#endif /* WGL_NV_gpu_affinity */ + +#ifndef WGL_NV_multisample_coverage +#define WGL_NV_multisample_coverage 1 +#define WGL_COVERAGE_SAMPLES_NV 0x2042 +#define WGL_COLOR_SAMPLES_NV 0x20B9 +#endif /* WGL_NV_multisample_coverage */ + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); +#ifdef WGL_WGLEXT_PROTOTYPES +int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); +BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); +BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue); +#endif +#endif /* WGL_NV_present_video */ + +#ifndef WGL_NV_render_depth_texture +#define WGL_NV_render_depth_texture 1 +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif /* WGL_NV_render_depth_texture */ + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_NV_render_texture_rectangle 1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif /* WGL_NV_render_texture_rectangle */ + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group); +BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier); +BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier); +BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count); +BOOL WINAPI wglResetFrameCountNV (HDC hDC); +#endif +#endif /* WGL_NV_swap_group */ + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#ifdef WGL_WGLEXT_PROTOTYPES +void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +void WINAPI wglFreeMemoryNV (void *pointer); +#endif +#endif /* WGL_NV_vertex_array_range */ + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); +typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); +BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); +BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +#endif +#endif /* WGL_NV_video_capture */ + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 +DECLARE_HANDLE(HPVIDEODEV); +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); +BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice); +BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer); +BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); +BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#endif +#endif /* WGL_NV_video_output */ + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#ifdef WGL_WGLEXT_PROTOTYPES +BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator); +INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif +#endif /* WGL_OML_sync_control */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 5623b7062..59ce1e65e 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -1,8 +1,15 @@ -#include "gl/system/gl_system.h" +//#include "gl/system/gl_system.h" +#define WIN32_LEAN_AND_MEAN +#include +#include +#include "wglext.h" + +#define USE_WINDOWS_DWORD #include "win32iface.h" #include "win32gliface.h" //#include "gl/gl_intern.h" +#include "x86.h" #include "templates.h" #include "version.h" #include "c_console.h" @@ -12,16 +19,21 @@ #include "i_system.h" #include "doomstat.h" #include "v_text.h" +#include "m_argv.h" //#include "gl_defs.h" #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_framebuffer.h" -#include "gl/shaders/gl_shader.h" -#include "gl/utility/gl_templates.h" void gl_CalculateCPUSpeed(); extern int NewWidth, NewHeight, NewBits, DisplayBits; +// these get used before GLEW is initialized so we have to use separate pointers with different names +PFNWGLCHOOSEPIXELFORMATARBPROC myWglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); +PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB; +PFNWGLSWAPINTERVALEXTPROC vsyncfunc; + + CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL ) { Printf("This won't take effect until "GAMENAME" is restarted.\n"); @@ -581,8 +593,8 @@ bool Win32GLVideo::SetPixelFormat() hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); - wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + myWglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + myWglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); // any extra stuff here? wglMakeCurrent(NULL, NULL); @@ -599,7 +611,7 @@ bool Win32GLVideo::SetPixelFormat() // //========================================================================== -bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) +bool Win32GLVideo::SetupPixelFormat(int multisample) { int colorDepth; HDC deskDC; @@ -612,7 +624,7 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) colorDepth = GetDeviceCaps(deskDC, BITSPIXEL); ReleaseDC(GetDesktopWindow(), deskDC); - if (wglChoosePixelFormatARB) + if (myWglChoosePixelFormatARB) { attributes[0] = WGL_RED_BITS_ARB; //bits attributes[1] = 8; @@ -635,14 +647,7 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) attributes[17] = true; attributes[18] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB - if (allowsoftware) - { - attributes[19] = WGL_NO_ACCELERATION_ARB; - } - else - { - attributes[19] = WGL_FULL_ACCELERATION_ARB; - } + attributes[19] = WGL_FULL_ACCELERATION_ARB; if (multisample > 0) { @@ -662,7 +667,7 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) attributes[24] = 0; attributes[25] = 0; - if (!wglChoosePixelFormatARB(m_hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats)) + if (!myWglChoosePixelFormatARB(m_hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats)) { Printf("R_OPENGL: Couldn't choose pixel format. Retrying in compatibility mode\n"); goto oldmethod; @@ -702,11 +707,8 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) if (pfd.dwFlags & PFD_GENERIC_FORMAT) { - if (!allowsoftware) - { - Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n"); - return false; - } + Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n"); + return false; } } @@ -724,43 +726,93 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) // //========================================================================== -bool Win32GLVideo::InitHardware (HWND Window, bool allowsoftware, int multisample) +// since we cannot use the extension loader here, before it gets initialized, +// we have to define the extended GL stuff we need, ourselves here. +// The headers generated by GLLoadGen only work if the loader gets initialized. +typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint); +#define GL_NUM_EXTENSIONS 0x821D + +bool Win32GLVideo::checkCoreUsability() +{ + // if we explicitly want to disable 4.x features this must fail. + if (Args->CheckParm("-gl3")) return false; + + // GL 4.4 implies GL_ARB_buffer_storage + if (strcmp((char*)glGetString(GL_VERSION), "4.4") >= 0) return true; + + // at this point the extension loader has not been initialized so we have to retrieve glGetStringi ourselves. + PFNGLGETSTRINGIPROC myglGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi"); + if (!myglGetStringi) return false; // this should not happen. + + const char *extension; + + int max = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &max); + + // step through all reported extensions and see if we got what we need... + for (int i = 0; i < max; i++) + { + extension = (const char*)myglGetStringi(GL_EXTENSIONS, i); + if (!strcmp(extension, "GL_ARB_buffer_storage")) return true; + } + return false; +} + +bool Win32GLVideo::InitHardware (HWND Window, int multisample) { m_Window=Window; m_hDC = GetDC(Window); - if (!SetupPixelFormat(allowsoftware, multisample)) + if (!SetupPixelFormat(multisample)) { Printf ("R_OPENGL: Reverting to software mode...\n"); return false; } - m_hRC = 0; - if (wglCreateContextAttribsARB != NULL) + for (int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) { - int ctxAttribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 3, - WGL_CONTEXT_MINOR_VERSION_ARB, 3, - WGL_CONTEXT_FLAGS_ARB, gl_debug? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0 - }; + m_hRC = NULL; + if (myWglCreateContextAttribsARB != NULL) + { + // let's try to get the best version possible. Some drivers only give us the version we request + // which breaks all version checks for feature support. The highest used features we use are from version 4.4, and 3.0 is a requirement. + static int versions[] = { 45, 44, 43, 42, 41, 40, 33, 32, 31, 30, -1 }; - m_hRC = wglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - } - if (m_hRC == 0) - { - m_hRC = wglCreateContext(m_hDC); - } + for (int i = 0; versions[i] > 0; i++) + { + int ctxAttribs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10, + WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10, + WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + WGL_CONTEXT_PROFILE_MASK_ARB, prof, + 0 + }; - if (m_hRC == NULL) - { - Printf ("R_OPENGL: Couldn't create render context. Reverting to software mode...\n"); - return false; - } + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + if (m_hRC != NULL) break; + } + } - wglMakeCurrent(m_hDC, m_hRC); - return true; + if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) + { + Printf("R_OPENGL: Couldn't create render context. Reverting to software mode...\n"); + return false; + } + + wglMakeCurrent(m_hDC, m_hRC); + + // we can only use core profile contexts if GL_ARB_buffer_storage is supported or GL version is >= 4.4 + if (prof == WGL_CONTEXT_CORE_PROFILE_BIT_ARB && !checkCoreUsability()) + { + wglMakeCurrent(0, 0); + wglDeleteContext(m_hRC); + } + else + { + return true; + } + } + return false; } //========================================================================== @@ -892,7 +944,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in I_RestoreWindowedPos(); } - if (!static_cast(Video)->InitHardware(Window, false, localmultisample)) + if (!static_cast(Video)->InitHardware(Window, localmultisample)) { vid_renderer = 0; return; diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index 4457c5372..4ef48ce18 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -1,7 +1,6 @@ #ifndef __WIN32GLIFACE_H__ #define __WIN32GLIFACE_H__ -#include "gl/system/gl_system.h" #include "hardware.h" #include "win32iface.h" #include "v_video.h" @@ -42,12 +41,10 @@ public: DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old); virtual bool SetResolution (int width, int height, int bits); void DumpAdapters(); - bool InitHardware (HWND Window, bool allowsoftware, int multisample); + bool InitHardware (HWND Window, int multisample); void Shutdown(); bool SetFullscreen(const char *devicename, int w, int h, int bits, int hz); - PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; HDC m_hDC; protected: @@ -83,12 +80,13 @@ protected: HWND InitDummy(); void ShutdownDummy(HWND dummy); bool SetPixelFormat(); - bool SetupPixelFormat(bool allowsoftware, int multisample); + bool SetupPixelFormat(int multisample); void GetDisplayDeviceName(); void MakeModesList(); void AddMode(int x, int y, int bits, int baseHeight, int refreshHz); void FreeModes(); + bool checkCoreUsability(); public: int GetTrueHeight() { return m_trueHeight; } @@ -107,7 +105,6 @@ public: Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen); virtual ~Win32GLFrameBuffer(); - PFNWGLSWAPINTERVALEXTPROC vsyncfunc; // unused but must be defined virtual void Blank (); diff --git a/wadsrc/static/glstuff/gllight.png b/wadsrc/static/glstuff/gllight.png deleted file mode 100644 index a3a296b9f..000000000 Binary files a/wadsrc/static/glstuff/gllight.png and /dev/null differ diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index 329042b74..d3394fc96 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -14,13 +14,6 @@ OptionValue "EnhancedStealth" 3, "Any fixed colormap" } -OptionValue "VBOModes" -{ - 0, "Off" - 1, "Static" - 2, "Dynamic" -} - OptionValue "FilterModes" { 0, "None" @@ -112,12 +105,6 @@ OptionValue "HqResizeModes" 6, "hq4x" } -OptionValue "HqResizeTargets" -{ - 0, "Everything" - 1, "Sprites/fonts" -} - OptionValue "FogMode" { 0, "Off" @@ -152,6 +139,7 @@ OptionMenu "GLTextureGLOptions" Option "Precache GL textures", gl_precache, "YesNo" Option "Camera textures offscreen", gl_usefb, "OnOff" Option "Trim sprite edges", gl_trimsprites, "OnOff" + Option "Sort draw lists by texture", gl_sort_textures, "YesNo" } OptionMenu "GLLightOptions" @@ -165,7 +153,6 @@ OptionMenu "GLLightOptions" Option "Force additive lighting", gl_lights_additive, "YesNo" Slider "Light intensity", gl_lights_intensity, 0.0, 1.0, 0.1 Slider "Light size", gl_lights_size, 0.0, 2.0, 0.1 - Option "Use shaders for lights", gl_dynlight_shader, "YesNo" } OptionMenu "GLPrefOptions" @@ -186,17 +173,6 @@ OptionMenu "GLPrefOptions" Option "Particle style", gl_particles_style, "Particles" Slider "Ambient light level", gl_light_ambient, 1.0, 255.0, 5.0 Option "Rendering quality", gl_render_precise, "Precision" - Option "Use vertex buffer", gl_usevbo, "VBOModes" -} - -OptionMenu "GLShaderOptions" -{ - Title "SHADER OPTIONS" - Option "Enable brightness maps", gl_brightmap_shader, "OnOff" - Option "Shaders for texture warp", gl_warp_shader, "OnOff" - Option "Shaders for fog", gl_fog_shader, "OnOff" - Option "Shaders for colormaps", gl_colormap_shader, "OnOff" - Option "Shaders for glowing textures", gl_glow_shader, "OnOff" } OptionMenu "OpenGLOptions" @@ -204,7 +180,6 @@ OptionMenu "OpenGLOptions" Title "OPENGL OPTIONS" Submenu "Dynamic Light Options", "GLLightOptions" Submenu "Texture Options", "GLTextureGLOptions" - Submenu "Shader Options", "GLShaderOptions" Submenu "Preferences", "GLPrefOptions" } diff --git a/wadsrc/static/shaders/glsl/burn.fp b/wadsrc/static/shaders/glsl/burn.fp new file mode 100644 index 000000000..4ab4cac95 --- /dev/null +++ b/wadsrc/static/shaders/glsl/burn.fp @@ -0,0 +1,15 @@ +uniform sampler2D tex; +uniform sampler2D texture2; +in vec4 vTexCoord; +in vec4 vColor; +out vec4 FragColor; + +void main() +{ + vec4 frag = vColor; + + vec4 t1 = texture2D(tex, vTexCoord.xy); + vec4 t2 = texture2D(texture2, vec2(vTexCoord.x, 1.0-vTexCoord.y)); + + FragColor = frag * vec4(t1.r, t1.g, t1.b, t2.a); +} diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 5b43dfd95..d8259c845 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -1,8 +1,6 @@ -uniform int fogenabled; -uniform vec4 fogcolor; -uniform vec3 camerapos; -varying vec4 pixelpos; -varying vec4 fogparm; +in vec4 pixelpos; +in vec2 glowdist; +out vec4 FragColor; //=========================================================================== // @@ -18,19 +16,15 @@ void main() // // calculate fog factor // - #ifndef NO_SM4 - if (fogenabled == -1) - { - fogdist = pixelpos.w; - } - else - { - fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); - } - #else + if (uFogEnabled == -1) + { fogdist = pixelpos.w; - #endif - fogfactor = exp2 (fogparm.z * fogdist); - gl_FragColor = vec4(fogcolor.rgb, 1.0 - fogfactor); + } + else + { + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + } + fogfactor = exp2 (uFogDensity * fogdist); + FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor); } diff --git a/wadsrc/static/shaders/glsl/func_brightmap.fp b/wadsrc/static/shaders/glsl/func_brightmap.fp index e8ad0bb3d..bea336eb6 100644 --- a/wadsrc/static/shaders/glsl/func_brightmap.fp +++ b/wadsrc/static/shaders/glsl/func_brightmap.fp @@ -1,9 +1,12 @@ uniform sampler2D texture2; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].st)); - vec4 texel = getTexel(gl_TexCoord[0].st); - return vec4(texel.rgb * min (color.rgb + brightpix.rgb, 1.0), texel.a*color.a); + return getTexel(vTexCoord.st); } +vec4 ProcessLight(vec4 color) +{ + vec4 brightpix = desaturate(texture2D(texture2, vTexCoord.st)); + return vec4(min (color.rgb + brightpix.rgb, 1.0), color.a); +} diff --git a/wadsrc/static/shaders/glsl/func_defaultlight.fp b/wadsrc/static/shaders/glsl/func_defaultlight.fp new file mode 100644 index 000000000..227d38c6a --- /dev/null +++ b/wadsrc/static/shaders/glsl/func_defaultlight.fp @@ -0,0 +1,5 @@ + +vec4 ProcessLight(vec4 color) +{ + return color; +} diff --git a/wadsrc/static/shaders/glsl/func_normal.fp b/wadsrc/static/shaders/glsl/func_normal.fp index f9297ca6f..184c14851 100644 --- a/wadsrc/static/shaders/glsl/func_normal.fp +++ b/wadsrc/static/shaders/glsl/func_normal.fp @@ -1,7 +1,6 @@ -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec4 pix = getTexel(gl_TexCoord[0].st); - return pix * color; + return getTexel(vTexCoord.st); } diff --git a/wadsrc/static/shaders/glsl/func_notexture.fp b/wadsrc/static/shaders/glsl/func_notexture.fp index 99ef44f68..9337ad6b1 100644 --- a/wadsrc/static/shaders/glsl/func_notexture.fp +++ b/wadsrc/static/shaders/glsl/func_notexture.fp @@ -1,6 +1,6 @@ -vec4 Process(vec4 color) +vec4 ProcessTexel() { - return color; + return desaturate(uObjectColor); } diff --git a/wadsrc/static/shaders/glsl/func_warp1.fp b/wadsrc/static/shaders/glsl/func_warp1.fp index c4acb8854..891eaa936 100644 --- a/wadsrc/static/shaders/glsl/func_warp1.fp +++ b/wadsrc/static/shaders/glsl/func_warp1.fp @@ -1,8 +1,8 @@ uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; const float pi = 3.14159265358979323846; vec2 offset = vec2(0,0); @@ -12,6 +12,6 @@ vec4 Process(vec4 color) texCoord += offset; - return getTexel(texCoord) * color; + return getTexel(texCoord); } diff --git a/wadsrc/static/shaders/glsl/func_warp2.fp b/wadsrc/static/shaders/glsl/func_warp2.fp index 9d5b8f9db..7cc5e7ebb 100644 --- a/wadsrc/static/shaders/glsl/func_warp2.fp +++ b/wadsrc/static/shaders/glsl/func_warp2.fp @@ -1,8 +1,8 @@ uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; const float pi = 3.14159265358979323846; vec2 offset = vec2(0.0,0.0); @@ -13,6 +13,6 @@ vec4 Process(vec4 color) texCoord += offset; - return getTexel(texCoord) * color; + return getTexel(texCoord); } diff --git a/wadsrc/static/shaders/glsl/func_wavex.fp b/wadsrc/static/shaders/glsl/func_wavex.fp index d90486358..e4230ae87 100644 --- a/wadsrc/static/shaders/glsl/func_wavex.fp +++ b/wadsrc/static/shaders/glsl/func_wavex.fp @@ -1,13 +1,13 @@ uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; const float pi = 3.14159265358979323846; texCoord.x += sin(pi * 2.0 * (texCoord.y + timer * 0.125)) * 0.1; - return getTexel(texCoord) * color; + return getTexel(texCoord); } diff --git a/wadsrc/static/shaders/glsl/fuzz_jagged.fp b/wadsrc/static/shaders/glsl/fuzz_jagged.fp index d1d1c9727..c088c7b30 100644 --- a/wadsrc/static/shaders/glsl/fuzz_jagged.fp +++ b/wadsrc/static/shaders/glsl/fuzz_jagged.fp @@ -1,16 +1,16 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec2 texSplat; const float pi = 3.14159265358979323846; texSplat.x = texCoord.x + mod(sin(pi * 2.0 * (texCoord.y + timer * 2.0)),0.1) * 0.1; texSplat.y = texCoord.y + mod(cos(pi * 2.0 * (texCoord.x + timer * 2.0)),0.1) * 0.1; - vec4 basicColor = getTexel(texSplat) * color; + vec4 basicColor = getTexel(texSplat); float texX = sin(texCoord.x * 100.0 + timer*5.0); float texY = cos(texCoord.x * 100.0 + timer*5.0); diff --git a/wadsrc/static/shaders/glsl/fuzz_noise.fp b/wadsrc/static/shaders/glsl/fuzz_noise.fp index 7e08646cb..9f5da5f25 100644 --- a/wadsrc/static/shaders/glsl/fuzz_noise.fp +++ b/wadsrc/static/shaders/glsl/fuzz_noise.fp @@ -1,10 +1,10 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; - vec4 basicColor = getTexel(texCoord) * color; + vec2 texCoord = vTexCoord.st; + vec4 basicColor = getTexel(texCoord); texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0; texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_smooth.fp b/wadsrc/static/shaders/glsl/fuzz_smooth.fp index 9cb840e78..4261d5415 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smooth.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smooth.fp @@ -1,10 +1,10 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; - vec4 basicColor = getTexel(texCoord) * color; + vec2 texCoord = vTexCoord.st; + vec4 basicColor = getTexel(texCoord); float texX = texCoord.x / 3.0 + 0.66; float texY = 0.34 - texCoord.y / 3.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp b/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp index 4c796de60..bfe04ec16 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp @@ -1,10 +1,10 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; - vec4 basicColor = getTexel(texCoord) * color; + vec2 texCoord = vTexCoord.st; + vec4 basicColor = getTexel(texCoord); float texX = sin(mod(texCoord.x * 100.0 + timer*5.0, 3.489)) + texCoord.x / 4.0; float texY = cos(mod(texCoord.y * 100.0 + timer*5.0, 3.489)) + texCoord.y / 4.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp index 074e5f10d..75bee0330 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp @@ -1,10 +1,10 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; - vec4 basicColor = getTexel(texCoord) * color; + vec2 texCoord = vTexCoord.st; + vec4 basicColor = getTexel(texCoord); float texX = sin(texCoord.x * 100.0 + timer*5.0); float texY = cos(texCoord.x * 100.0 + timer*5.0); diff --git a/wadsrc/static/shaders/glsl/fuzz_standard.fp b/wadsrc/static/shaders/glsl/fuzz_standard.fp index a93bef849..fd87eaa46 100644 --- a/wadsrc/static/shaders/glsl/fuzz_standard.fp +++ b/wadsrc/static/shaders/glsl/fuzz_standard.fp @@ -1,10 +1,10 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; - vec4 basicColor = getTexel(texCoord) * color; + vec2 texCoord = vTexCoord.st; + vec4 basicColor = getTexel(texCoord); texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0; texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_swirly.fp b/wadsrc/static/shaders/glsl/fuzz_swirly.fp index 19816f8f4..86a66ac8e 100644 --- a/wadsrc/static/shaders/glsl/fuzz_swirly.fp +++ b/wadsrc/static/shaders/glsl/fuzz_swirly.fp @@ -1,10 +1,10 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; - vec4 basicColor = getTexel(texCoord) * color; + vec2 texCoord = vTexCoord.st; + vec4 basicColor = getTexel(texCoord); float texX = sin(texCoord.x * 100.0 + timer*5.0); float texY = cos(texCoord.x * 100.0 + timer*5.0); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index aa2c33238..c77a058c2 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -1,55 +1,102 @@ +in vec4 pixelpos; +in vec2 glowdist; -// Changing this constant gives results very similar to changing r_visibility. -// Default is 232, it seems to give exactly the same light bands as software renderer. -#define DOOMLIGHTFACTOR 232.0 +in vec4 vTexCoord; +in vec4 vColor; +out vec4 FragColor; -#ifdef DYNLIGHT - -// ATI does not like this inside an #ifdef so it will be prepended by the compiling code inside the .EXE now. -//#version 120 -//#extension GL_EXT_gpu_shader4 : enable - -uniform ivec3 lightrange; -#ifndef MAXLIGHTS128 -uniform vec4 lights[256]; +#ifdef SHADER_STORAGE_LIGHTS + layout(std430, binding = 1) buffer LightBufferSSO + { + vec4 lights[]; + }; #else -uniform vec4 lights[128]; -#endif - + layout(std140) uniform LightBufferUBO + { + vec4 lights[NUM_UBO_LIGHTS]; + }; #endif - -uniform int fogenabled; -uniform vec4 fogcolor; -uniform vec3 dlightcolor; -uniform vec3 camerapos; -varying vec4 pixelpos; -varying vec4 fogparm; -//uniform vec2 lightparms; -uniform float desaturation_factor; - -uniform vec4 topglowcolor; -uniform vec4 bottomglowcolor; -varying vec2 glowdist; - -uniform int texturemode; uniform sampler2D tex; vec4 Process(vec4 color); +vec4 ProcessTexel(); +vec4 ProcessLight(vec4 color); -varying float lightlevel; +//=========================================================================== +// +// Desaturate a color +// +//=========================================================================== -#ifdef SOFTLIGHT +vec4 desaturate(vec4 texel) +{ + if (uDesaturationFactor > 0.0) + { + float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14); + return mix (texel, vec4(gray,gray,gray,texel.a), uDesaturationFactor); + } + else + { + return texel; + } +} + +//=========================================================================== +// +// This function is common for all (non-special-effect) fragment shaders +// +//=========================================================================== + +vec4 getTexel(vec2 st) +{ + vec4 texel = texture2D(tex, st); + + // + // Apply texture modes + // + switch (uTextureMode) + { + case 1: // TM_MASK + texel.rgb = vec3(1.0,1.0,1.0); + break; + + case 2: // TM_OPAQUE + texel.a = 1.0; + break; + + case 3: // TM_INVERSE + texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a); + break; + + case 4: // TM_REDTOALPHA + texel = vec4(1.0, 1.0, 1.0, texel.r); + break; + } + texel *= uObjectColor; + + return desaturate(texel); +} + +//=========================================================================== +// // Doom lighting equation ripped from EDGE. // Big thanks to EDGE developers for making the only port // that actually replicates software renderer's lighting in OpenGL. // Float version. // Basically replace int with float and divide all constants by 31. +// +//=========================================================================== + float R_DoomLightingEquation(float light, float dist) { + // Changing this constant gives results very similar to changing r_visibility. + // Default is 232, it seems to give exactly the same light bands as software renderer. + #define DOOMLIGHTFACTOR 232.0 + /* L in the range 0 to 63 */ float L = light * 63.0/31.0; @@ -65,100 +112,101 @@ float R_DoomLightingEquation(float light, float dist) /* result is colormap index (0 bright .. 31 dark) */ return clamp(index, min_L, 1.0); } -#endif - -//=========================================================================== -// -// Desaturate a color -// -//=========================================================================== - -vec4 desaturate(vec4 texel) -{ - #ifndef NO_DESATURATE - float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14); - return mix (vec4(gray,gray,gray,texel.a), texel, desaturation_factor); - #else - return texel; - #endif -} //=========================================================================== // // Calculate light // +// It is important to note that the light color is not desaturated +// due to ZDoom's implementation weirdness. Everything that's added +// on top of it, e.g. dynamic lights and glows are, though, because +// the objects emitting these lights are also. +// +// This is making this a bit more complicated than it needs to +// because we can't just desaturate the final fragment color. +// //=========================================================================== vec4 getLightColor(float fogdist, float fogfactor) { - vec4 color = gl_Color; - #ifdef SOFTLIGHT - float newlightlevel = 1.0 - R_DoomLightingEquation(lightlevel, gl_FragCoord.z); - color.rgb *= clamp(vec3(newlightlevel) + dlightcolor, 0.0, 1.0); - #endif - #ifndef NO_FOG - // - // apply light diminishing - // - if (fogenabled > 0) + vec4 color = vColor; + + if (uLightLevel >= 0.0) { - #if (!defined(NO_SM4) || defined(DOOMLIGHT)) && !defined SOFTLIGHT - // special lighting mode 'Doom' not available on older cards for performance reasons. - if (fogdist < fogparm.y) - { - color.rgb *= fogparm.x - (fogdist / fogparm.y) * (fogparm.x - 1.0); - } - #endif + float newlightlevel = 1.0 - R_DoomLightingEquation(uLightLevel, gl_FragCoord.z); + color.rgb *= newlightlevel; + } + else if (uFogEnabled > 0.0) + { + // brightening around the player for light mode 2 + if (fogdist < uLightDist) + { + color.rgb *= uLightFactor - (fogdist / uLightDist) * (uLightFactor - 1.0); + } - //color = vec4(color.rgb * (1.0 - fogfactor), color.a); + // + // apply light diminishing through fog equation + // color.rgb = mix(vec3(0.0, 0.0, 0.0), color.rgb, fogfactor); } - #endif - #ifndef NO_GLOW // // handle glowing walls // - if (topglowcolor.a > 0.0 && glowdist.x < topglowcolor.a) + if (uGlowTopColor.a > 0.0 && glowdist.x < uGlowTopColor.a) { - color.rgb += desaturate(topglowcolor * (1.0 - glowdist.x / topglowcolor.a)).rgb; + color.rgb += desaturate(uGlowTopColor * (1.0 - glowdist.x / uGlowTopColor.a)).rgb; } - if (bottomglowcolor.a > 0.0 && glowdist.y < bottomglowcolor.a) + if (uGlowBottomColor.a > 0.0 && glowdist.y < uGlowBottomColor.a) { - color.rgb += desaturate(bottomglowcolor * (1.0 - glowdist.y / bottomglowcolor.a)).rgb; + color.rgb += desaturate(uGlowBottomColor * (1.0 - glowdist.y / uGlowBottomColor.a)).rgb; } color = min(color, 1.0); - #endif - - // calculation of actual light color is complete. - return color; -} -//=========================================================================== -// -// Gets a texel and performs common manipulations -// -//=========================================================================== - -vec4 getTexel(vec2 st) -{ - vec4 texel = texture2D(tex, st); - - #ifndef NO_TEXTUREMODE // - // Apply texture modes + // apply brightmaps (or other light manipulation by custom shaders. // - if (texturemode == 2) - { - texel.a = 1.0; - } - else if (texturemode == 1) - { - texel.rgb = vec3(1.0,1.0,1.0); - } - #endif + color = ProcessLight(color); - return desaturate(texel); + // + // apply dynamic lights (except additive) + // + + vec4 dynlight = uDynLightColor; + + if (uLightIndex >= 0) + { + ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1); + if (lightRange.z > lightRange.x) + { + // + // modulated lights + // + for(int i=lightRange.x; i= 0) + { + ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1); + if (lightRange.w > lightRange.z) + { + vec4 addlight = vec4(0.0,0.0,0.0,0.0); + + // + // additive lights - these can be done after the alpha test. + // + for(int i=lightRange.z; i