From 7d3beb665b7a3e802ef57091ff423dffc7bf29b5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 10 May 2014 21:47:07 +0200 Subject: [PATCH 001/138] - rewrote vertex buffer code to require GL_ARB_BUFFER_STORAGE extension. This means it won't work anymore on anything that doesn't support OpenGL 4.0, but I don't think this is a problem. On older NVidia cards performance gains could not be seen and on older AMDs using the vertex buffer was even worse as long as it got mixed with immediate mode rendering. --- src/gl/data/gl_vertexbuffer.cpp | 106 ++++++++++------------------- src/gl/data/gl_vertexbuffer.h | 19 +++--- src/gl/models/gl_voxels.cpp | 26 +++---- src/gl/renderer/gl_renderstate.cpp | 8 +++ src/gl/renderer/gl_renderstate.h | 9 +++ src/gl/scene/gl_flats.cpp | 2 +- src/gl/scene/gl_scene.cpp | 3 +- src/gl/system/gl_interface.cpp | 43 ++++-------- src/gl/system/gl_interface.h | 13 +--- 9 files changed, 97 insertions(+), 132 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index c07b6cea3..c5703a8ef 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -49,20 +49,18 @@ #include "gl/data/gl_vertexbuffer.h" +const int BUFFER_SIZE = 2000000; + CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { - if (self < -1 || self > 2) + if (self < -1 || self > 1 || !(gl.flags & RFL_BUFFER_STORAGE)) { 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"); + if (!(gl.flags & RFL_BUFFER_STORAGE)) self = 0; + else self = 1; } } @@ -96,13 +94,24 @@ 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); + } + else + { + map = NULL; + } } FFlatVertexBuffer::~FFlatVertexBuffer() { - UnmapVBO(); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBuffer(GL_ARRAY_BUFFER, 0); } //========================================================================== @@ -118,7 +127,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 +268,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]; + FFlatVertex *mapvt = &map[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; } } @@ -324,11 +292,10 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { vbo_shadowdata.Clear(); - if (vbo_arg > 0) + if (gl.flags & RFL_BUFFER_STORAGE) { CreateFlatVBO(); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, vbo_shadowdata.Size() * sizeof(FFlatVertex), &vbo_shadowdata[0], GL_DYNAMIC_DRAW); + memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); } else if (sectors) { @@ -350,16 +317,14 @@ void FFlatVertexBuffer::CreateVBO() void FFlatVertexBuffer::BindVBO() { - if (vbo_arg > 0) + if (gl.flags & RFL_BUFFER_STORAGE) { - 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); } } @@ -371,20 +336,23 @@ void FFlatVertexBuffer::BindVBO() void FFlatVertexBuffer::CheckPlanes(sector_t *sector) { - if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) + if (gl.flags & RFL_BUFFER_STORAGE) { - if (sector->ceilingdata == NULL) // only update if there's no thinker attached + if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) { - UpdatePlaneVertices(sector, sector_t::ceiling); - sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(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); + } } - } - if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor]) - { - if (sector->floordata == NULL) // only update if there's no thinker attached + if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor]) { - UpdatePlaneVertices(sector, sector_t::floor); - sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(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); + } } } } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 49db1c7db..2755b6494 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -20,11 +20,10 @@ public: virtual void BindVBO() = 0; }; -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); }; @@ -35,27 +34,27 @@ struct FFlatVertex // exactly 32 bytes large class FFlatVertexBuffer : public FVertexBuffer { FFlatVertex *map; + unsigned int mIndex; - void MapVBO(); void CheckPlanes(sector_t *sector); public: int vbo_arg; - TArray vbo_shadowdata; // this is kept around for non-VBO rendering + TArray vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer -public: FFlatVertexBuffer(); ~FFlatVertexBuffer(); + void CreateVBO(); + void BindVBO(); + void CheckUpdate(sector_t *sector); + +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(); }; diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index f47685216..14ed5985c 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -506,25 +506,27 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translatio { FMaterial * tex = FMaterial::ValidateTexture(skin); tex->Bind(cm, 0, translation); - 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; + gl_RenderState.SetVertexBuffer(mVBO); + gl_RenderState.Apply(); + glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } - - glBegin(GL_QUADS); - for(unsigned i=0;i < mIndices.Size(); i++) + else { - FVoxelVertex *vert = &mVertices[mIndices[i]]; - glTexCoord2fv(&vert->u); - glVertex3fv(&vert->x); + gl_RenderState.Apply(); + glBegin(GL_QUADS); + for (unsigned i = 0; i < mIndices.Size(); i++) + { + FVoxelVertex *vert = &mVertices[mIndices[i]]; + glTexCoord2fv(&vert->u); + glVertex3fv(&vert->x); + } + glEnd(); } - glEnd(); } //=========================================================================== diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 73cc5ec90..f0ceb40fa 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -41,6 +41,7 @@ #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" @@ -79,6 +80,7 @@ void FRenderState::Reset() mBlendEquation = GL_FUNC_ADD; glBlendEquation = -1; m2D = true; + mVertexBuffer = mCurrentVertexBuffer = NULL; } @@ -300,6 +302,12 @@ void FRenderState::Apply(bool forcenoshader) } } + if (mVertexBuffer != mCurrentVertexBuffer) + { + if (mVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0); + else mVertexBuffer->BindVBO(); + mCurrentVertexBuffer = mVertexBuffer; + } if (forcenoshader || !ApplyShader()) { GLRenderer->mShaderManager->SetActiveShader(NULL); diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 061f5c2df..7e611f7a5 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -5,6 +5,8 @@ #include "c_cvars.h" #include "r_defs.h" +class FVertexBuffer; + EXTERN_CVAR(Bool, gl_direct_state_change) struct FStateAttr @@ -104,6 +106,8 @@ class FRenderState int mBlendEquation; bool m2D; + FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; + FStateVec3 mCameraPos; FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTopPlane, mGlowBottomPlane; @@ -140,6 +144,11 @@ public: int SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime); void Apply(bool forcenoshader = false); + void SetVertexBuffer(FVertexBuffer *vb) + { + mVertexBuffer = vb; + } + void SetTextureMode(int mode) { mTextureMode = mode; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 3efdcba8b..7ff3d7110 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -272,7 +272,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) } else { - if (vboindex >= 0) + if (gl_usevbo && vboindex >= 0) { //glColor3f( 1.f,.5f,.5f); int index = vboindex; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 513abaa57..47f990796 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -353,7 +353,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(); } @@ -931,7 +930,7 @@ void FGLRenderer::RenderView (player_t* player) LastCamera=player->camera; } - mVBO->BindVBO(); + gl_RenderState.SetVertexBuffer(mVBO); // reset statistics counters ResetProfilingData(); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 2d311f0bb..25797e4fa 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -155,41 +155,28 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; - 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; + gl.version = strtod((char*)glGetString(GL_VERSION), NULL); 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. + // 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_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; - } + // 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) + if (gl.version >= 3.f) { gl.flags|=RFL_FRAMEBUFFER; } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 79623c07f..fdadd67d9 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -9,16 +9,8 @@ enum RenderFlags RFL_TEXTURE_COMPRESSION=8, RFL_TEXTURE_COMPRESSION_S3TC=16, - 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_FRAMEBUFFER = 32, + RFL_BUFFER_STORAGE = 64, }; enum TexMode @@ -40,6 +32,7 @@ struct RenderContext unsigned int flags; unsigned int shadermodel; unsigned int maxuniforms; + float version; int max_texturesize; char * vendorstring; From f7404d20fb77b6a2fdcee179e54828e1618c27fd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 01:23:27 +0200 Subject: [PATCH 002/138] - add vertex buffer based drawing for all walls and flats. --- src/gl/data/gl_vertexbuffer.cpp | 1 + src/gl/data/gl_vertexbuffer.h | 18 +++++ src/gl/scene/gl_flats.cpp | 68 +++++++++++++++--- src/gl/scene/gl_scene.cpp | 3 + src/gl/scene/gl_vertex.cpp | 121 ++++++++++++++++++++++++++++++++ src/gl/scene/gl_wall.h | 6 ++ src/gl/scene/gl_walls_draw.cpp | 86 +++++++++++++++++------ 7 files changed, 273 insertions(+), 30 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index c5703a8ef..a0f9aa849 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -296,6 +296,7 @@ void FFlatVertexBuffer::CreateVBO() { CreateFlatVBO(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); + mIndex = vbo_shadowdata.Size(); } else if (sectors) { diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 2755b6494..24fe5b4d5 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -35,6 +35,7 @@ class FFlatVertexBuffer : public FVertexBuffer { FFlatVertex *map; unsigned int mIndex; + unsigned int mCurIndex; void CheckPlanes(sector_t *sector); @@ -49,6 +50,23 @@ public: void BindVBO(); 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; + return diff; + } + 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); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 7ff3d7110..c32011998 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -238,21 +238,72 @@ 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++) + if (!gl_usevbo) { - 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); + glBegin(GL_TRIANGLE_FAN); + + if (plane.plane.a | plane.plane.b) + { + for (unsigned int k = 0; k < sub->numlines; k++) + { + 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); + } + } + else + { + float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz; + for (unsigned int k = 0; k < sub->numlines; k++) + { + vertex_t *vt = sub->firstline[k].v1; + glTexCoord2f(vt->fx / 64.f, -vt->fy / 64.f); + glVertex3f(vt->fx, zc, vt->fy); + } + } + glEnd(); + } + else + { + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + if (plane.plane.a | plane.plane.b) + { + 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++; + } + } + 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++; + } + } + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); } - glEnd(); flatvertices += sub->numlines; flatprimitives++; } + //========================================================================== // // @@ -292,7 +343,6 @@ 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++) { diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 47f990796..1aa3c2b3f 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -931,6 +931,7 @@ void FGLRenderer::RenderView (player_t* player) } gl_RenderState.SetVertexBuffer(mVBO); + GLRenderer->mVBO->Reset(); // reset statistics counters ResetProfilingData(); @@ -991,6 +992,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); diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index 3aff28d1f..03f7df520 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" @@ -88,6 +89,37 @@ void GLWall::SplitUpperEdge(texcoord * tcs) vertexcount += sidedef->numsegs-1; } +void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) +{ + if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; + + side_t *sidedef = seg->sidedef; + float polyw = glseg.fracright - glseg.fracleft; + float facu = (tcs[2].u - tcs[1].u) / polyw; + float facv = (tcs[2].v - tcs[1].v) / polyw; + float fact = (ztop[1] - ztop[0]) / polyw; + float facc = (zceil[1] - zceil[0]) / polyw; + float facf = (zfloor[1] - zfloor[0]) / polyw; + + for (int i = 0; i < sidedef->numsegs - 1; i++) + { + seg_t *cseg = sidedef->segs[i]; + float sidefrac = cseg->sidefrac; + if (sidefrac <= glseg.fracleft) continue; + if (sidefrac >= glseg.fracright) return; + + float fracfac = sidefrac - glseg.fracleft; + + 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; +} + //========================================================================== // // Split upper edge of wall @@ -121,6 +153,37 @@ void GLWall::SplitLowerEdge(texcoord * tcs) vertexcount += sidedef->numsegs-1; } +void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) +{ + if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; + + side_t *sidedef = seg->sidedef; + float polyw = glseg.fracright - glseg.fracleft; + float facu = (tcs[3].u - tcs[0].u) / polyw; + float facv = (tcs[3].v - tcs[0].v) / polyw; + float facb = (zbottom[1] - zbottom[0]) / polyw; + float facc = (zceil[1] - zceil[0]) / polyw; + float facf = (zfloor[1] - zfloor[0]) / polyw; + + for (int i = sidedef->numsegs - 2; i >= 0; i--) + { + seg_t *cseg = sidedef->segs[i]; + float sidefrac = cseg->sidefrac; + if (sidefrac >= glseg.fracright) continue; + if (sidefrac <= glseg.fracleft) return; + + float fracfac = sidefrac - glseg.fracleft; + + 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; +} + //========================================================================== // // Split left edge of wall @@ -153,6 +216,35 @@ void GLWall::SplitLeftEdge(texcoord * tcs) } } +void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) +{ + if (vertexes[0] == NULL) return; + + vertex_t * vi = vertexes[0]; + + if (vi->numheights) + { + 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; + + while (inumheights && vi->heightlist[i] <= zbottom[0]) i++; + while (inumheights && vi->heightlist[i] < ztop[0]) + { + 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; + } +} + //========================================================================== // // Split right edge of wall @@ -185,3 +277,32 @@ void GLWall::SplitRightEdge(texcoord * tcs) } } +void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr) +{ + if (vertexes[1] == NULL) return; + + vertex_t * vi = vertexes[1]; + + if (vi->numheights) + { + 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; + + while (i>0 && vi->heightlist[i] >= ztop[1]) i--; + while (i>0 && vi->heightlist[i] > zbottom[1]) + { + 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 e53513167..207b7bdbf 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 @@ -215,6 +216,11 @@ private: 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: void Process(seg_t *seg, sector_t *frontsector, sector_t *backsector); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index d7edc6ef7..63e5086a7 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -48,7 +48,9 @@ #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/scene/gl_drawinfo.h" @@ -248,38 +250,80 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) // the rest of the code is identical for textured rendering and lights - 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 (!gl_usevbo) + { + glBegin(GL_TRIANGLE_FAN); - if (split && glseg.fracleft==0) SplitLeftEdge(tcs); + // lower left corner + if (textured & 1) glTexCoord2f(tcs[0].u, tcs[0].v); + glVertex3f(glseg.x1, zbottom[0], glseg.y1); - // upper left corner - if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v); - glVertex3f(glseg.x1,ztop[0],glseg.y1); + if (split && glseg.fracleft == 0) SplitLeftEdge(tcs); - if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs); + // upper left corner + if (textured & 1) glTexCoord2f(tcs[1].u, tcs[1].v); + glVertex3f(glseg.x1, ztop[0], glseg.y1); - // color for right side - if (color2) glColor4fv(color2); + if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs); - // upper right corner - if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v); - glVertex3f(glseg.x2,ztop[1],glseg.y2); + // color for right side + if (color2) glColor4fv(color2); - if (split && glseg.fracright==1) SplitRightEdge(tcs); + // upper right corner + if (textured & 1) glTexCoord2f(tcs[2].u, tcs[2].v); + glVertex3f(glseg.x2, ztop[1], glseg.y2); - // lower right corner - if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v); - glVertex3f(glseg.x2,zbottom[1],glseg.y2); + if (split && glseg.fracright == 1) SplitRightEdge(tcs); - if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs); + // lower right corner + if (textured & 1) glTexCoord2f(tcs[3].u, tcs[3].v); + glVertex3f(glseg.x2, zbottom[1], glseg.y2); - glEnd(); + if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs); + + glEnd(); + + vertexcount += 4; + } + else + { + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + + ptr->x = glseg.x1; + ptr->y = glseg.y1; + ptr->z = zbottom[0]; + ptr->u = tcs[0].u; + ptr->v = tcs[0].v; + ptr++; + if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr); + ptr->x = glseg.x1; + ptr->y = glseg.y1; + ptr->z = ztop[0]; + ptr->u = tcs[1].u; + ptr->v = tcs[1].v; + ptr++; + if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr); + ptr->x = glseg.x2; + ptr->y = glseg.y2; + ptr->z = ztop[1]; + ptr->u = tcs[2].u; + ptr->v = tcs[2].v; + ptr++; + if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr); + ptr->x = glseg.x2; + ptr->y = glseg.y2; + ptr->z = zbottom[1]; + ptr->u = tcs[3].u; + ptr->v = tcs[3].v; + ptr++; + if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); + vertexcount += 4; + } - vertexcount+=4; } From 09f407143649616bba8c35755dced5711481504e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 13:27:51 +0200 Subject: [PATCH 003/138] Ok, it had to be done: Removed shader support for pre GLSL 1.3/GL 3.0 hardware. The compromises needed to accomodate these are just too bad and would block any attempt at streamlining the code. --- src/gl/data/gl_data.cpp | 9 +- src/gl/dynlights/gl_dynlight1.cpp | 12 ++- src/gl/models/gl_models.cpp | 6 +- src/gl/renderer/gl_lightdata.cpp | 8 +- src/gl/renderer/gl_renderstate.cpp | 62 +++--------- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_sprite.cpp | 4 +- src/gl/scene/gl_walls_draw.cpp | 2 +- src/gl/scene/gl_weapon.cpp | 2 +- src/gl/shaders/gl_shader.cpp | 101 +++++++------------- src/gl/shaders/gl_shader.h | 2 - src/gl/system/gl_framebuffer.cpp | 2 +- src/gl/system/gl_interface.cpp | 19 +--- src/gl/system/gl_interface.h | 16 +++- src/gl/system/gl_menu.cpp | 26 +---- src/gl/textures/gl_hqresize.cpp | 2 +- src/gl/textures/gl_material.cpp | 4 +- wadsrc/static/menudef.z | 20 +--- wadsrc/static/shaders/glsl/fogboundary.fp | 18 ++-- wadsrc/static/shaders/glsl/main.fp | 20 ++-- wadsrc/static/shaders/glsl/main.vp | 14 +-- wadsrc/static/shaders/glsl/main_colormap.fp | 24 +++-- wadsrc/static/shaders/glsl/main_foglayer.fp | 18 ++-- 23 files changed, 132 insertions(+), 261 deletions(-) diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index e0bb5ee6b..da72f6313 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -356,7 +356,14 @@ 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; + if (!gl.hasGLSL()) + { + // light modes 2 and 8 require shaders + if (glset.map_lightmode == 2 || glset.map_lightmode == 8) + { + glset.map_lightmode = 3; + } + } } else { diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 0b2ffa43d..e09207411 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -70,7 +70,17 @@ CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN CUSTOM_CVAR (Bool, gl_dynlight_shader, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { - if (self && (gl.maxuniforms < 1024 || gl.shadermodel < 4)) self = false; + if (self) + { + if (!gl.hasGLSL()) + { + self = false; + } + else if (gl.maxuniforms < 1024 && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + { + self = false; + } + } } CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 39668cd02..4b8a8e44b 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -753,7 +753,7 @@ void gl_RenderModel(GLSprite * spr, int cm) 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) + if (!gl.hasGLSL()) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -795,7 +795,7 @@ void gl_RenderModel(GLSprite * spr, int cm) glRotatef(smf->pitchoffset, 0, 0, 1); glRotatef(-smf->rolloffset, 1, 0, 0); - if (gl.shadermodel >= 4) glActiveTexture(GL_TEXTURE0); + if (gl.hasGLSL()) glActiveTexture(GL_TEXTURE0); #if 0 if (gl_light_models) @@ -814,7 +814,7 @@ void gl_RenderModel(GLSprite * spr, int cm) gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, NULL, translation ); - if (gl.shadermodel < 4) + if (!gl.hasGLSL()) { glMatrixMode(GL_MODELVIEW); glPopMatrix(); diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 9292c765e..1523443c8 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -80,12 +80,12 @@ CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE); bool gl_BrightmapsActive() { - return gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_brightmap_shader); + return gl.hasGLSL(); } bool gl_GlowActive() { - return gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_glow_shader); + return gl.hasGLSL(); } //========================================================================== @@ -125,7 +125,7 @@ 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; + if (self == 2 && !gl.hasGLSL()) self = 1; } CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL) @@ -133,7 +133,7 @@ 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 ((newself == 2 || newself == 8) && !gl.hasGLSL()) newself = 3; if (self != newself) self = newself; glset.lightmode = newself; } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index f0ceb40fa..8d3423423 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -104,28 +104,13 @@ int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, flo } } - if (gl.shadermodel == 4) + if (gl.hasGLSL()) { 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; + usecmshader = false; softwarewarp = shaderindex > 0 && shaderindex < 3? shaderindex : 0; shaderindex = 0; } @@ -149,43 +134,22 @@ bool FRenderState::ApplyShader() bool useshaders = false; FShader *activeShader = NULL; - if (mSpecialEffect > 0 && gl.shadermodel > 2) + if (mSpecialEffect > 0 && gl.hasGLSL()) { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); } - else + else if (gl.hasGLSL()) { - switch (gl.shadermodel) + useshaders = (!m2D || mEffectState != 0 || mColormapState); // all 3D rendering and 2D with texture effects. + } + + if (useshaders) + { + FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4); + + if (shd != NULL) { - 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; - } - - if (useshaders) - { - FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4); - - if (shd != NULL) - { - activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); - } + activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); } } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 1aa3c2b3f..8fe1f180a 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -288,7 +288,7 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) void FGLRenderer::SetViewMatrix(bool mirror, bool planemirror) { - if (gl.shadermodel >= 4) + if (gl.hasGLSL()) { glActiveTexture(GL_TEXTURE7); glMatrixMode(GL_TEXTURE); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 63efb978e..d018d2eea 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -218,7 +218,7 @@ 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) + if (gl.hasGLSL() && !gl_nolayer) { // fog layer only works on modern hardware. foglayer = true; @@ -795,7 +795,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.hasGLSL() && gl_fuzztype != 0) { // Todo: implement shader selection here RenderStyle = LegacyRenderStyles[STYLE_Translucent]; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 63e5086a7..f060978e4 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -338,7 +338,7 @@ 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)) + if (gl.hasGLSL()) { int rel = rellight + getExtraLight(); gl_SetFog(lightlevel, rel, &Colormap, false); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index aa991c0a0..fe3aee0ff 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -313,7 +313,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) vis.RenderStyle.CheckFuzz(); if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl.shadermodel >= 4 && gl_fuzztype != 0) + if (gl.hasGLSL() && gl_fuzztype != 0) { // Todo: implement shader selection here vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index ca1921bd4..2065768fa 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -79,7 +79,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * static char buffer[10000]; FString error; - if (gl.shadermodel > 0) + if (gl.hasGLSL()) { int vp_lump = Wads.CheckNumForFullName(vert_prog_lump); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump); @@ -93,10 +93,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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. @@ -307,52 +303,40 @@ FShaderContainer::FShaderContainer(const char *ShaderName, const char *ShaderPat 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++) { - for(int i = 0;i < NUM_SHADERS; i++) + FString name; + + name << ShaderName << shaderdesc[i]; + + try { - FString name; - - name << ShaderName << shaderdesc[i]; - - try + FString str; + if ((i&4) != 0) { - FString str; - if ((i&4) != 0) + if (gl.maxuniforms < 1024) { - 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; + 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"; } - catch(CRecoverableError &err) + 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; - I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage()); } } + 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)); } //========================================================================== @@ -502,28 +486,15 @@ FShaderManager::~FShaderManager() // //========================================================================== -void FShaderManager::Recompile() -{ - Clean(); - CompileShaders(); -} - -//========================================================================== -// -// -// -//========================================================================== - void FShaderManager::CompileShaders() { mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; - if (gl.shadermodel > 0) + if (gl.hasGLSL()) { 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 } for(unsigned i = 0; i < usershaders.Size(); i++) @@ -531,25 +502,19 @@ void FShaderManager::CompileShaders() FString name = ExtractFileBase(usershaders[i]); FName sfn = name; - if (gl.shadermodel > 2) - { - FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]); - mTextureEffects.Push(shc); - } + FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]); + mTextureEffects.Push(shc); } - if (gl.shadermodel > 2) + for(int i=0;iLoad(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, + effectshaders[i].fp2, effectshaders[i].defines)) { - FShader *eff = new FShader(); - if (!eff->Load(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; } } } @@ -604,7 +569,7 @@ 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 (gl.hasGLSL() && mActiveShader != sh) { glUseProgram(sh == NULL? 0 : sh->GetHandle()); mActiveShader = sh; diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 61053287c..bd3aa0f30 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -153,8 +153,6 @@ public: } return NULL; } - - void Recompile(); }; #define FIRST_USER_SHADER 12 diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 99e9bd9a4..d22c6a5ed 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -73,9 +73,9 @@ CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE) FGLRenderer *GLRenderer; -void gl_SetupMenu(); void gl_LoadExtensions(); void gl_PrintStartupLog(); +void gl_SetupMenu(); //========================================================================== // diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 31176d220..434659a7c 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -133,7 +133,6 @@ void gl_LoadExtensions() // This loads any function pointers and flags that require a vaild render context to // initialize properly - gl.shadermodel = 0; // assume no shader support gl.vendorstring=(char*)glGetString(GL_VENDOR); if (CheckExtension("GL_ARB_texture_compression")) gl.flags|=RFL_TEXTURE_COMPRESSION; @@ -141,23 +140,11 @@ void gl_LoadExtensions() if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; gl.version = strtod((char*)glGetString(GL_VERSION), NULL); + gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL); + if (Args->CheckParm("-noshader")) gl.glslversion = 0.0f; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // 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_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 (gl.version >= 3.f) { @@ -187,7 +174,7 @@ void gl_PrintStartupLog() 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; + if (gl.hasGLSL()) gl.maxuniforms = v; glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &v); Printf ("Max. vertex uniforms: %d\n", v); glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index fdadd67d9..66f96be00 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -6,11 +6,12 @@ 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_FRAMEBUFFER = 32, - RFL_BUFFER_STORAGE = 64, + RFL_FRAMEBUFFER = 4, + RFL_BUFFER_STORAGE = 8, + RFL_SHADER_STORAGE_BUFFER = 16, }; enum TexMode @@ -30,9 +31,9 @@ enum TexMode struct RenderContext { unsigned int flags; - unsigned int shadermodel; unsigned int maxuniforms; float version; + float glslversion; int max_texturesize; char * vendorstring; @@ -40,6 +41,11 @@ struct RenderContext { return maxuniforms>=2048? 128:64; } + + bool hasGLSL() const + { + return glslversion >= 1.3f; + } }; extern RenderContext gl; diff --git a/src/gl/system/gl_menu.cpp b/src/gl/system/gl_menu.cpp index 75436209c..0518606b9 100644 --- a/src/gl/system/gl_menu.cpp +++ b/src/gl/system/gl_menu.cpp @@ -59,7 +59,7 @@ CUSTOM_CVAR (Float, vid_contrast, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // when they are actually valid. void gl_SetupMenu() { - if (gl.shadermodel < 4) + if (!gl.hasGLSL()) { // Radial fog and Doom lighting are not available in SM < 4 cards // The way they are implemented does not work well on older hardware. @@ -95,28 +95,4 @@ void gl_SetupMenu() 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/textures/gl_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp index 2c5f831f1..837977145 100644 --- a/src/gl/textures/gl_hqresize.cpp +++ b/src/gl/textures/gl_hqresize.cpp @@ -225,7 +225,7 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u 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)) + if (inputTexture->bWarped && !gl.hasGLSL()) return inputBuffer; switch (inputTexture->UseType) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 9cb3ef523..5d471fc81 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -624,7 +624,7 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand) { expanded = false; } - else if (gl.shadermodel > 2) + else if (gl.hasGLSL()) { if (tx->gl_info.shaderindex >= FIRST_USER_SHADER) { @@ -670,7 +670,7 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand) tex = tx; tx->gl_info.mExpanded = expanded; - FTexture *basetex = tx->GetRedirect(gl.shadermodel < 4); + FTexture *basetex = tx->GetRedirect(!gl.hasGLSL()); if (!expanded && !basetex->gl_info.mExpanded && basetex->UseType != FTexture::TEX_Sprite) { // check if the texture is just a simple redirect to a patch diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index 329042b74..0db780620 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" @@ -186,17 +179,7 @@ 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" + Option "Use vertex buffer", gl_usevbo, "OnOff" } OptionMenu "OpenGLOptions" @@ -204,7 +187,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/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 5b43dfd95..5ab8ac717 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -18,18 +18,14 @@ 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 (fogenabled == -1) + { fogdist = pixelpos.w; - #endif + } + else + { + fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); + } fogfactor = exp2 (fogparm.z * fogdist); gl_FragColor = vec4(fogcolor.rgb, 1.0 - fogfactor); } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index aa2c33238..6bb17a2ad 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -102,7 +102,7 @@ vec4 getLightColor(float fogdist, float fogfactor) // if (fogenabled > 0) { - #if (!defined(NO_SM4) || defined(DOOMLIGHT)) && !defined SOFTLIGHT + #if (defined(DOOMLIGHT)) && !defined SOFTLIGHT // special lighting mode 'Doom' not available on older cards for performance reasons. if (fogdist < fogparm.y) { @@ -197,20 +197,14 @@ void main() // if (fogenabled != 0) { - #ifndef NO_SM4 - if (fogenabled == 1 || fogenabled == -1) - { - fogdist = pixelpos.w; - } - else - { - fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); - } - #elif !defined(FOG_RADIAL) + if (fogenabled == 1 || fogenabled == -1) + { fogdist = pixelpos.w; - #else + } + else + { fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); - #endif + } fogfactor = exp2 (fogparm.z * fogdist); } #endif diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 7aebb8171..fc905b753 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -19,12 +19,8 @@ void main() lightlevel = lightlevel_in; #endif - #ifndef NO_SM4 - // Yes, I know... But using a texture matrix here saves me from the hassle of tracking its state across shaders. ;) - vec4 worldcoord = gl_TextureMatrix[7] * gl_Vertex; - #else - vec4 worldcoord = gl_Vertex; - #endif + // We use texture matrix 7 as the model matrix and the modelview matrix as the view matrix. + vec4 worldcoord = gl_TextureMatrix[7] * gl_Vertex; vec4 eyeCoordPos = gl_ModelViewMatrix * worldcoord; gl_FrontColor = gl_Color; @@ -55,11 +51,7 @@ void main() gl_TexCoord[0].xy = sst; #endif - #ifndef NO_SM4 - gl_Position = gl_ModelViewProjectionMatrix * worldcoord; - #else - gl_Position = ftransform(); - #endif + gl_Position = gl_ModelViewProjectionMatrix * worldcoord; #ifdef __GLSL_CG_DATA_TYPES gl_ClipVertex = eyeCoordPos; #endif diff --git a/wadsrc/static/shaders/glsl/main_colormap.fp b/wadsrc/static/shaders/glsl/main_colormap.fp index a64f67bc2..fa0f28f25 100644 --- a/wadsrc/static/shaders/glsl/main_colormap.fp +++ b/wadsrc/static/shaders/glsl/main_colormap.fp @@ -16,19 +16,17 @@ vec4 getTexel(vec2 st) { vec4 texel = texture2D(tex, st); - #ifndef NO_TEXTUREMODE - // - // Apply texture modes - // - if (texturemode == 2) - { - texel.a = 1.0; - } - else if (texturemode == 1) - { - texel.rgb = vec3(1.0,1.0,1.0); - } - #endif + // + // Apply texture modes + // + if (texturemode == 2) + { + texel.a = 1.0; + } + else if (texturemode == 1) + { + texel.rgb = vec3(1.0,1.0,1.0); + } return texel; } diff --git a/wadsrc/static/shaders/glsl/main_foglayer.fp b/wadsrc/static/shaders/glsl/main_foglayer.fp index bfe08d327..3802e3d85 100644 --- a/wadsrc/static/shaders/glsl/main_foglayer.fp +++ b/wadsrc/static/shaders/glsl/main_foglayer.fp @@ -39,18 +39,14 @@ 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 (fogenabled == -1) + { fogdist = pixelpos.w; - #endif + } + else + { + fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); + } fogfactor = exp2 (fogparm.z * fogdist); vec4 frag = Process(vec4(1.0,1.0,1.0,1.0)); From f3a9cb0cfa7a9ade4878f2fed84ef1a9f20d8552 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 14:46:37 +0200 Subject: [PATCH 004/138] remove special texture creation for fullscreen colormaps. On GL 3.x+ this isn't needed at all and on older hardware it causes performance issues, in particular with hires textures due to impossibility of precaching. In addition it forces some really awkward handling of lighting for things that have their own color, like stenciled sprites or particles. With this special case gone it will be possible to handle this case in a saner manner than it is right now. As compensation for older hardware a fullscreen blend will be drawn over the entire screen. This won't be 100% accurate but it's preferable to keeping the current method. --- src/gl/renderer/gl_lightdata.cpp | 27 +++-- src/gl/renderer/gl_renderstate.cpp | 48 ++++---- src/gl/scene/gl_scene.cpp | 182 +++++++++++++++++++---------- 3 files changed, 161 insertions(+), 96 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 1523443c8..0660f04c2 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -275,22 +275,27 @@ void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float float & r=*pred,& g=*pgreen,& b=*pblue; int torch=0; - if (gl_fixedcolormap) + if (gl_fixedcolormap) { - if (gl_fixedcolormap==CM_LITE) + if (!gl_enhanced_nightvision || !gl.hasGLSL()) { - if (gl_enhanced_nightvision) r=0.375f, g=1.0f, b=0.375f; - else r=g=b=1.0f; + // we cannot multiply the light in here without causing major problems with the ThingColor so for older hardware + // these maps are done as a postprocessing overlay. + r = g = b = 1.0f; } - else if (gl_fixedcolormap>=CM_TORCH) + else if (gl_fixedcolormap == CM_LITE) { - 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; + 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; + g = r; + b = g * 0.75f; + } + else r = g = b = 1.0f; return; } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index d0d5c34b3..67a53bf19 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -92,33 +92,35 @@ void FRenderState::Reset() 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.hasGLSL()) { - usecmshader = cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK; + if (shaderindex == 3) + { + // Brightmap should not be used. + if (!mBrightmapEnabled || cm >= CM_FIRSTSPECIALCOLORMAP) + { + shaderindex = 0; + } + } + + mColormapState = cm; + if (cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK) + { + cm = CM_DEFAULT; + } + mEffectState = shaderindex; + mWarpTime = warptime; } else { - usecmshader = false; + if (cm != CM_SHADE) cm = CM_DEFAULT; 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; } @@ -141,18 +143,18 @@ bool FRenderState::ApplyShader() else if (gl.hasGLSL()) { useshaders = (!m2D || mEffectState != 0 || mColormapState); // all 3D rendering and 2D with texture effects. - } - - if (useshaders) - { - FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4); - - if (shd != NULL) + if (useshaders) { - activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); + FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); + + if (shd != NULL) + { + activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); + } } } + if (activeShader) { int fogset = 0; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 8fe1f180a..d3758c0a4 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -616,6 +616,19 @@ void FGLRenderer::DrawScene(bool toscreen) } +static void FillScreen() +{ + gl_RenderState.EnableAlphaTest(false); + gl_RenderState.EnableTexture(false); + 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(); +} + //========================================================================== // // Draws a blend over the entire view @@ -642,12 +655,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; } } } @@ -655,71 +668,124 @@ 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) + { + gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); + glColor4f(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 (!gl.hasGLSL()) + { + float r, g, b; + bool inverse = false; + const float BLACK_THRESH = 0.05f; + const float WHITE_THRESH = 0.95f; + + // for various reasons (performance and keeping the lighting code clean) + // we no longer do colormapped textures on pre GL 3.0 hardware and instead do + // just a fullscreen overlay to emulate the inverse invulnerability effect or similar fullscreen blends. + if (gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP && gl_fixedcolormap < CM_MAXCOLORMAP) + { + FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; + + if (scm->ColorizeEnd[0] < BLACK_THRESH && scm->ColorizeEnd[1] < BLACK_THRESH && scm->ColorizeEnd[2] < BLACK_THRESH) + { + r = scm->ColorizeStart[0]; + g = scm->ColorizeStart[1]; + b = scm->ColorizeStart[2]; + inverse = true; + } + else + { + r = scm->ColorizeEnd[0]; + g = scm->ColorizeEnd[1]; + b = scm->ColorizeEnd[2]; + } + + } + else if (gl_enhanced_nightvision) + { + if (gl_fixedcolormap == CM_LITE) + { + r = 0.375f, g = 1.0f, b = 0.375f; + } + 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; + g = r; + b = g * 0.75f; + } + else r = g = b = 1.f; + } + + if (inverse) + { + gl_RenderState.BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + glColor4f(1.f, 1.f, 1.f, 1.f); + FillScreen(); + } + + if (r < WHITE_THRESH || g < WHITE_THRESH || b < WHITE_THRESH) + { + gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); + glColor4f(r, g, b, 1.0f); + FillScreen(); } } - 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) - { - 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(); - } - } - 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 // When I was writing this the original was called too late so that I @@ -741,16 +807,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(); + FillScreen(); } } From 53f4cd010837e3bbdd4c897daa97d44a7ee8a911 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 16:06:25 +0200 Subject: [PATCH 005/138] - added objectcolor uniform. This will be used to hold the thingcolor for shader based rendering. --- src/gl/dynlights/gl_dynlight1.cpp | 8 ------- src/gl/renderer/gl_renderstate.cpp | 9 ++++++++ src/gl/renderer/gl_renderstate.h | 23 +++++++++++++++++++- src/gl/scene/gl_flats.cpp | 1 - src/gl/scene/gl_sprite.cpp | 3 ++- src/gl/scene/gl_walls_draw.cpp | 1 + src/gl/shaders/gl_shader.h | 5 ++++- wadsrc/static/shaders/glsl/func_notexture.fp | 2 +- wadsrc/static/shaders/glsl/main.fp | 3 ++- wadsrc/static/shaders/glsl/main_colormap.fp | 3 ++- 10 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index e09207411..57da56b40 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -234,14 +234,6 @@ bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & u { 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; } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 67a53bf19..84f270e06 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -78,6 +78,7 @@ void FRenderState::Reset() mAlphaFunc = GL_GEQUAL; mAlphaThreshold = 0.5f; mBlendEquation = GL_FUNC_ADD; + mObjectColor = 0xffffffff; glBlendEquation = -1; m2D = true; mVertexBuffer = mCurrentVertexBuffer = NULL; @@ -158,6 +159,7 @@ bool FRenderState::ApplyShader() if (activeShader) { int fogset = 0; + //glColor4fv(mColor.vec); if (mFogEnabled) { if ((mFogColor & 0xffffff) == 0) @@ -226,6 +228,11 @@ bool FRenderState::ApplyShader() { glUniform3fv(activeShader->dlightcolor_index, 1, mDynLight); } + if (mObjectColor != activeShader->currentobjectcolor) + { + activeShader->currentobjectcolor = mObjectColor; + glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f); + } return true; } @@ -276,6 +283,8 @@ void FRenderState::Apply(bool forcenoshader) } if (forcenoshader || !ApplyShader()) { + //if (mColor.vec[0] >= 0.f) glColor4fv(mColor.vec); + GLRenderer->mShaderManager->SetActiveShader(NULL); if (mTextureMode != ffTextureMode) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 7e611f7a5..35f5795a2 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -107,11 +107,12 @@ class FRenderState bool m2D; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; - + FStateVec4 mColor; FStateVec3 mCameraPos; FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTopPlane, mGlowBottomPlane; PalEntry mFogColor; + PalEntry mObjectColor; float mFogDensity; int mEffectState; @@ -149,6 +150,26 @@ public: mVertexBuffer = vb; } + void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) + { + mColor.Set(r, g, b, a); + } + + 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); + } + + 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); + } + + void ResetColor() + { + mColor.Set(1,1,1,1); + } + void SetTextureMode(int mode) { mTextureMode = mode; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index c32011998..f24db1fdd 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -325,7 +325,6 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) { if (gl_usevbo && vboindex >= 0) { - //glColor3f( 1.f,.5f,.5f); int index = vboindex; for (int i=0; isubsectorcount; i++) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index d018d2eea..46541fc27 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -749,7 +749,8 @@ void GLSprite::Process(AActor* thing,sector_t * sector) 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; + // needs to be fixed later + //Colormap.colormap = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP; } } } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index f060978e4..7f7538dc4 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -373,6 +373,7 @@ void GLWall::RenderFogBoundary() gl_RenderState.AlphaFunc(GL_GREATER,0); glDepthFunc(GL_LEQUAL); glColor4f(fc[0],fc[1],fc[2], fogd1); + gl_RenderState.SetColor(-1, 0, 0, 0); // we do not want the render state to control the color. if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); // Korshun. flags &= ~GLWF_GLOW; diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index bd3aa0f30..4b0c37e1e 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -40,7 +40,9 @@ class FShader int glowtopcolor_index; int glowbottomplane_index; int glowtopplane_index; + int objectcolor_index; + PalEntry currentobjectcolor; int currentglowstate; int currentfogenabled; int currenttexturemode; @@ -59,7 +61,7 @@ public: currentglowstate = currentfogenabled = currenttexturemode = 0; currentlightfactor = currentlightdist = 0.0f; currentfogdensity = -1; - currentfogcolor = 0; + currentobjectcolor = currentfogcolor = 0; timer_index = -1; desaturation_index = -1; @@ -73,6 +75,7 @@ public: fogcolor_index = -1; lights_index = -1; dlightcolor_index = -1; + objectcolor_index = -1; glowtopplane_index = -1; glowbottomplane_index = -1; glowtopcolor_index = -1; diff --git a/wadsrc/static/shaders/glsl/func_notexture.fp b/wadsrc/static/shaders/glsl/func_notexture.fp index 99ef44f68..904d4a6cd 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) { - return color; + return color*objectcolor; } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 6bb17a2ad..a99ffa330 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -23,6 +23,7 @@ uniform vec4 lights[128]; uniform int fogenabled; uniform vec4 fogcolor; +uniform vec4 objectcolor; uniform vec3 dlightcolor; uniform vec3 camerapos; varying vec4 pixelpos; @@ -158,7 +159,7 @@ vec4 getTexel(vec2 st) } #endif - return desaturate(texel); + return desaturate(texel * objectcolor); } //=========================================================================== diff --git a/wadsrc/static/shaders/glsl/main_colormap.fp b/wadsrc/static/shaders/glsl/main_colormap.fp index fa0f28f25..d4c079cdd 100644 --- a/wadsrc/static/shaders/glsl/main_colormap.fp +++ b/wadsrc/static/shaders/glsl/main_colormap.fp @@ -1,6 +1,7 @@ uniform int texturemode; uniform sampler2D tex; +uniform vec4 objectcolor; uniform vec3 colormapstart; uniform vec3 colormaprange; @@ -28,7 +29,7 @@ vec4 getTexel(vec2 st) texel.rgb = vec3(1.0,1.0,1.0); } - return texel; + return texel*objectcolor; } From 52056a05bda71b47740ebc5567fe367df8d2f5fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 16:49:17 +0200 Subject: [PATCH 006/138] - changed handling of DynLight in shader to serve as a global dynamic light color for all lighting modes. --- src/gl/dynlights/gl_dynlight.h | 4 +- src/gl/dynlights/gl_dynlight1.cpp | 13 +----- src/gl/renderer/gl_lightdata.cpp | 67 ++++++++---------------------- src/gl/renderer/gl_renderstate.cpp | 9 ++-- src/gl/renderer/gl_renderstate.h | 15 +++++-- src/gl/scene/gl_flats.cpp | 4 +- src/gl/scene/gl_skydome.cpp | 2 +- src/gl/scene/gl_walls_draw.cpp | 4 +- src/gl/scene/gl_weapon.cpp | 12 ++++-- src/gl/shaders/gl_shader.cpp | 1 + src/gl/shaders/gl_shader.h | 3 +- wadsrc/static/shaders/glsl/main.fp | 16 ++++--- 12 files changed, 61 insertions(+), 89 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index ca3b2ec90..dbf89324b 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -182,8 +182,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_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data); +bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, bool checkside=true, bool forceadditive=true); bool gl_SetupLightTexture(); diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 57da56b40..90d65559c 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -100,8 +100,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; @@ -147,14 +146,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; @@ -176,7 +167,7 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, // //========================================================================== bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, - float & scale, int desaturation, bool checkside, bool forceadditive) + float & scale, bool checkside, bool forceadditive) { Vector fn, pos; diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 0660f04c2..1ceb609c8 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -256,13 +256,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)); + return PalEntry(255, BYTE(r), BYTE(g), BYTE(b)); } //========================================================================== @@ -373,7 +375,7 @@ void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, Pal // //========================================================================== -float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) +static float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) { float density; @@ -417,98 +419,65 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) } -//========================================================================== -// -// Check fog by current lighting info -// -//========================================================================== - -bool gl_CheckFog(FColormap *cm, int lightlevel) -{ - // Check for fog boundaries. This needs a few more checks for the sectors - bool frontfog; - - PalEntry fogcolor = cm->FadeColor; - - if ((fogcolor.d & 0xffffff) == 0) - { - frontfog = 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 = lightlevel < 248; - } - return frontfog; -} - //========================================================================== // // 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)); } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 84f270e06..96b782771 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -224,15 +224,16 @@ bool FRenderState::ApplyShader() glUniform3iv(activeShader->lightrange_index, 1, mNumLights); glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData); } - if (glset.lightmode == 8) - { - glUniform3fv(activeShader->dlightcolor_index, 1, mDynLight); - } if (mObjectColor != activeShader->currentobjectcolor) { activeShader->currentobjectcolor = mObjectColor; glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f); } + if (mDynColor != activeShader->currentdlightcolor) + { + activeShader->currentobjectcolor = mObjectColor; + glUniform4f(activeShader->dlightcolor_index, mDynColor.r / 255.f, mDynColor.g / 255.f, mDynColor.b / 255.f, 0); + } return true; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 35f5795a2..2c2c43605 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -95,7 +95,6 @@ class FRenderState bool mBrightmapEnabled; int mSpecialEffect; int mTextureMode; - float mDynLight[3]; float mLightParms[2]; int mNumLights[3]; float *mLightData; @@ -113,6 +112,7 @@ class FRenderState FStateVec4 mGlowTopPlane, mGlowBottomPlane; PalEntry mFogColor; PalEntry mObjectColor; + PalEntry mDynColor; float mFogDensity; int mEffectState; @@ -153,21 +153,25 @@ public: void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mColor.Set(r, g, b, a); + glColor4fv(mColor.vec); } 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); + glColor4fv(mColor.vec); } 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); + glColor4fv(mColor.vec); } void ResetColor() { mColor.Set(1,1,1,1); + glColor4fv(mColor.vec); } void SetTextureMode(int mode) @@ -224,9 +228,12 @@ public: void SetDynLight(float r, float g, float b) { - mDynLight[0] = r; - mDynLight[1] = g; - mDynLight[2] = b; + mDynColor = PalEntry(xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255)); + } + + void SetDynLight(PalEntry pe) + { + mDynColor = pe; } void SetFog(PalEntry c, float d) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index f24db1fdd..4a4c0d715 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -143,7 +143,7 @@ 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)) + if (!gl_SetupLight(p, light, nearPt, up, right, scale, false, foggy)) { node=node->nextLight; continue; @@ -206,7 +206,7 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) } p.Set(plane.plane); - gl_GetLight(p, light, Colormap.colormap, false, false, lightdata); + gl_GetLight(p, light, false, false, lightdata); node = node->nextLight; } } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index dee3ea4e3..7dbf5e573 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -602,7 +602,7 @@ void GLSkyPortal::DrawContents() { gl_RenderState.EnableTexture(false); foglayer=true; - glColor4f(FadeColor.r/255.0f,FadeColor.g/255.0f,FadeColor.b/255.0f,skyfog/255.0f); + gl_RenderState.SetColorAlpha(FadeColor, skyfog / 255.0f); RenderDome(FNullTextureID(), NULL, 0, 0, false, CM_DEFAULT); gl_RenderState.EnableTexture(true); foglayer=false; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 7f7538dc4..b4af1e28d 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -81,7 +81,7 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light) return false; } - if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, true, !!(flags&GLWF_FOGGY))) + if (!gl_SetupLight(p, light, nearPt, up, right, scale, true, !!(flags&GLWF_FOGGY))) { return false; } @@ -197,7 +197,7 @@ void GLWall::SetupLights() } if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) { - gl_GetLight(p, node->lightsource, Colormap.colormap, true, false, lightdata); + gl_GetLight(p, node->lightsource, true, false, lightdata); } } } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index fe3aee0ff..c9f8434c4 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -286,7 +286,8 @@ 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; + visstyle_t vis; vis.RenderStyle=playermo->RenderStyle; @@ -345,6 +346,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 +367,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,7 +374,8 @@ 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; } @@ -384,6 +386,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) DrawPSprite (player,psp,psp->sx+ofsx, psp->sy+ofsy, cm.colormap, hudModelStep, OverrideShader); } } + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.SetDynLight(0, 0, 0); gl_RenderState.EnableBrightmap(false); glset.lightmode = oldlightmode; } @@ -408,7 +412,7 @@ 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. diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 2065768fa..8f993b857 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -177,6 +177,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * fogcolor_index = glGetUniformLocation(hShader, "fogcolor"); lights_index = glGetUniformLocation(hShader, "lights"); dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor"); + objectcolor_index = glGetUniformLocation(hShader, "objectcolor"); glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor"); glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 4b0c37e1e..62c87c1f9 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -42,6 +42,7 @@ class FShader int glowtopplane_index; int objectcolor_index; + PalEntry currentdlightcolor; PalEntry currentobjectcolor; int currentglowstate; int currentfogenabled; @@ -61,7 +62,7 @@ public: currentglowstate = currentfogenabled = currenttexturemode = 0; currentlightfactor = currentlightdist = 0.0f; currentfogdensity = -1; - currentobjectcolor = currentfogcolor = 0; + currentdlightcolor = currentobjectcolor = currentfogcolor = 0; timer_index = -1; desaturation_index = -1; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index a99ffa330..8587b5ac3 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -24,7 +24,7 @@ uniform vec4 lights[128]; uniform int fogenabled; uniform vec4 fogcolor; uniform vec4 objectcolor; -uniform vec3 dlightcolor; +uniform vec4 dlightcolor; uniform vec3 camerapos; varying vec4 pixelpos; varying vec4 fogparm; @@ -95,7 +95,7 @@ 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); + color.rgb *= clamp(vec3(newlightlevel), 0.0, 1.0); #endif #ifndef NO_FOG // @@ -187,11 +187,6 @@ void main() float fogdist = 0.0; float fogfactor = 0.0; - #ifdef DYNLIGHT - vec4 dynlight = vec4(0.0,0.0,0.0,0.0); - vec4 addlight = vec4(0.0,0.0,0.0,0.0); - #endif - #ifndef NO_FOG // // calculate fog factor @@ -214,6 +209,9 @@ void main() #ifdef DYNLIGHT + vec4 dynlight = dlightcolor; + vec4 addlight = vec4(0.0,0.0,0.0,0.0); + for(int i=0; i Date: Sun, 11 May 2014 16:51:33 +0200 Subject: [PATCH 007/138] -looks like we still need this... --- src/gl/renderer/gl_lightdata.cpp | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 1ceb609c8..3caa5cbc5 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -419,6 +419,40 @@ static float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) } +//========================================================================== +// +// Check fog by current lighting info +// +//========================================================================== + +bool gl_CheckFog(FColormap *cm, int lightlevel) +{ + // Check for fog boundaries. This needs a few more checks for the sectors + bool frontfog; + + PalEntry fogcolor = cm->FadeColor; + + if ((fogcolor.d & 0xffffff) == 0) + { + frontfog = 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 = lightlevel < 248; + } + return frontfog; +} + //========================================================================== // // Check if the current linedef is a candidate for a fog boundary From 607be91c4858244ad49ed4cb3c384f2b97a9eb47 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 16:54:11 +0200 Subject: [PATCH 008/138] - bad copy. --- src/gl/renderer/gl_lightdata.cpp | 2 +- src/gl/renderer/gl_renderstate.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 3caa5cbc5..afd5cdbcf 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -375,7 +375,7 @@ void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, Pal // //========================================================================== -static float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) +float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) { float density; diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 2c2c43605..e037fb637 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -236,6 +236,11 @@ public: mDynColor = pe; } + void SetObjectColor(PalEntry pe) + { + mObjectColor = pe; + } + void SetFog(PalEntry c, float d) { mFogColor = c; From 7793bbbcc978d766c1ac0621e543005ed96a9b84 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 17:56:38 +0200 Subject: [PATCH 009/138] Further cleanup of lighting code. - remove thing color from lighting calculations. - implement alpha textures and inverse sprites for infrared as texture modes. This still requires some handling for the alpha texture mode for non-shader rendering because there is no way in the fixed pipeline to do it. The inverted texture effect can be done with a texture combiner. - fixed: ThingColor for sprites was set in the wrong place. It must be in the Process function, not in the lighting calculation. - added functions for isolated calculation of sprites' dynlight color. --- src/gl/renderer/gl_lightdata.cpp | 28 ++++---- src/gl/renderer/gl_lightdata.h | 3 +- src/gl/renderer/gl_renderer.cpp | 1 + src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_sprite.cpp | 35 ++++------ src/gl/scene/gl_spritelight.cpp | 73 ++++++++++++++++++++- src/gl/scene/gl_wall.h | 4 ++ src/gl/system/gl_interface.cpp | 19 +----- src/gl/system/gl_interface.h | 16 ++--- wadsrc/static/shaders/glsl/main.fp | 12 +++- wadsrc/static/shaders/glsl/main_colormap.fp | 12 +++- 11 files changed, 133 insertions(+), 72 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index afd5cdbcf..102d1d43e 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -160,13 +160,17 @@ 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; + texturemode = TM_INVERSE; } if (blendequation == -1) @@ -316,14 +320,9 @@ 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 light, int rellight, const FColormap * cm, float *red, float *green, float *blue, 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; + gl_GetLightColor(light, rellight, cm, red, green, blue, weapon); } //========================================================================== @@ -331,20 +330,15 @@ void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, floa // set current light color // //========================================================================== -void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor, bool weapon) +void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, bool weapon) { float r,g,b; gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon); - if (glset.lightmode != 8) - { - glColor4f(r * ThingColor.r/255.0f, g * ThingColor.g/255.0f, b * ThingColor.b/255.0f, alpha); - } - else + gl_RenderState.SetColor(r, g, b, alpha); + if (glset.lightmode == 8) { - glColor4f(r, g, b, alpha); - if (gl_fixedcolormap) { glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); diff --git a/src/gl/renderer/gl_lightdata.h b/src/gl/renderer/gl_lightdata.h index 33d179b27..8eb70bbb9 100644 --- a/src/gl/renderer/gl_lightdata.h +++ b/src/gl/renderer/gl_lightdata.h @@ -20,8 +20,7 @@ void gl_SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefog 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; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 3ce805351..5120c00ea 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -338,6 +338,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) else { // This is an alpha texture + gl_RenderState.SetTextureMode(TM_REDTOALPHA); gltex->BindPatch(CM_SHADE, 0); } diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index bd39f8008..959641076 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -377,7 +377,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) { if (glset.lightmode == 8) { - gl_SetColor(light, rel, &p, a, extralight); // Korshun. + gl_SetColor(light, rel, &p, a, !!extralight); // Korshun. } else { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 46541fc27..d64f62b71 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -169,7 +169,7 @@ void GLSprite::Draw(int pass) } gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold); - glColor4f(0.2f,0.2f,0.2f,fuzzalpha); + gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha); additivefog = true; } else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One) @@ -181,22 +181,23 @@ void GLSprite::Draw(int pass) { if (actor) { - lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, ThingColor, trans, + lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, 0xffffffff, trans, fullbright || gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP, false); } else if (particle) { if (gl_light_particles) { - lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, ThingColor); + lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, 0xffffffff); } else { - gl_SetColor(lightlevel, rel, &Colormap, trans, ThingColor); + gl_SetColor(lightlevel, rel, &Colormap, trans); } } else return; } + gl_RenderState.SetObjectColor(ThingColor); if (gl_isBlack(Colormap.FadeColor)) foglevel=lightlevel; @@ -425,13 +426,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 +465,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; } } @@ -734,6 +721,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) { @@ -749,8 +740,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) if (gl_enhanced_nightvision && (thing->IsKindOf(RUNTIME_CLASS(AInventory)) || thing->flags3&MF3_ISMONSTER || thing->flags&MF_MISSILE || thing->flags&MF_CORPSE)) { - // needs to be fixed later - //Colormap.colormap = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP; + RenderStyle.Flags |= STYLEF_InvertSource; } } } @@ -785,8 +775,6 @@ void GLSprite::Process(AActor* thing,sector_t * sector) translation=thing->Translation; - ThingColor=0xffffff; - RenderStyle = thing->RenderStyle; OverrideShader = 0; trans = FIXED2FLOAT(thing->alpha); hw_styleflags = STYLEHW_Normal; @@ -955,8 +943,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; diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index b1216d86b..66a2b6c7f 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -57,6 +57,77 @@ #include "gl/textures/gl_material.h" +//========================================================================== +// +// Sets a single light value from all dynamic lights affecting the specified location +// +//========================================================================== + +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; + float out[3] = { 0.0f, 0.0f, 0.0f }; + + // Go through both light lists + for (int i = 0; i < 2; i++) + { + FLightNode * node = subsec->lighthead[i]; + while (node) + { + light = node->lightsource; + if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer()) + { + 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) + { + 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()) + { + 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; + } + } + gl_RenderState.SetDynLight(out[0], out[1], out[2]); +} + +void gl_SetDynSpriteLight(AActor *thing, particle_t *particle) +{ + if (thing != NULL) + { + gl_SetDynSpriteLight(thing, thing->x, thing->y, thing->z + (thing->height >> 1), thing->subsector); + } + else if (particle != NULL) + { + gl_SetDynSpriteLight(NULL, particle->x, particle->y, particle->z, particle->subsector); + } +} + //========================================================================== // // Gets the light for a sprite - takes dynamic lights into account @@ -294,7 +365,7 @@ int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int } else { - gl_SetColor(lightlevel, rellight, cm, alpha, ThingColor, weapon); + gl_SetColor(lightlevel, rellight, cm, alpha, weapon); } } gl_RenderState.AlphaFunc(GL_GEQUAL,alpha*gl_mask_sprite_threshold); diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 207b7bdbf..ba050c1b6 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -351,6 +351,10 @@ inline float Dist2(float x1,float y1,float x2,float y2) // Light + color +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); + + 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); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 434659a7c..7615373c5 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -194,8 +194,7 @@ void gl_PrintStartupLog() void gl_SetTextureMode(int type) { - static float white[] = {1.f,1.f,1.f,1.f}; - + gl.needAlphaTexture = false; if (type == TM_MASK) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -222,7 +221,7 @@ void gl_SetTextureMode(int type) 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) + else if (type == TM_INVERSE) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); @@ -237,22 +236,10 @@ void gl_SetTextureMode(int type) 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); + gl.needAlphaTexture = (type == TM_REDTOALPHA); } } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 66f96be00..13913f621 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -16,16 +16,13 @@ enum RenderFlags enum TexMode { - TMF_MASKBIT = 1, - TMF_OPAQUEBIT = 2, - TMF_INVERTBIT = 4, + TM_MODULATE = 0, // (r, g, b, a) + TM_MASK = 1, // (1, 1, 1, a) + TM_OPAQUE = 2, // (r, g, b, 1) + TM_INVERSE = 3, // (1-r, 1-g, 1-b, a) + TM_REDTOALPHA = 4, // (1, 1, 1, r) - 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, + // 4 cannot be done natively without shaders and requires special textures. }; struct RenderContext @@ -36,6 +33,7 @@ struct RenderContext float glslversion; int max_texturesize; char * vendorstring; + bool needAlphaTexture; int MaxLights() const { diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 8587b5ac3..d4334251b 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -149,7 +149,17 @@ vec4 getTexel(vec2 st) // // Apply texture modes // - if (texturemode == 2) + if (texturemode == 3) + { + texel *=objectcolor; + texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a); + return texel; + } + else if (texturemode == 4) + { + texel = vec4(1.0, 1.0, 1.0, texel.r); + } + else if (texturemode == 2) { texel.a = 1.0; } diff --git a/wadsrc/static/shaders/glsl/main_colormap.fp b/wadsrc/static/shaders/glsl/main_colormap.fp index d4c079cdd..d78a21f5f 100644 --- a/wadsrc/static/shaders/glsl/main_colormap.fp +++ b/wadsrc/static/shaders/glsl/main_colormap.fp @@ -20,7 +20,17 @@ vec4 getTexel(vec2 st) // // Apply texture modes // - if (texturemode == 2) + if (texturemode == 3) + { + texel *=objectcolor; + texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a); + return texel; + } + else if (texturemode == 4) + { + texel = vec4(1.0, 1.0, 1.0, texel.r); + } + else if (texturemode == 2) { texel.a = 1.0; } From 887d35d559820d9ffac14f17e09b9c1557a2c09f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 19:44:19 +0200 Subject: [PATCH 010/138] - remove colormap from texture generation parameters. The one remaining special case, alpha texture on old hardware is now handled by the currently set texture mode at the time of use. - use the cleaned up decal lighting code from the first GLEW branch. --- src/gl/renderer/gl_lightdata.cpp | 1 + src/gl/renderer/gl_renderer.cpp | 2 +- src/gl/renderer/gl_renderstate.h | 2 + src/gl/scene/gl_decal.cpp | 100 +++++------------------ src/gl/scene/gl_skydome.cpp | 2 - src/gl/system/gl_interface.cpp | 2 - src/gl/system/gl_interface.h | 5 ++ src/gl/system/gl_wipe.cpp | 22 ++--- src/gl/textures/gl_bitmap.cpp | 133 ++++--------------------------- src/gl/textures/gl_bitmap.h | 28 ++++--- src/gl/textures/gl_hwtexture.cpp | 49 ++++-------- src/gl/textures/gl_hwtexture.h | 21 +++-- src/gl/textures/gl_material.cpp | 43 +++++----- src/gl/textures/gl_material.h | 16 ++-- 14 files changed, 134 insertions(+), 292 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 102d1d43e..7d69ababd 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -170,6 +170,7 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend } else if (style.Flags & STYLEF_InvertSource) { + // The only place where InvertSource is used is for inverted sprites with the infrared powerup. texturemode = TM_INVERSE; } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 5120c00ea..d7d2466f0 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -246,7 +246,7 @@ unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h) FMaterial * gltex = FMaterial::ValidateTexture(tex); if (gltex) { - return gltex->CreateTexBuffer(CM_DEFAULT, 0, w, h); + return gltex->CreateTexBuffer(0, w, h); } return NULL; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index e037fb637..cd37705af 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -2,6 +2,7 @@ #define __GL_RENDERSTATE_H #include +#include "gl/system/gl_interface.h" #include "c_cvars.h" #include "r_defs.h" @@ -177,6 +178,7 @@ public: void SetTextureMode(int mode) { mTextureMode = mode; + gl.checkTextureMode(mode); } void EnableTexture(bool on) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 959641076..7c2dda05f 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -74,7 +74,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) int light; int rel; float a; - bool flipx, flipy, loadAlpha; + bool flipx, flipy; DecalVertex dv[4]; FTextureID decalTile; @@ -179,9 +179,6 @@ 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) @@ -190,58 +187,6 @@ void GLWall::DrawDecal(DBaseDecal *decal) p.LightColor = PalEntry(p.colormap, v, v, v); } - 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); @@ -299,8 +244,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 +302,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,6 +329,8 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_SetRenderStyle(decal->RenderStyle, false, false); + tex->BindPatch(p.colormap, decal->Translation); + // 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); @@ -407,6 +345,8 @@ void GLWall::DrawDecal(DBaseDecal *decal) } glEnd(); rendered_decals++; + gl_RenderState.SetTextureMode(TM_MODULATE); + gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetFog(fc,-1); gl_RenderState.SetDynLight(0,0,0); } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 7dbf5e573..b5f3b1333 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -290,7 +290,6 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float 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; @@ -312,7 +311,6 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float 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; diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 7615373c5..2299ddabb 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -194,7 +194,6 @@ void gl_PrintStartupLog() void gl_SetTextureMode(int type) { - gl.needAlphaTexture = false; if (type == TM_MASK) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -239,7 +238,6 @@ void gl_SetTextureMode(int type) else // if (type == TM_MODULATE) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - gl.needAlphaTexture = (type == TM_REDTOALPHA); } } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 13913f621..8618c246a 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -44,6 +44,11 @@ struct RenderContext { return glslversion >= 1.3f; } + + void checkTextureMode(int mode) + { + if (!hasGLSL()) needAlphaTexture = (mode == TM_REDTOALPHA); + } }; extern RenderContext gl; diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index c41a1fb24..b7751b7ec 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -145,9 +145,9 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) } wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true); - wipestartscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT); + wipestartscreen->CreateTexture(NULL, Width, Height, false, 0); glFinish(); - wipestartscreen->Bind(0, CM_DEFAULT); + wipestartscreen->Bind(0); 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); @@ -168,9 +168,9 @@ 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); + wipeendscreen->CreateTexture(NULL, Width, Height, false, 0); glFlush(); - wipeendscreen->Bind(0, CM_DEFAULT); + wipeendscreen->Bind(0); 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); @@ -280,7 +280,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.EnableAlphaTest(false); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, CM_DEFAULT); + fb->wipestartscreen->Bind(0); glColor4f(1.f, 1.f, 1.f, 1.f); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); @@ -293,7 +293,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) glVertex2i(fb->Width, fb->Height); glEnd(); - fb->wipeendscreen->Bind(0, CM_DEFAULT); + fb->wipeendscreen->Bind(0); glColor4f(1.f, 1.f, 1.f, clamp(Clock/32.f, 0.f, 1.f)); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); @@ -347,7 +347,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) // Draw the new screen on the bottom. gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.Apply(); - fb->wipeendscreen->Bind(0, CM_DEFAULT); + fb->wipeendscreen->Bind(0); glColor4f(1.f, 1.f, 1.f, 1.f); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); @@ -363,7 +363,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) int i, dy; bool done = false; - fb->wipestartscreen->Bind(0, CM_DEFAULT); + fb->wipestartscreen->Bind(0); // Copy the old screen in vertical strips on top of the new one. while (ticks--) { @@ -492,7 +492,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.EnableAlphaTest(false); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, CM_DEFAULT); + fb->wipestartscreen->Bind(0); glColor4f(1.f, 1.f, 1.f, 1.f); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); @@ -523,10 +523,10 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) // Burn the new screen on top of it. glColor4f(1.f, 1.f, 1.f, 1.f); - fb->wipeendscreen->Bind(1, CM_DEFAULT); + fb->wipeendscreen->Bind(1); //BurnTexture->Bind(0, CM_DEFAULT); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0, CM_DEFAULT); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0); 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); diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index d90fd36b7..51e03aa98 100644 --- a/src/gl/textures/gl_bitmap.cpp +++ b/src/gl/textures/gl_bitmap.cpp @@ -50,12 +50,11 @@ // //=========================================================================== 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, bool alphatex, int count, int step) { int i; - int fac; - if (cm == CM_DEFAULT) + if (!alphatex) { for(i=0;i= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size())) - { - for(i=0;i, @@ -147,57 +115,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 @@ -215,7 +137,7 @@ 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 (alphatex) { for(int i=0;i<256;i++) { @@ -225,37 +147,21 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them. } } - else + else if (translation > 0) { - // apply any translation. - // The ice and blood color translations are done directly - // because that yields better results. - switch(translation) + PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); + if (ptrans) { - default: - { - PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); - if (ptrans) + for (i = 0; i < 256; i++) { - for(i = 0; i < 256; i++) - { - penew[i] = (ptrans[i]&0xffffff) | (palette[i]&0xff000000); - } - break; + penew[i] = (ptrans[i] & 0xffffff) | (palette[i] & 0xff000000); } } - - 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); - } } - // Now penew contains the actual palette that is to be used for creating the image. + else + { + memcpy(penew, palette, 256*sizeof(PalEntry)); + } // 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..98addb51d 100644 --- a/src/gl/textures/gl_bitmap.h +++ b/src/gl/textures/gl_bitmap.h @@ -5,24 +5,34 @@ #include "gl/textures/gl_material.h" -void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count); - class FGLBitmap : public FBitmap { - int cm; + bool alphatex; int translation; public: - FGLBitmap() { cm = CM_DEFAULT; translation = 0; } + FGLBitmap() + { + alphatex = false; + 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; - if (_trans != -1337) translation = _trans; + alphatex = false; + translation = 0; + } + void SetTranslationInfo(int _trans) + { + if (_trans == -1) alphatex = true; + else if (_trans != -1337) translation = _trans; + + } + + void SetAlphaTex() + { + alphatex = true; } virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth, diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 648bac770..7aa8b610c 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -277,9 +277,7 @@ FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool w texwidth=_width; texheight=_height; - int cm_arraysize = CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size(); - glTexID = new unsigned[cm_arraysize]; - memset(glTexID,0,sizeof(unsigned int)*cm_arraysize); + glDefTexID = 0; clampmode=0; glDepthID = 0; forcenofiltering = nofilter; @@ -317,21 +315,8 @@ void FHardwareTexture::Clean(bool all) if (all) { - for (int i=0;i= CM_MAXCOLORMAP) cm=CM_DEFAULT; - if (translation==0) { - return &glTexID[cm]; + return &glDefTexID; } // normally there aren't more than very few different // translations here so this isn't performance critical. for(unsigned int i=0;i= CM_MAXCOLORMAP) cm=CM_DEFAULT; - - unsigned int * pTexID=GetTexID(cm, translation); + if (alphatexture) translation = TRANS_Alpha; + unsigned int * pTexID=GetTexID(translation); if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); - LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, cm==CM_SHADE, texunit); + LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, alphatexture, 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..fc962f3ea 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -10,6 +10,17 @@ class FCanvasTexture; class AActor; +// For error catching while changing parameters. +enum EInvalid +{ + Invalid = 0 +}; + +enum ETranslation +{ + TRANS_Alpha = INT_MAX +}; + enum { GLT_CLAMPX=1, @@ -27,7 +38,7 @@ class FHardwareTexture { unsigned int glTexID; int translation; - int cm; + //int cm; }; public: @@ -48,12 +59,12 @@ private: bool forcenofiltering; bool forcenocompression; - unsigned int * glTexID; + unsigned glDefTexID; TArray glTexID_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); + unsigned * GetTexID(int translation); int GetDepthBuffer(); void DeleteTexture(unsigned int texid); @@ -68,8 +79,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); + unsigned int Bind(int texunit, int translation=0, bool alphatexture = false); + unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int translation=0, bool alphatexture = false); void Resize(int _width, int _height) ; void Clean(bool all); diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 5d471fc81..8253c3262 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -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, bool alphatexture) { if (HiresLump==-1) { @@ -131,7 +131,7 @@ 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); + if (alphatexture) bmp.SetAlphaTex(); int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); @@ -271,7 +271,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, bool expand, FTexture *hirescheck, int warp, bool alphatexture) { unsigned char * buffer; int W, H; @@ -281,7 +281,7 @@ 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, alphatexture); if (buffer) { return buffer; @@ -296,7 +296,8 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in memset(buffer, 0, W * (H+1) * 4); FGLBitmap bmp(buffer, W*4, W, H); - bmp.SetTranslationInfo(cm, translation); + bmp.SetTranslationInfo(translation); + if (alphatexture) bmp.SetAlphaTex(); if (tex->bComplex) { @@ -337,7 +338,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in else //if (bIsTransparent != 1) { // [BB] Potentially upsample the buffer. - buffer = gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || cm == CM_SHADE ); + buffer = gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || alphatexture); } currentwarp = warp; currentwarptime = gl_frameMS; @@ -386,7 +387,7 @@ bool FGLTexture::CreatePatch() // //=========================================================================== -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 warp) { int usebright = false; @@ -400,7 +401,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int hwtex = gltexture[clampmode] = gltexture[4]; gltexture[4] = NULL; - if (hwtex->Bind(texunit, cm, translation)) + if (hwtex->Bind(texunit, 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); @@ -428,7 +429,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int } // Bind it to the system. - if (!hwtex->Bind(texunit, cm, translation)) + if (!hwtex->Bind(texunit, translation)) { int w=0, h=0; @@ -438,10 +439,10 @@ 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, false, hirescheck, warp); tex->ProcessData(buffer, w, h, false); } - if (!hwtex->CreateTexture(buffer, w, h, true, texunit, cm, translation)) + if (!hwtex->CreateTexture(buffer, w, h, true, texunit, translation)) { // could not create texture delete[] buffer; @@ -463,7 +464,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int // Binds a sprite to the renderer // //=========================================================================== -const FHardwareTexture * FGLTexture::BindPatch(int texunit, int cm, int translation, int warp) +const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, int warp, bool alphatexture) { bool usebright = false; int transparm = translation; @@ -489,14 +490,14 @@ const FHardwareTexture * FGLTexture::BindPatch(int texunit, int cm, int translat // Bind it to the system. - if (!glpatch->Bind(texunit, cm, translation)) + if (!glpatch->Bind(texunit, translation, alphatexture)) { int w, h; // Create this texture - unsigned char * buffer = CreateTexBuffer(cm, translation, w, h, bExpand, NULL, warp); + unsigned char * buffer = CreateTexBuffer(translation, w, h, bExpand, NULL, warp, alphatexture); tex->ProcessData(buffer, w, h, true); - if (!glpatch->CreateTexture(buffer, w, h, false, texunit, cm, translation)) + if (!glpatch->CreateTexture(buffer, w, h, false, texunit, translation, alphatexture)) { // could not create texture delete[] buffer; @@ -755,7 +756,7 @@ 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) { @@ -847,7 +848,7 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) else if (clampmode != -1) clampmode &= 3; else clampmode = 4; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, cm, clampmode, translation, allowhires? tex:NULL, softwarewarp); + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL, softwarewarp); if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) { for(unsigned i=0;igl_info.SystemTexture->Bind(i+1, CM_DEFAULT, clampmode, 0, NULL, false); + layer->gl_info.SystemTexture->Bind(i+1, clampmode, 0, NULL, false); maxbound = i+1; } } @@ -890,11 +891,11 @@ void FMaterial::BindPatch(int cm, int translation, int overrideshader) int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed); - const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, cm, translation, softwarewarp); + const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, gl.needAlphaTexture); // 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); + mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, 0, 0, false); maxbound = 1; } // unbind everything from the last texture that's still active @@ -1012,7 +1013,7 @@ void FMaterial::BindToFrameBuffer() if (mBaseLayer->gltexture == NULL) { // must create the hardware texture first - mBaseLayer->Bind(0, CM_DEFAULT, 0, 0, NULL, 0); + mBaseLayer->Bind(0, 0, 0, NULL, 0); FHardwareTexture::Unbind(0); } mBaseLayer->gltexture[0]->BindToFrameBuffer(); diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 3754e9337..16f1ed451 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -48,7 +48,7 @@ enum ETexUse }; -class FGLTexture //: protected WorldTextureInfo, protected PatchTextureInfo +class FGLTexture { friend class FMaterial; public: @@ -68,21 +68,21 @@ private: bool bExpand; float AlphaThreshold; - unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, int cm); + unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture); BYTE *WarpBuffer(BYTE *buffer, int Width, int Height, int warp); 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); + const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck, int warp); + const FHardwareTexture *BindPatch(int texunit, int translation, int warp, bool alphatexture); 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, bool expand, FTexture *hirescheck, int warp, bool alphatexture = false); void Clean(bool all); int Dump(int i); @@ -138,9 +138,9 @@ public: 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 + unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand = false, bool allowhires=true) const { - return mBaseLayer->CreateTexBuffer(cm, translation, w, h, expand, allowhires? tex:NULL, 0); + return mBaseLayer->CreateTexBuffer(translation, w, h, expand, allowhires? tex:NULL, 0); } void Clean(bool f) @@ -233,7 +233,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 From 978ace241c43562fb805530a9f8fc271d4b78a21 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 21:47:54 +0200 Subject: [PATCH 011/138] - removed all code that mixes together the different lighting methods. Now everything goes through the 3 different light parameters in the render state. - removed cm parameter from many functions. --- src/gl/dynlights/gl_dynlight1.cpp | 2 +- src/gl/models/gl_models.cpp | 15 +- src/gl/models/gl_models.h | 20 +-- src/gl/models/gl_models_md2.cpp | 8 +- src/gl/models/gl_models_md3.cpp | 8 +- src/gl/models/gl_voxels.cpp | 8 +- src/gl/renderer/gl_colormap.h | 2 +- src/gl/renderer/gl_renderer.cpp | 10 +- src/gl/renderer/gl_renderer.h | 2 +- src/gl/renderer/gl_renderstate.cpp | 45 ++---- src/gl/renderer/gl_renderstate.h | 2 +- src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_drawinfo.cpp | 2 +- src/gl/scene/gl_flats.cpp | 6 +- src/gl/scene/gl_portal.cpp | 28 ++-- src/gl/scene/gl_renderhacks.cpp | 1 - src/gl/scene/gl_scene.cpp | 9 +- src/gl/scene/gl_skydome.cpp | 98 +++--------- src/gl/scene/gl_sprite.cpp | 30 +--- src/gl/scene/gl_spritelight.cpp | 245 ----------------------------- src/gl/scene/gl_wall.h | 17 -- src/gl/scene/gl_walls.cpp | 2 +- src/gl/scene/gl_walls_draw.cpp | 10 +- src/gl/scene/gl_weapon.cpp | 37 +++-- src/gl/system/gl_cvars.h | 8 - src/gl/system/gl_interface.cpp | 8 +- src/gl/system/gl_wipe.cpp | 11 +- src/gl/textures/gl_hwtexture.h | 4 + src/gl/textures/gl_material.cpp | 14 +- src/gl/textures/gl_material.h | 5 +- src/gl/textures/gl_texture.cpp | 2 +- 31 files changed, 154 insertions(+), 507 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 90d65559c..c1bb9dbbf 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -241,7 +241,7 @@ bool gl_SetupLightTexture() if (GLRenderer->gllight == NULL) return false; FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight); - pat->BindPatch(CM_DEFAULT, 0); + pat->BindPatch(0); return true; } diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 4b8a8e44b..1efcefd08 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -626,7 +626,6 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, - int cm, Matrix3x4 *normaltransform, int translation) { @@ -684,14 +683,14 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, if (mdl!=NULL) { if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) - mdl->RenderFrameInterpolated(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, cm, translation); + mdl->RenderFrameInterpolated(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], translation); } } } -void gl_RenderModel(GLSprite * spr, int cm) +void gl_RenderModel(GLSprite * spr) { FSpriteModelFrame * smf = spr->modelframe; @@ -808,11 +807,11 @@ void gl_RenderModel(GLSprite * spr, int cm) 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 ); + gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), &ModelToWorld, &NormalTransform, translation ); } #endif - gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, NULL, translation ); + gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), NULL, translation ); if (!gl.hasGLSL()) { @@ -840,7 +839,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); @@ -883,7 +882,7 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm) glRotatef(smf->pitchoffset, 0, 0, 1); glRotatef(-smf->rolloffset, 1, 0, 0); - 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(); diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 5d474dd8d..ebfb8b8c5 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -27,9 +27,9 @@ 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; + virtual void RenderFrame(FTexture * skin, int frame, 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 RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; virtual void MakeGLData() {} virtual void CleanGLData() {} @@ -138,8 +138,8 @@ public: 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 translation=0); + virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0); }; @@ -228,8 +228,8 @@ public: 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 translation=0); + virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0); }; class FVoxelVertexBuffer; @@ -291,8 +291,8 @@ public: 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 translation=0); + virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0); FTexture *GetPaletteTexture() const { return mPalette; } }; @@ -344,9 +344,9 @@ 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(); diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index 244ec064d..12c8bebe7 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -293,7 +293,7 @@ void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices,FMod } -void FDMDModel::RenderFrame(FTexture * skin, int frameno, int cm, int translation) +void FDMDModel::RenderFrame(FTexture * skin, int frameno, int translation) { int activeLod; @@ -311,7 +311,7 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int cm, int translatio FMaterial * tex = FMaterial::ValidateTexture(skin); - tex->Bind(cm, 0, translation); + tex->Bind(0, translation); int numVerts = info.numVertices; @@ -337,7 +337,7 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int cm, int translatio RenderGLCommands(lods[activeLod].glCommands, numVerts, frame->vertices/*, modelColors, NULL*/); } -void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, int translation) +void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int translation) { int activeLod = 0; @@ -355,7 +355,7 @@ void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int framen FMaterial * tex = FMaterial::ValidateTexture(skin); - tex->Bind(cm, 0, translation); + tex->Bind(0, translation); int numVerts = info.numVertices; diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 12509b769..bd1b4e972 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -232,7 +232,7 @@ void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert) glEnd(); } -void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, int translation) +void FMD3Model::RenderFrame(FTexture * skin, int frameno, int translation) { if (frameno>=numFrames) return; @@ -258,12 +258,12 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, int translatio FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin); - tex->Bind(cm, 0, translation); + tex->Bind(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::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int translation) { if (frameno>=numFrames || frameno2>=numFrames) return; @@ -283,7 +283,7 @@ void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int framen FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin); - tex->Bind(cm, 0, translation); + tex->Bind(0, translation); MD3Vertex* verticesInterpolated = new MD3Vertex[surfaces[i].numVertices]; MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices; diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index 14ed5985c..99b565fc5 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -502,10 +502,10 @@ int FVoxelModel::FindFrame(const char * name) // //=========================================================================== -void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translation) +void FVoxelModel::RenderFrame(FTexture * skin, int frame, int translation) { FMaterial * tex = FMaterial::ValidateTexture(skin); - tex->Bind(cm, 0, translation); + tex->Bind(0, translation); if (mVBO == NULL) MakeGLData(); if (mVBO != NULL) @@ -535,8 +535,8 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translatio // //=========================================================================== -void FVoxelModel::RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation) +void FVoxelModel::RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation) { - RenderFrame(skin, frame, cm, translation); + RenderFrame(skin, frame, translation); } diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 7c9921108..59ccf9961 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -24,7 +24,7 @@ enum EColorManipulation // 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 + CM_FOGLAYER= 0x20000020, // Sprite shaped fog layer }; #define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index d7d2466f0..3e88ebceb 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -333,13 +333,13 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) GLTranslationPalette * pal = static_cast(parms.remap->GetNative()); if (pal) translation = -pal->GetIndex(); } - gltex->BindPatch(CM_DEFAULT, translation); + gltex->BindPatch(translation); } else { // This is an alpha texture gl_RenderState.SetTextureMode(TM_REDTOALPHA); - gltex->BindPatch(CM_SHADE, 0); + gltex->BindPatch(0); } u1 = gltex->GetUL(); @@ -349,7 +349,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) } else { - gltex->Bind(CM_DEFAULT, 0, 0); + gltex->Bind(0, 0); u2=1.f; v2=-1.f; u1 = v1 = 0.f; @@ -519,7 +519,7 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture * if (!gltexture) return; - gltexture->Bind(CM_DEFAULT, 0, 0); + gltexture->Bind(0, 0); // scaling is not used here. if (!local_origin) @@ -613,7 +613,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint PalEntry pe = gl_CalcLightColor(lightlevel, cm.LightColor, cm.blendfactor, true); glColor3ub(pe.r, pe.g, pe.b); - gltexture->Bind(cm.colormap); + gltexture->Bind(); int i; float rot = float(rotation * M_PI / float(1u << 31)); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 8db9cb195..4a4e31c10 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -91,7 +91,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); 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 96b782771..d6cf1804e 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -82,6 +82,7 @@ void FRenderState::Reset() glBlendEquation = -1; m2D = true; mVertexBuffer = mCurrentVertexBuffer = NULL; + mColormapState = CM_DEFAULT; } @@ -91,33 +92,18 @@ void FRenderState::Reset() // //========================================================================== -int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime) +int FRenderState::SetupShader(bool cameratexture, int &shaderindex, float warptime) { int softwarewarp = 0; if (gl.hasGLSL()) { - if (shaderindex == 3) - { - // Brightmap should not be used. - if (!mBrightmapEnabled || cm >= CM_FIRSTSPECIALCOLORMAP) - { - shaderindex = 0; - } - } - - mColormapState = cm; - if (cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK) - { - cm = CM_DEFAULT; - } mEffectState = shaderindex; mWarpTime = warptime; } else { - if (cm != CM_SHADE) cm = CM_DEFAULT; softwarewarp = shaderindex > 0 && shaderindex < 3? shaderindex : 0; shaderindex = 0; } @@ -134,30 +120,21 @@ int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, flo bool FRenderState::ApplyShader() { - bool useshaders = false; - FShader *activeShader = NULL; - if (mSpecialEffect > 0 && gl.hasGLSL()) + if (gl.hasGLSL()) { - activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); - } - else if (gl.hasGLSL()) - { - useshaders = (!m2D || mEffectState != 0 || mColormapState); // all 3D rendering and 2D with texture effects. - if (useshaders) + FShader *activeShader; + if (mSpecialEffect > 0) { - FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); - - if (shd != NULL) - { - activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); - } + activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); } - } + FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); + if (shd != NULL) + { + activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); + } - if (activeShader) - { int fogset = 0; //glColor4fv(mColor.vec); if (mFogEnabled) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index cd37705af..d01cc53cf 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -143,7 +143,7 @@ public: void Reset(); - int SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime); + int SetupShader(bool cameratexture, int &shaderindex, float warptime); void Apply(bool forcenoshader = false); void SetVertexBuffer(FVertexBuffer *vb) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 7c2dda05f..ed54e9e32 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -329,7 +329,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_SetRenderStyle(decal->RenderStyle, false, false); - tex->BindPatch(p.colormap, decal->Translation); + tex->BindPatch(decal->Translation); // If srcalpha is one it looks better with a higher alpha threshold diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 62e604aca..52177cbe2 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -1068,7 +1068,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo int rel = getExtraLight(); gl_SetColor(lightlevel, rel, &Colormap, 1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gltexture->Bind(Colormap.colormap); + gltexture->Bind(); float fviewx = FIXED2FLOAT(viewx); float fviewy = FIXED2FLOAT(viewy); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 4a4c0d715..179c087d1 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -407,7 +407,7 @@ void GLFlat::Draw(int pass) // fall through case GLPASS_TEXTURE: { - gltexture->Bind(Colormap.colormap); + gltexture->Bind(); bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, false); if (pushed) @@ -471,7 +471,7 @@ void GLFlat::Draw(int pass) else { if (foggy) gl_RenderState.EnableBrightmap(false); - gltexture->Bind(Colormap.colormap); + gltexture->Bind(); bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, true); gl_RenderState.EnableBrightmap(true); @@ -515,7 +515,7 @@ inline void GLFlat::PutFlat(bool fog) { { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } } }; - bool light = gl_forcemultipass; + bool light = false; bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack); if (!gl_fixedcolormap) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index ee0d494a4..020a37b4e 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -50,6 +50,7 @@ #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" @@ -187,7 +188,7 @@ bool GLPortal::Start(bool usestencil, bool doquery) 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(); glDepthFunc(GL_LESS); gl_RenderState.Apply(); @@ -345,9 +346,8 @@ 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.ResetColor(); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); @@ -404,7 +404,7 @@ 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 @@ -604,7 +604,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 +634,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; @@ -844,12 +844,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); @@ -962,7 +962,7 @@ 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 @@ -973,7 +973,7 @@ void GLHorizonPortal::DrawContents() } - gltexture->Bind(origin->colormap.colormap); + gltexture->Bind(); gl_RenderState.EnableAlphaTest(false); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index a6452a01f..20d6ac7bc 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 d3758c0a4..0c4439bc6 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -85,7 +85,6 @@ 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) EXTERN_CVAR (Int, screenblocks) EXTERN_CVAR (Bool, cl_capfps) @@ -845,6 +844,7 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) { DrawPlayerSprites (viewsector, false); } + gl_RenderState.SetFixedColormap(CM_DEFAULT); DrawTargeterSprites(); DrawBlend(viewsector); @@ -918,6 +918,7 @@ void FGLRenderer::SetFixedColormap (player_t *player) } } } + gl_RenderState.SetFixedColormap(gl_fixedcolormap); } //----------------------------------------------------------------------------- @@ -1060,6 +1061,7 @@ 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); screen->Begin2D(false); DrawBlend(viewsector); glFlush(); @@ -1235,6 +1237,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in int height = gltex->TextureHeight(GLUSE_TEXTURE); gl_fixedcolormap=CM_DEFAULT; + gl_RenderState.SetFixedColormap(CM_DEFAULT); bool usefb; @@ -1279,7 +1282,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in if (!usefb) { glFlush(); - gltex->Bind(CM_DEFAULT, 0, 0); + gltex->Bind(0, 0); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height); } else @@ -1287,7 +1290,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in GLRenderer->EndOffscreen(); } - gltex->Bind(CM_DEFAULT, 0, 0); + gltex->Bind(0, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); tex->SetUpdated(); } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index b5f3b1333..f56076ef6 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -78,12 +78,10 @@ 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. //----------------------------------------------------------------------------- @@ -111,7 +109,8 @@ static void SkyVertex(int r, int c) if (!foglayer) { - gl_SetColor(255, 0, NULL, r==0? 0.0f : 1.0f); + // this cannot use the renderstate because it's inside a primitive. + glColor4f(1.f, 1.f, 1.f, r==0? 0.0f : 1.0f); // And the texture coordinates. if(!yflip) // Flipped Y is for the lower hemisphere. @@ -165,30 +164,24 @@ static void RenderSkyHemisphere(int hemi, bool mirror) // 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); + gl_RenderState.Apply(); if (!secondlayer) { - glColor3f(R, G ,B); glBegin(GL_TRIANGLE_FAN); for(c = 0; c < columns; c++) { SkyVertex(1, c); } glEnd(); + gl_RenderState.SetObjectColor(0xffffffff); // unset the cap's color } gl_RenderState.EnableTexture(true); @@ -197,7 +190,7 @@ static void RenderSkyHemisphere(int hemi, bool mirror) } else { - gl_RenderState.Apply(true); + gl_RenderState.Apply(); columns=4; // no need to do more! glBegin(GL_TRIANGLE_FAN); for(c = 0; c < columns; c++) @@ -246,7 +239,7 @@ static void RenderSkyHemisphere(int hemi, bool mirror) //----------------------------------------------------------------------------- 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) +static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float y_offset, bool mirror) { int texh = 0; bool texscale = false; @@ -257,7 +250,7 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float if (tex) { glPushMatrix(); - tex->Bind(CM_Index, 0, 0); + tex->Bind(0, 0); texw = tex->TextureWidth(GLUSE_TEXTURE); texh = tex->TextureHeight(GLUSE_TEXTURE); @@ -290,20 +283,7 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float if (tex && !secondlayer) { PalEntry pe = tex->tex->GetSkyCapColor(false); - - 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; - } + gl_RenderState.SetObjectColor(pe); } RenderSkyHemisphere(SKYHEMI_UPPER, mirror); @@ -311,19 +291,7 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float if (tex && !secondlayer) { PalEntry pe = tex->tex->GetSkyCapColor(true); - 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; - } + gl_RenderState.SetObjectColor(pe); } RenderSkyHemisphere(SKYHEMI_LOWER, mirror); @@ -344,7 +312,7 @@ 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; @@ -355,15 +323,13 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C else glRotatef(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y); - glColor3f(R, G ,B); - if (sb->faces[5]) { faces=4; // north tex = FMaterial::ValidateTexture(sb->faces[0]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(0, 0); @@ -378,7 +344,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C // east tex = FMaterial::ValidateTexture(sb->faces[1]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(0, 0); @@ -393,7 +359,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C // south tex = FMaterial::ValidateTexture(sb->faces[2]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(0, 0); @@ -408,7 +374,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C // west tex = FMaterial::ValidateTexture(sb->faces[3]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(0, 0); @@ -426,7 +392,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C faces=1; // all 4 sides tex = FMaterial::ValidateTexture(sb->faces[0]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); @@ -479,7 +445,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C // top tex = FMaterial::ValidateTexture(sb->faces[faces]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); if (!sb->fliptop) @@ -509,7 +475,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C // bottom tex = FMaterial::ValidateTexture(sb->faces[faces+1]); - tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glTexCoord2f(0, 0); @@ -533,7 +499,6 @@ 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. @@ -541,16 +506,12 @@ void GLSkyPortal::DrawContents() if (glset.lightmode == 8) glset.lightmode = 2; - if (gl_fixedcolormap) + if (!gl_fixedcolormap) { - CM_Index=gl_fixedcolormapfadecolor; + FadeColor = origin->fadecolor; } + gl_RenderState.SetColor(0xffffffff); gl_RenderState.EnableFog(false); gl_RenderState.EnableAlphaTest(false); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -561,18 +522,7 @@ void GLSkyPortal::DrawContents() 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); + RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2); gl_RenderState.EnableAlphaTest(true); } else @@ -582,7 +532,7 @@ void GLSkyPortal::DrawContents() 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->skytexno1, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored); gl_RenderState.SetTextureMode(TM_MODULATE); } @@ -592,7 +542,7 @@ void GLSkyPortal::DrawContents() if (origin->doublesky && origin->texture[1]) { secondlayer=true; - RenderDome(FNullTextureID(), origin->texture[1], origin->x_offset[1], origin->y_offset, false, CM_Index); + RenderDome(FNullTextureID(), origin->texture[1], origin->x_offset[1], origin->y_offset, false); secondlayer=false; } @@ -601,7 +551,7 @@ void GLSkyPortal::DrawContents() gl_RenderState.EnableTexture(false); foglayer=true; gl_RenderState.SetColorAlpha(FadeColor, skyfog / 255.0f); - RenderDome(FNullTextureID(), NULL, 0, 0, false, CM_DEFAULT); + RenderDome(FNullTextureID(), NULL, 0, 0, false); gl_RenderState.EnableTexture(true); foglayer=false; } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index d64f62b71..9c8bba2f0 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -179,23 +179,11 @@ 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, 0xffffffff, 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, 0xffffffff); - } - else - { - gl_SetColor(lightlevel, rel, &Colormap, trans); - } - } - else return; + gl_SetColor(lightlevel, rel, &Colormap, trans); } gl_RenderState.SetObjectColor(ThingColor); @@ -207,11 +195,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) @@ -243,7 +226,7 @@ void GLSprite::Draw(int pass) gl_RenderState.SetFog(0, 0); } - if (gltexture) gltexture->BindPatch(Colormap.colormap, translation, OverrideShader); + if (gltexture) gltexture->BindPatch(translation, OverrideShader); else if (!modelframe) gl_RenderState.EnableTexture(false); if (!modelframe) @@ -309,7 +292,7 @@ void GLSprite::Draw(int pass) { // If we get here we know that we have colored fog and no fixed colormap. gl_SetFog(foglevel, rel, &Colormap, additivefog); - gl_RenderState.SetFixedColormap(CM_FOGLAYER); + //gl_RenderState.SetFixedColormap(CM_FOGLAYER); fixme: does not work yet. gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.Apply(); @@ -335,7 +318,7 @@ void GLSprite::Draw(int pass) } else { - gl_RenderModel(this, Colormap.colormap); + gl_RenderModel(this); } if (pass==GLPASS_TRANSLUCENT) @@ -361,6 +344,7 @@ void GLSprite::Draw(int pass) Colormap.FadeColor = backupfade; gl_RenderState.EnableTexture(true); + gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetDynLight(0,0,0); } diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index 66a2b6c7f..e4e2e855a 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -127,248 +127,3 @@ void gl_SetDynSpriteLight(AActor *thing, particle_t *particle) gl_SetDynSpriteLight(NULL, particle->x, particle->y, particle->z, particle->subsector); } } - -//========================================================================== -// -// Gets the light for a sprite - takes dynamic lights into account -// -//========================================================================== - -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) -{ - ADynamicLight *light; - float frac, lr, lg, lb; - float radius; - bool changed = false; - - out[0]=out[1]=out[2]=0; - - for(int j=0;j<2;j++) - { - // Go through both light lists - FLightNode * node = subsec->lighthead[j]; - while (node) - { - light=node->lightsource; - if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer()) - { - 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) - { - frac = 1.0f - (dist / radius); - - if (frac > 0) - { - 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; - } - } - } - } - 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; -} - - - -//========================================================================== -// -// 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) -{ - 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) - { - 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; - } - else - { - // 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); - } - } -} - -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, weapon); - } - } - gl_RenderState.AlphaFunc(GL_GEQUAL,alpha*gl_mask_sprite_threshold); - return lightlevel; -} - diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index ba050c1b6..a9d0c1087 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -354,21 +354,4 @@ inline float Dist2(float x1,float y1,float x2,float y2) 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); - -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); - - - - #endif diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 2d14e0949..e8c23ad81 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -152,7 +152,7 @@ void GLWall::PutWall(bool translucent) }; bool masked; - bool light = gl_forcemultipass; + bool light = false; if (!gl_fixedcolormap) { diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index b4af1e28d..38adfeeab 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -412,7 +412,7 @@ void GLWall::RenderMirrorSurface() gl_SetFog(lightlevel, getExtraLight(), &Colormap, true); FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture); - pat->BindPatch(Colormap.colormap, 0); + pat->BindPatch(0); flags &= ~GLWF_GLOW; //flags |= GLWF_NOSHADER; @@ -465,7 +465,7 @@ void GLWall::RenderTranslucentWall() { if (flags&GLWF_FOGGY) gl_RenderState.EnableBrightmap(false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(Colormap.colormap, flags, 0); + gltexture->Bind(flags, 0); extra = getExtraLight(); } else @@ -532,7 +532,7 @@ void GLWall::Draw(int pass) else gl_SetFog(255, 0, NULL, false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(Colormap.colormap, flags, 0); + gltexture->Bind(flags, 0); RenderWall(3, NULL); gl_RenderState.EnableGlow(false); gl_RenderState.EnableLight(false); @@ -552,7 +552,7 @@ void GLWall::Draw(int pass) if (pass != GLPASS_BASE) { - gltexture->Bind(Colormap.colormap, flags, 0); + gltexture->Bind(flags, 0); } RenderWall(pass == GLPASS_BASE? 2:3, NULL); gl_RenderState.EnableGlow(false); @@ -560,7 +560,7 @@ void GLWall::Draw(int pass) break; case GLPASS_TEXTURE: // modulated texture - gltexture->Bind(Colormap.colormap, flags, 0); + gltexture->Bind(flags, 0); RenderWall(1, NULL); break; diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index c9f8434c4..d582b7165 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -69,7 +69,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) { float fU1,fV1; float fU2,fV2; @@ -83,7 +83,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; } @@ -95,7 +95,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed FMaterial * tex = FMaterial::ValidateTexture(lump, false); if (!tex) return; - tex->BindPatch(cm_index, 0, OverrideShader); + tex->BindPatch(0, OverrideShader); int vw = viewwidth; int vh = viewheight; @@ -192,17 +192,13 @@ 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; @@ -215,7 +211,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) } statebright[i] = !!psp->state->GetFullbright() && !disablefullbright; } - + } } if (gl_fixedcolormap) @@ -300,8 +296,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) vis.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap && cm.colormap == 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; } } @@ -380,10 +376,17 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) 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);// 0x55333333, 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); } } gl_RenderState.SetObjectColor(0xffffffff); @@ -417,5 +420,5 @@ void FGLRenderer::DrawTargeterSprites() // 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); } \ No newline at end of file diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index f748f9b52..79321f5b5 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); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 2299ddabb..5f35c4ec2 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -179,10 +179,10 @@ void gl_PrintStartupLog() Printf ("Max. vertex uniforms: %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); } diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index b7751b7ec..28cfa0e6d 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -279,9 +279,9 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.EnableAlphaTest(false); + gl_RenderState.ResetColor(); gl_RenderState.Apply(); fb->wipestartscreen->Bind(0); - glColor4f(1.f, 1.f, 1.f, 1.f); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); glVertex2i(0, 0); @@ -294,7 +294,8 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) glEnd(); fb->wipeendscreen->Bind(0); - glColor4f(1.f, 1.f, 1.f, clamp(Clock/32.f, 0.f, 1.f)); + gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f)); + gl_RenderState.Apply(); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); glVertex2i(0, 0); @@ -346,9 +347,9 @@ 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); - glColor4f(1.f, 1.f, 1.f, 1.f); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); glVertex2i(0, 0); @@ -398,7 +399,6 @@ 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); @@ -491,9 +491,9 @@ 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.ResetColor(); gl_RenderState.Apply(); fb->wipestartscreen->Bind(0); - glColor4f(1.f, 1.f, 1.f, 1.f); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0, vb); glVertex2i(0, 0); @@ -522,7 +522,6 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) glActiveTexture(GL_TEXTURE0); // Burn the new screen on top of it. - glColor4f(1.f, 1.f, 1.f, 1.f); fb->wipeendscreen->Bind(1); //BurnTexture->Bind(0, CM_DEFAULT); diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index fc962f3ea..4e13bc841 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 diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 8253c3262..9faf996be 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -835,14 +835,14 @@ outl: // //=========================================================================== -void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) +void FMaterial::Bind(int clampmode, int translation, int overrideshader) { int usebright = false; int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT; - int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed); + int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, tex->gl_info.shaderspeed); if (tex->bHasCanvas || tex->bWarped) clampmode = 0; else if (clampmode != -1) clampmode &= 3; @@ -883,13 +883,13 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader) // //=========================================================================== -void FMaterial::BindPatch(int cm, int translation, int overrideshader) +void FMaterial::BindPatch(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); + int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, tex->gl_info.shaderspeed); const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, gl.needAlphaTexture); // The only multitexture effect usable on sprites is the brightmap. @@ -916,7 +916,7 @@ void FMaterial::Precache() { if (tex->UseType==FTexture::TEX_Sprite) { - BindPatch(CM_DEFAULT, 0); + BindPatch(0); } else { @@ -925,10 +925,10 @@ void FMaterial::Precache() { if (mBaseLayer->gltexture[i] != 0) { - Bind (CM_DEFAULT, i, 0); + Bind (i, 0); cached++; } - if (cached == 0) Bind(CM_DEFAULT, -1, 0); + if (cached == 0) Bind(-1, 0); } } } diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 16f1ed451..f01e39cd3 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -120,7 +120,6 @@ class FMaterial float SpriteU[2], SpriteV[2]; float spriteright, spritebottom; - void SetupShader(int shaderindex, int &cm); FGLTexture * ValidateSysTexture(FTexture * tex, bool expand); bool TrimBorders(int *rect); @@ -135,8 +134,8 @@ 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); + void Bind(int clamp = 0, int translation = 0, int overrideshader = 0); + void BindPatch(int translation = 0, int overrideshader = 0); unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand = false, bool allowhires=true) const { diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index 68c33f125..70f5f05be 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -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); } From c47c7421a36f4594f1637367607ba09666c44b35 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 22:57:42 +0200 Subject: [PATCH 012/138] - route all glColor calls through render state. - add sector links to dynamic lights. --- src/gl/data/gl_data.h | 4 ++- src/gl/dynlights/a_dynlight.cpp | 46 ++++++++++++++++++++----- src/gl/dynlights/gl_dynlight.h | 4 ++- src/gl/dynlights/gl_dynlight1.cpp | 40 +++++++++++++++++++--- src/gl/renderer/gl_colormap.h | 24 ++++++------- src/gl/renderer/gl_lightdata.cpp | 50 +-------------------------- src/gl/renderer/gl_lightdata.h | 11 ------ src/gl/renderer/gl_renderer.cpp | 57 +++++++++++++------------------ src/gl/scene/gl_decal.cpp | 3 +- src/gl/scene/gl_drawinfo.cpp | 6 ++-- src/gl/scene/gl_flats.cpp | 7 ++-- src/gl/scene/gl_scene.cpp | 14 ++++---- src/gl/scene/gl_skydome.cpp | 6 ++-- src/gl/scene/gl_sprite.cpp | 30 +++++----------- src/gl/scene/gl_walls.cpp | 12 +++---- src/gl/scene/gl_walls_draw.cpp | 10 +++--- src/gl/scene/gl_weapon.cpp | 8 ++--- src/gl/shaders/gl_shader.cpp | 2 ++ src/r_defs.h | 1 + 19 files changed, 160 insertions(+), 175 deletions(-) diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 6a71dd1ac..6a1589cde 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); @@ -58,4 +58,6 @@ extern TArray currentmapsection; void gl_InitPortals(); void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); +extern long gl_frameMS; + #endif diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index bc12288cd..6ac50a785 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -526,6 +526,11 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius) subSec->validcount = ::validcount; touching_subsectors = AddLightNode(&subSec->lighthead[additive], subSec, this, touching_subsectors); + if (subSec->sector->validcount != ::validcount) + { + touching_sector = AddLightNode(&subSec->sector->lighthead[additive], subSec->sector, this, touching_sector); + subSec->sector->validcount = ::validcount; + } for (unsigned int i = 0; i < subSec->numlines; i++) { @@ -537,8 +542,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[additive], seg->sidedef, this, touching_sides); } } @@ -581,15 +585,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 +628,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 +691,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 +701,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 +728,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) diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index dbf89324b..37cbc4f93 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); @@ -183,8 +184,9 @@ struct FDynLightData bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data); -bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, bool checkside=true, bool forceadditive=true); +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(); +void gl_UploadLights(FDynLightData &data); #endif diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index c1bb9dbbf..f13f24ab6 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -159,15 +159,13 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadd } - - //========================================================================== // // 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, bool checkside, bool forceadditive) + float & scale, int desaturation, bool checkside, bool forceadditive) { Vector fn, pos; @@ -225,11 +223,45 @@ bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & u { gl_RenderState.BlendEquation(GL_FUNC_ADD); } - glColor3f(r,g,b); + gl_RenderState.SetColor(r, g, b, 1.f, desaturation); return true; } +//========================================================================== +// +// +// +//========================================================================== + +#if 0 +void gl_UploadLights(FDynLightData &data) +{ + ParameterBufferElement *pptr; + int size0 = data.arrays[0].Size()/4; + int size1 = data.arrays[1].Size()/4; + int size2 = data.arrays[2].Size()/4; + + if (size0 + size1 + size2 > 0) + { + int sizetotal = size0 + size1 + size2 + 1; + int index = GLRenderer->mParmBuffer->Reserve(sizetotal, &pptr); + + float parmcnt[] = { index + 1, index + 1 + size0, index + 1 + size0 + size1, index + 1 + size0 + size1 + size2 }; + + memcpy(&pptr[0], parmcnt, 4 * sizeof(float)); + memcpy(&pptr[1], &data.arrays[0][0], 4 * size0*sizeof(float)); + memcpy(&pptr[1 + size0], &data.arrays[1][0], 4 * size1*sizeof(float)); + memcpy(&pptr[1 + size0 + size1], &data.arrays[2][0], 4 * size2*sizeof(float)); + gl_RenderState.SetDynLightIndex(index); + } + else + { + gl_RenderState.SetDynLightIndex(-1); + } +} +#endif + //========================================================================== // // diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 59ccf9961..7d2bdb7ee 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -13,9 +13,6 @@ 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 @@ -34,14 +31,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 +46,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 +62,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 7d69ababd..c5bf4c1c8 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.hasGLSL(); -} - -bool gl_GlowActive() -{ - return gl.hasGLSL(); -} - //========================================================================== // // Sets up the fog tables @@ -337,7 +321,7 @@ void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, boo gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon); - gl_RenderState.SetColor(r, g, b, alpha); + gl_RenderState.SetColor(r, g, b, alpha, cm->desaturation); if (glset.lightmode == 8) { if (gl_fixedcolormap) @@ -518,15 +502,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) { @@ -606,9 +584,6 @@ 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); @@ -619,29 +594,6 @@ void gl_SetFog(int lightlevel, int rellight, const FColormap *cmap, bool isaddit } } -//========================================================================== -// -// 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 8eb70bbb9..b968bfe7a 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); @@ -46,14 +43,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 3e88ebceb..b94995cc7 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -273,10 +273,10 @@ void FGLRenderer::ClearBorders() 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.SetColor(0.f ,0.f ,0.f ,1.f); gl_RenderState.Set2DMode(true); gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(true); + gl_RenderState.Apply(); glBegin(GL_QUADS); // upper quad @@ -311,36 +311,35 @@ 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); 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(translation); } else { // This is an alpha texture gl_RenderState.SetTextureMode(TM_REDTOALPHA); - gltex->BindPatch(0); } + gltex->BindPatch(translation); u1 = gltex->GetUL(); v1 = gltex->GetVT(); @@ -373,17 +372,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; @@ -398,8 +397,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) gl_RenderState.SetTextureMode(TM_OPAQUE); } - glColor4f(r, g, b, FIXED2FLOAT(parms.alpha)); - + gl_RenderState.SetColor(color); gl_RenderState.EnableAlphaTest(false); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_STRIP); @@ -418,8 +416,9 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) 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); @@ -450,8 +449,8 @@ 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); + gl_RenderState.SetColorAlpha(p, 1.f); + gl_RenderState.Apply(); glBegin(GL_LINES); glVertex2i(x1, y1); glVertex2i(x2, y2); @@ -468,8 +467,8 @@ 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); + gl_RenderState.SetColorAlpha(p, 1.f); + gl_RenderState.Apply(); glBegin(GL_POINTS); glVertex2i(x1, y1); glEnd(); @@ -484,19 +483,13 @@ 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; + gl_RenderState.SetColorAlpha(color, damount); + gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); - glColor4f(r, g, b, damount); glVertex2i(x1, y1); glVertex2i(x1, y1 + h); glVertex2i(x1 + w, y1 + h); @@ -536,9 +529,9 @@ 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); @@ -609,9 +602,7 @@ 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(); diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index ed54e9e32..bc878ec0d 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -183,8 +183,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) 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(); } diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 52177cbe2..4db9602dc 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -985,7 +985,7 @@ 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); @@ -1013,7 +1013,7 @@ 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); @@ -1051,7 +1051,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo if (gl_fixedcolormap) { - Colormap.GetFixedColormap(); + Colormap.Clear(); lightlevel=255; } else diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 179c087d1..b5a5fc5c6 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -143,12 +143,13 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) } p.Set(plane.plane); - if (!gl_SetupLight(p, light, nearPt, up, right, scale, false, foggy)) + if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.desaturation, false, foggy)) { node=node->nextLight; continue; } draw_dlightf++; + gl_RenderState.Apply(); // Render the light glBegin(GL_TRIANGLE_FAN); @@ -501,7 +502,7 @@ inline void GLFlat::PutFlat(bool fog) if (gl_fixedcolormap) { - Colormap.GetFixedColormap(); + Colormap.Clear(); } if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog) { @@ -533,7 +534,7 @@ inline void GLFlat::PutFlat(bool fog) else foggy = false; list = list_indices[light][masked][foggy]; - if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap && gl_BrightmapsActive()) list = GLDL_LIGHTBRIGHT; + if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap && gl.hasGLSL()) list = GLDL_LIGHTBRIGHT; gl_drawinfo->drawlists[list].AddFlat (this); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 0c4439bc6..4b47abb1f 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -474,7 +474,7 @@ void FGLRenderer::RenderScene(int recursion) } // third pass: modulated texture - glColor3f(1.0f, 1.0f, 1.0f); + gl_RenderState.ResetColor(); gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); gl_RenderState.EnableFog(false); glDepthFunc(GL_LEQUAL); @@ -619,7 +619,7 @@ static void FillScreen() { gl_RenderState.EnableAlphaTest(false); gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(true); + gl_RenderState.Apply(); glBegin(GL_TRIANGLE_STRIP); glVertex2f(0.0f, 0.0f); glVertex2f(0.0f, (float)SCREENHEIGHT); @@ -715,7 +715,7 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) if (extra_red || extra_green || extra_blue) { gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - glColor4f(extra_red, extra_green, extra_blue, 1.0f); + gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f); FillScreen(); } } @@ -773,14 +773,14 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) if (inverse) { gl_RenderState.BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - glColor4f(1.f, 1.f, 1.f, 1.f); + gl_RenderState.ResetColor(); FillScreen(); } if (r < WHITE_THRESH || g < WHITE_THRESH || b < WHITE_THRESH) { gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - glColor4f(r, g, b, 1.0f); + gl_RenderState.SetColor(r, g, b, 1.0f); FillScreen(); } } @@ -806,7 +806,7 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) if (blend[3]>0.0f) { gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4fv(blend); + gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]); FillScreen(); } } @@ -850,7 +850,7 @@ void FGLRenderer::EndDrawScene(sector_t * 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); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index f56076ef6..5492a1649 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -109,7 +109,7 @@ static void SkyVertex(int r, int c) if (!foglayer) { - // this cannot use the renderstate because it's inside a primitive. + // this must not use the renderstate because it's inside a primitive. glColor4f(1.f, 1.f, 1.f, r==0? 0.0f : 1.0f); // And the texture coordinates. @@ -244,7 +244,7 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float int texh = 0; bool texscale = false; - // 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) @@ -511,7 +511,7 @@ void GLSkyPortal::DrawContents() FadeColor = origin->fadecolor; } - gl_RenderState.SetColor(0xffffffff); + gl_RenderState.ResetColor(); gl_RenderState.EnableFog(false); gl_RenderState.EnableAlphaTest(false); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 9c8bba2f0..325fe9082 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -112,10 +112,6 @@ void GLSprite::Draw(int pass) { if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) 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,16 +122,15 @@ 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) @@ -169,7 +164,7 @@ void GLSprite::Draw(int pass) } gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold); - gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha); + gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, Colormap.desaturation); additivefog = true; } else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One) @@ -339,12 +334,8 @@ void GLSprite::Draw(int pass) } } - // End of gl_sprite_brightfog hack: restore FadeColor to normalcy - if (backupfade != Colormap.FadeColor.d) - Colormap.FadeColor = backupfade; - - gl_RenderState.EnableTexture(true); gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.EnableTexture(true); gl_RenderState.SetDynLight(0,0,0); } @@ -696,7 +687,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) && (!gl.hasGLSL() || !gltexture || !gltexture->tex->gl_info.bBrightmapDisablesFullbright)); lightlevel=fullbright? 255 : gl_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ? @@ -717,7 +708,7 @@ 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) { @@ -750,10 +741,7 @@ 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(); } } @@ -894,7 +882,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s if (gl_fixedcolormap) { - Colormap.GetFixedColormap(); + Colormap.Clear(); } else if (!particle->bright) { diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index e8c23ad81..2d6b78fd5 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -71,7 +71,7 @@ void GLWall::CheckGlowing() { bottomglowcolor[3] = topglowcolor[3] = 0; - if (!gl_isFullbright(Colormap.LightColor, lightlevel) && gl_GlowActive()) + if (!gl_isFullbright(Colormap.LightColor, lightlevel) && gl.hasGLSL()) { FTexture *tex = TexMan[topflat]; if (tex != NULL && tex->isGlowing()) @@ -133,7 +133,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(); @@ -184,7 +184,7 @@ void GLWall::PutWall(bool translucent) list = list_indices[light][masked][!!(flags&GLWF_FOGGY)]; if (list == GLDL_LIGHT) { - if (gltexture->tex->gl_info.Brightmap && gl_BrightmapsActive()) list = GLDL_LIGHTBRIGHT; + if (gltexture->tex->gl_info.Brightmap && gl.hasGLSL()) list = GLDL_LIGHTBRIGHT; if (flags & GLWF_GLOW) list = GLDL_LIGHTBRIGHT; } gl_drawinfo->drawlists[list].AddWall(this); @@ -525,7 +525,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); } @@ -554,8 +554,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); } } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 38adfeeab..937549195 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -81,7 +81,7 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light) return false; } - if (!gl_SetupLight(p, light, nearPt, up, right, scale, true, !!(flags&GLWF_FOGGY))) + if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.desaturation, true, !!(flags&GLWF_FOGGY))) { return false; } @@ -267,7 +267,7 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs); - // color for right side + // color for right side (do not set in render state!) if (color2) glColor4fv(color2); // upper right corner @@ -365,15 +365,13 @@ void GLWall::RenderFogBoundary() 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); - gl_RenderState.SetColor(-1, 0, 0, 0); // we do not want the render state to control the color. + gl_RenderState.SetColor(fc[0], fc[1], fc[2], fogd1, Colormap.desaturation); if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); // Korshun. flags &= ~GLWF_GLOW; @@ -406,10 +404,10 @@ void GLWall::RenderMirrorSurface() gl_RenderState.SetEffect(EFF_SPHEREMAP); 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(0); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index d582b7165..57d05931f 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -203,7 +203,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { bool disablefullbright = false; FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL); - if (lump.isValid() && gl_BrightmapsActive()) + if (lump.isValid() && gl.hasGLSL()) { FMaterial * tex=FMaterial::ValidateTexture(lump, false); if (tex) @@ -217,7 +217,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) if (gl_fixedcolormap) { lightlevel=255; - cm.GetFixedColormap(); + cm.Clear(); statebright[0] = statebright[1] = true; fakesec = viewsector; } @@ -294,7 +294,7 @@ 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) { // this only happens for Strife's inverted weapon sprite vis.RenderStyle.Flags |= STYLEF_InvertSource; @@ -379,7 +379,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // set the lighting parameters if (vis.RenderStyle.BlendOp == STYLEOP_Shadow) { - gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f);// 0x55333333, cmc.desaturation); + gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, cmc.desaturation); } else { diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 8f993b857..768d3ad53 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -393,6 +393,7 @@ FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights) glUniform3fv(sh->colormaprange_index, 1, m); } } + /* else { bool desat = cm>=CM_DESAT1 && cm<=CM_DESAT31; @@ -407,6 +408,7 @@ FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights) } } } + */ return sh; } diff --git a/src/r_defs.h b/src/r_defs.h index bb2401684..80f908e81 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -771,6 +771,7 @@ struct sector_t int subsectorcount; // list of subsectors subsector_t ** subsectors; FPortal * portals[2]; // floor and ceiling portals + FLightNode * lighthead[2]; enum { From 506798f134c857557e5cd15b093a2976490ba3b2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 23:12:28 +0200 Subject: [PATCH 013/138] allow brightmaps and fullbright objects in fog. The reasons why they were disabled no longer exist. --- src/gl/scene/gl_flats.cpp | 2 -- src/gl/scene/gl_scene.cpp | 3 --- src/gl/scene/gl_walls_draw.cpp | 2 -- src/gl/shaders/gl_shader.cpp | 6 ++---- 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index b5a5fc5c6..383ee1574 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -471,11 +471,9 @@ void GLFlat::Draw(int pass) } else { - if (foggy) gl_RenderState.EnableBrightmap(false); gltexture->Bind(); bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, true); - gl_RenderState.EnableBrightmap(true); if (pushed) { glPopMatrix(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 4b47abb1f..d32432a28 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -405,7 +405,6 @@ void FGLRenderer::RenderScene(int recursion) 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(); @@ -422,10 +421,8 @@ void FGLRenderer::RenderScene(int recursion) } 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(); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 937549195..d3574ebe9 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -461,7 +461,6 @@ void GLWall::RenderTranslucentWall() int extra; if (gltexture) { - if (flags&GLWF_FOGGY) gl_RenderState.EnableBrightmap(false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); gltexture->Bind(flags, 0); extra = getExtraLight(); @@ -486,7 +485,6 @@ void GLWall::RenderTranslucentWall() { gl_RenderState.EnableTexture(true); } - gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableGlow(false); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 768d3ad53..a132e65dd 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -393,10 +393,9 @@ FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights) glUniform3fv(sh->colormaprange_index, 1, m); } } - /* else { - bool desat = cm>=CM_DESAT1 && cm<=CM_DESAT31; + bool desat = false;// 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 ) @@ -404,11 +403,10 @@ FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights) sh->Bind(Speed); if (desat) { - glUniform1f(sh->desaturation_index, 1.f-float(cm-CM_DESAT0)/(CM_DESAT31-CM_DESAT0)); + //glUniform1f(sh->desaturation_index, 1.f-float(cm-CM_DESAT0)/(CM_DESAT31-CM_DESAT0)); } } } - */ return sh; } From b9a6fe80a466fd39afa063a5f245d944919d8ef8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 May 2014 23:56:53 +0200 Subject: [PATCH 014/138] Do not use the shader to handle STYLEF_RedIsAlpha. Turns out that the name doesn't accurately describe what it does. It is correct for images that come with their own palette or are true color. But for images using the game palette it doesn't use the red channel to determine translucency but the palette index! Ugh... This means it cannot be done with a simple operation in the shader because it won't get a proper source image. The only solution is to create a separate texture. --- src/gl/renderer/gl_lightdata.cpp | 6 +----- src/gl/renderer/gl_renderer.cpp | 15 +++------------ src/gl/renderer/gl_renderer.h | 2 +- src/gl/renderer/gl_renderstate.h | 1 - src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_weapon.cpp | 8 ++++---- src/gl/system/gl_interface.h | 9 --------- src/gl/textures/gl_material.cpp | 4 ++-- src/gl/textures/gl_material.h | 2 +- wadsrc/static/shaders/glsl/main.fp | 4 ---- wadsrc/static/shaders/glsl/main_colormap.fp | 4 ---- 12 files changed, 14 insertions(+), 45 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index c5bf4c1c8..60bc1bd67 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -144,11 +144,7 @@ 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_RedIsAlpha) - { - texturemode = TM_REDTOALPHA; - } - else if (style.Flags & STYLEF_ColorIsFixed) + if (style.Flags & STYLEF_ColorIsFixed) { texturemode = TM_MASK; } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index b94995cc7..f6420ce28 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -334,17 +334,14 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) if (pal) translation = -pal->GetIndex(); } } - else - { - // This is an alpha texture - gl_RenderState.SetTextureMode(TM_REDTOALPHA); - } - gltex->BindPatch(translation); + gl_SetRenderStyle(parms.style, !parms.masked, false); + gltex->BindPatch(translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha)); u1 = gltex->GetUL(); v1 = gltex->GetVT(); u2 = gltex->GetUR(); v2 = gltex->GetVB(); + } else { @@ -391,12 +388,6 @@ 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); - } - gl_RenderState.SetColor(color); gl_RenderState.EnableAlphaTest(false); gl_RenderState.Apply(); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 4a4e31c10..fde918d16 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -91,7 +91,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, 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.h b/src/gl/renderer/gl_renderstate.h index d01cc53cf..ab58c9509 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -178,7 +178,6 @@ public: void SetTextureMode(int mode) { mTextureMode = mode; - gl.checkTextureMode(mode); } void EnableTexture(bool on) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index bc878ec0d..5e490b8a7 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -328,7 +328,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_SetRenderStyle(decal->RenderStyle, false, false); - tex->BindPatch(decal->Translation); + tex->BindPatch(decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha)); // If srcalpha is one it looks better with a higher alpha threshold diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 325fe9082..c051e94ee 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -221,7 +221,7 @@ void GLSprite::Draw(int pass) gl_RenderState.SetFog(0, 0); } - if (gltexture) gltexture->BindPatch(translation, OverrideShader); + if (gltexture) gltexture->BindPatch(translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); else if (!modelframe) gl_RenderState.EnableTexture(false); if (!modelframe) diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 57d05931f..1b0c99053 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -69,7 +69,7 @@ EXTERN_CVAR(Int, gl_fuzztype) // //========================================================================== -void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, 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; @@ -95,7 +95,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed FMaterial * tex = FMaterial::ValidateTexture(lump, false); if (!tex) return; - tex->BindPatch(0, OverrideShader); + tex->BindPatch(0, OverrideShader, alphatexture); int vw = viewwidth; int vh = viewheight; @@ -386,7 +386,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) 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); + DrawPSprite(player, psp, psp->sx + ofsx, psp->sy + ofsy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha)); } } gl_RenderState.SetObjectColor(0xffffffff); @@ -420,5 +420,5 @@ void FGLRenderer::DrawTargeterSprites() // 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, 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/system/gl_interface.h b/src/gl/system/gl_interface.h index 8618c246a..45e0a09ac 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -20,9 +20,6 @@ enum TexMode TM_MASK = 1, // (1, 1, 1, a) TM_OPAQUE = 2, // (r, g, b, 1) TM_INVERSE = 3, // (1-r, 1-g, 1-b, a) - TM_REDTOALPHA = 4, // (1, 1, 1, r) - - // 4 cannot be done natively without shaders and requires special textures. }; struct RenderContext @@ -33,7 +30,6 @@ struct RenderContext float glslversion; int max_texturesize; char * vendorstring; - bool needAlphaTexture; int MaxLights() const { @@ -44,11 +40,6 @@ struct RenderContext { return glslversion >= 1.3f; } - - void checkTextureMode(int mode) - { - if (!hasGLSL()) needAlphaTexture = (mode == TM_REDTOALPHA); - } }; extern RenderContext gl; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 9faf996be..ce3c75181 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -883,7 +883,7 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader) // //=========================================================================== -void FMaterial::BindPatch(int translation, int overrideshader) +void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture) { int usebright = false; int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; @@ -891,7 +891,7 @@ void FMaterial::BindPatch(int translation, int overrideshader) int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, tex->gl_info.shaderspeed); - const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, gl.needAlphaTexture); + const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, alphatexture); // The only multitexture effect usable on sprites is the brightmap. if (glpatch != NULL && shaderindex == 3) { diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index f01e39cd3..e1a5e93cd 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -135,7 +135,7 @@ public: } void Bind(int clamp = 0, int translation = 0, int overrideshader = 0); - void BindPatch(int translation = 0, int overrideshader = 0); + void BindPatch(int translation = 0, int overrideshader = 0, bool alphatexture = false); unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand = false, bool allowhires=true) const { diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index d4334251b..086cda7f9 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -155,10 +155,6 @@ vec4 getTexel(vec2 st) texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a); return texel; } - else if (texturemode == 4) - { - texel = vec4(1.0, 1.0, 1.0, texel.r); - } else if (texturemode == 2) { texel.a = 1.0; diff --git a/wadsrc/static/shaders/glsl/main_colormap.fp b/wadsrc/static/shaders/glsl/main_colormap.fp index d78a21f5f..5f88baaa7 100644 --- a/wadsrc/static/shaders/glsl/main_colormap.fp +++ b/wadsrc/static/shaders/glsl/main_colormap.fp @@ -26,10 +26,6 @@ vec4 getTexel(vec2 st) texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a); return texel; } - else if (texturemode == 4) - { - texel = vec4(1.0, 1.0, 1.0, texel.r); - } else if (texturemode == 2) { texel.a = 1.0; From 98cc7eeb99087e3e2976c9474bd05d08ed3a926c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 May 2014 00:13:19 +0200 Subject: [PATCH 015/138] pass softlightlevel through render state. --- src/gl/renderer/gl_lightdata.cpp | 91 ++++++------------------------ src/gl/renderer/gl_lightdata.h | 4 +- src/gl/renderer/gl_renderer.cpp | 2 +- src/gl/renderer/gl_renderstate.cpp | 5 ++ src/gl/renderer/gl_renderstate.h | 6 ++ src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_drawinfo.cpp | 2 +- src/gl/scene/gl_flats.cpp | 6 +- src/gl/scene/gl_portal.cpp | 4 +- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_walls_draw.cpp | 11 ++-- src/gl/scene/gl_weapon.cpp | 2 +- 13 files changed, 45 insertions(+), 94 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 60bc1bd67..60ecf70be 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -225,11 +225,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; } @@ -254,81 +254,22 @@ PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force) //========================================================================== // -// Get current light color +// set 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) +void gl_SetColor(int sectorlightlevel, int rellight, const FColormap &cm, float alpha, bool weapon) +{ + if (gl_fixedcolormap != CM_DEFAULT) { - if (!gl_enhanced_nightvision || !gl.hasGLSL()) - { - // we cannot multiply the light in here without causing major problems with the ThingColor so for older hardware - // these maps are done as a postprocessing overlay. - r = g = b = 1.0f; - } - else if (gl_fixedcolormap == CM_LITE) - { - r = 0.375f, g = 1.0f, b = 0.375f; - } - 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; - g = r; - b = g * 0.75f; - } - else r = g = b = 1.0f; - return; + gl_RenderState.SetColorAlpha(0xffffff, alpha, 0); + gl_RenderState.SetSoftLightLevel(255); } - - 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; -} - -//========================================================================== -// -// set current light color -// -//========================================================================== -void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, bool weapon) -{ - gl_GetLightColor(light, rellight, cm, red, green, blue, weapon); -} - -//========================================================================== -// -// set current light color -// -//========================================================================== -void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, bool weapon) -{ - float r,g,b; - - gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon); - - gl_RenderState.SetColor(r, g, b, alpha, cm->desaturation); - if (glset.lightmode == 8) - { - if (gl_fixedcolormap) - { - glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); - } - else - { - float lightlevel = gl_CalcLightLevel(light, rellight, weapon) / 255.0f; - glVertexAttrib1f(VATTR_LIGHTLEVEL, lightlevel); - } + else + { + 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)); } } @@ -586,7 +527,9 @@ void gl_SetFog(int lightlevel, int rellight, const FColormap *cmap, bool isaddit // 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); + } } } diff --git a/src/gl/renderer/gl_lightdata.h b/src/gl/renderer/gl_lightdata.h index b968bfe7a..f76f732af 100644 --- a/src/gl/renderer/gl_lightdata.h +++ b/src/gl/renderer/gl_lightdata.h @@ -15,9 +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, 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; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index f6420ce28..b6d64eeee 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -593,7 +593,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint FColormap cm; cm = colormap; - gl_SetColor(lightlevel, 0, &cm, 1.f); + gl_SetColor(lightlevel, 0, cm, 1.f); gltexture->Bind(); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index d6cf1804e..71198bafe 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -212,6 +212,11 @@ bool FRenderState::ApplyShader() glUniform4f(activeShader->dlightcolor_index, mDynColor.r / 255.f, mDynColor.g / 255.f, mDynColor.b / 255.f, 0); } + if (glset.lightmode == 8) + { + glVertexAttrib1f(VATTR_LIGHTLEVEL, mSoftLight / 255.f); + } + return true; } return false; diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index ab58c9509..5308da42b 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -96,6 +96,7 @@ class FRenderState bool mBrightmapEnabled; int mSpecialEffect; int mTextureMode; + int mSoftLight; float mLightParms[2]; int mNumLights[3]; float *mLightData; @@ -221,6 +222,11 @@ public: mGlowBottom.Set(b[0], b[1], b[2], b[3]); } + void SetSoftLightLevel(int level) + { + mSoftLight = level; + } + void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom) { mGlowTopPlane.Set(FIXED2FLOAT(top.a), FIXED2FLOAT(top.b), FIXED2FLOAT(top.ic), FIXED2FLOAT(top.d)); diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 5e490b8a7..1d15ebcab 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -317,7 +317,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_RenderState.SetObjectColor(decal->AlphaColor); } - gl_SetColor(light, rel, &p, a); + gl_SetColor(light, rel, p, a); // for additively drawn decals we must temporarily set the fog color to black. PalEntry fc = gl_RenderState.GetFogColor(); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 4db9602dc..2c7a4a15a 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -1066,7 +1066,7 @@ 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(); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 383ee1574..7be264e68 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -395,7 +395,7 @@ void GLFlat::Draw(int pass) switch (pass) { case GLPASS_BASE: - gl_SetColor(lightlevel, rel, &Colormap,1.0f); + gl_SetColor(lightlevel, rel, Colormap,1.0f); if (!foggy) gl_SetFog(lightlevel, rel, &Colormap, false); DrawSubsectors(pass, false); break; @@ -403,7 +403,7 @@ void GLFlat::Draw(int pass) case GLPASS_PLAIN: // Single-pass rendering case GLPASS_ALL: case GLPASS_BASE_MASKED: - gl_SetColor(lightlevel, rel, &Colormap,1.0f); + gl_SetColor(lightlevel, rel, Colormap,1.0f); if (!foggy || pass != GLPASS_BASE_MASKED) gl_SetFog(lightlevel, rel, &Colormap, false); // fall through case GLPASS_TEXTURE: @@ -460,7 +460,7 @@ void GLFlat::Draw(int pass) 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)); if (!gltexture) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 020a37b4e..b49b0027d 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -962,13 +962,13 @@ void GLHorizonPortal::DrawContents() if (gltexture && gltexture->tex->isFullbright()) { // glowing textures are always drawn full bright without color - gl_SetColor(255, 0, &origin->colormap, 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); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index d32432a28..3804ea048 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -460,7 +460,7 @@ void FGLRenderer::RenderScene(int recursion) { gl_RenderState.BlendFunc(GL_ONE, GL_ONE); glDepthFunc(GL_EQUAL); - if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0f); // Korshun. + gl_RenderState.SetSoftLightLevel(255); for(int i=GLDL_FIRSTLIGHT; i<=GLDL_LASTLIGHT; i++) { gl_drawinfo->drawlists[i].Draw(GLPASS_LIGHT); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index c051e94ee..41e94a73b 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -178,7 +178,7 @@ void GLSprite::Draw(int pass) { gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL); } - gl_SetColor(lightlevel, rel, &Colormap, trans); + gl_SetColor(lightlevel, rel, Colormap, trans); } gl_RenderState.SetObjectColor(ThingColor); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index d3574ebe9..dc7127690 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -371,8 +371,7 @@ void GLWall::RenderFogBoundary() gl_RenderState.EnableFog(false); gl_RenderState.AlphaFunc(GL_GREATER,0); glDepthFunc(GL_LEQUAL); - gl_RenderState.SetColor(fc[0], fc[1], fc[2], fogd1, Colormap.desaturation); - if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); // Korshun. + gl_RenderState.SetColor(fc[0], fc[1], fc[2], fogd1); flags &= ~GLWF_GLOW; RenderWall(4,fc); @@ -403,7 +402,7 @@ void GLWall::RenderMirrorSurface() // 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); @@ -471,7 +470,7 @@ 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); @@ -523,7 +522,7 @@ void GLWall::Draw(int pass) // fall through case GLPASS_PLAIN: // Single-pass rendering 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); @@ -537,7 +536,7 @@ void GLWall::Draw(int pass) 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); + gl_SetColor(lightlevel, rel, Colormap,1.0f); if (!(flags&GLWF_FOGGY)) { if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 1b0c99053..c6cd3c5dd 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -384,7 +384,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) else { gl_SetDynSpriteLight(playermo, NULL); - gl_SetColor(statebright[i] ? 255 : lightlevel, 0, &cmc, trans, true); + 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)); } From 4d005bdfa0aa769331241005f59b66130266d425 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 May 2014 14:45:41 +0200 Subject: [PATCH 016/138] shader rework All those special shaders have been merged together. Mostly working but the non-shader lighting seems a bit broken. --- src/gl/renderer/gl_colormap.h | 4 +- src/gl/renderer/gl_renderstate.cpp | 134 +++--- src/gl/renderer/gl_renderstate.h | 101 ++--- src/gl/scene/gl_scene.cpp | 2 + src/gl/scene/gl_sprite.cpp | 4 +- src/gl/scene/gl_weapon.cpp | 1 + src/gl/shaders/gl_shader.cpp | 405 +++++++----------- src/gl/shaders/gl_shader.h | 271 ++++++++---- src/gl/textures/gl_bitmap.cpp | 2 +- wadsrc/static/shaders/glsl/fogboundary.fp | 15 +- wadsrc/static/shaders/glsl/func_brightmap.fp | 11 +- .../static/shaders/glsl/func_defaultlight.fp | 5 + wadsrc/static/shaders/glsl/func_normal.fp | 5 +- wadsrc/static/shaders/glsl/func_notexture.fp | 4 +- wadsrc/static/shaders/glsl/func_warp1.fp | 4 +- wadsrc/static/shaders/glsl/func_warp2.fp | 4 +- wadsrc/static/shaders/glsl/func_wavex.fp | 4 +- wadsrc/static/shaders/glsl/fuzz_jagged.fp | 4 +- wadsrc/static/shaders/glsl/fuzz_noise.fp | 4 +- wadsrc/static/shaders/glsl/fuzz_smooth.fp | 4 +- .../static/shaders/glsl/fuzz_smoothnoise.fp | 4 +- .../shaders/glsl/fuzz_smoothtranslucent.fp | 4 +- wadsrc/static/shaders/glsl/fuzz_standard.fp | 4 +- wadsrc/static/shaders/glsl/fuzz_swirly.fp | 4 +- wadsrc/static/shaders/glsl/main.fp | 390 +++++++++-------- wadsrc/static/shaders/glsl/main.vp | 52 +-- wadsrc/static/shaders/glsl/main_colormap.fp | 51 --- wadsrc/static/shaders/glsl/main_foglayer.fp | 55 --- 28 files changed, 722 insertions(+), 830 deletions(-) create mode 100644 wadsrc/static/shaders/glsl/func_defaultlight.fp delete mode 100644 wadsrc/static/shaders/glsl/main_colormap.fp delete mode 100644 wadsrc/static/shaders/glsl/main_foglayer.fp diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 7d2bdb7ee..8126cb5d4 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -15,13 +15,11 @@ enum EColorManipulation CM_DEFAULT=0, // untranslated 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 }; #define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 71198bafe..7efa1d30f 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -38,6 +38,7 @@ ** */ +#include "templates.h" #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" @@ -51,7 +52,6 @@ void gl_SetTextureMode(int type); FRenderState gl_RenderState; -int FStateAttr::ChangeCounter; CVAR(Bool, gl_direct_state_change, true, 0) @@ -71,6 +71,7 @@ void FRenderState::Reset() mFogColor.d = ffFogColor.d = -1; mFogDensity = ffFogDensity = 0; mTextureMode = ffTextureMode = -1; + mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA; glSrcBlend = glDstBlend = -1; @@ -83,6 +84,7 @@ void FRenderState::Reset() m2D = true; mVertexBuffer = mCurrentVertexBuffer = NULL; mColormapState = CM_DEFAULT; + mLightParms[3] = -1.f; } @@ -128,11 +130,12 @@ bool FRenderState::ApplyShader() { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); } - FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); + FShader *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4); if (shd != NULL) { - activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); + activeShader = shd; + shd->Bind(); } int fogset = 0; @@ -149,74 +152,93 @@ bool FRenderState::ApplyShader() } } - if (fogset != activeShader->currentfogenabled) - { - glUniform1i(activeShader->fogenabled_index, (activeShader->currentfogenabled = fogset)); - } - 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; + glColor4fv(mColor.vec); + + activeShader->muDesaturation.Set(mDesaturation); + 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); - 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->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. - glUniform4f(activeShader->glowtopcolor_index, 0.f, 0.f, 0.f, 0.f); - glUniform4f(activeShader->glowbottomcolor_index, 0.f, 0.f, 0.f, 0.f); + 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 (mLightEnabled) { - glUniform3iv(activeShader->lightrange_index, 1, mNumLights); - glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData); + activeShader->muLightRange.Set(mNumLights); + glUniform4fv(activeShader->lights_index, mNumLights[3], mLightData); } - if (mObjectColor != activeShader->currentobjectcolor) + else { - activeShader->currentobjectcolor = mObjectColor; - glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f); - } - if (mDynColor != activeShader->currentdlightcolor) - { - activeShader->currentobjectcolor = mObjectColor; - glUniform4f(activeShader->dlightcolor_index, mDynColor.r / 255.f, mDynColor.g / 255.f, mDynColor.b / 255.f, 0); + static const int nulint[] = { 0, 0, 0, 0 }; + activeShader->muLightRange.Set(nulint); } - if (glset.lightmode == 8) + if (mColormapState != activeShader->currentfixedcolormap) { - glVertexAttrib1f(VATTR_LIGHTLEVEL, mSoftLight / 255.f); - } + float r, g, b; + activeShader->currentfixedcolormap = mColormapState; + if (mColormapState == CM_DEFAULT) + { + 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) + { + r = 0.375f, g = 1.0f, b = 0.375f; + } + else + { + r = g = b = 1.f; + } + activeShader->muFixedColormap.Set(2); + activeShader->muColormapStart.Set(r, g, b, 1.f); + } + else if (mColormapState >= CM_TORCH) + { + 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); + } + } return true; } return false; @@ -326,6 +348,14 @@ void FRenderState::Apply(bool forcenoshader) } ffSpecialEffect = mSpecialEffect; } + // Now compose the final color for this... + float realcolor[4]; + realcolor[0] = clamp((mColor.vec[0] + mDynColor.r / 255.f), 0.f, 1.f) * (mObjectColor.r / 255.f); + realcolor[1] = clamp((mColor.vec[1] + mDynColor.g / 255.f), 0.f, 1.f) * (mObjectColor.g / 255.f); + realcolor[2] = clamp((mColor.vec[2] + mDynColor.b / 255.f), 0.f, 1.f) * (mObjectColor.b / 255.f); + realcolor[3] = mColor.vec[3] * (mObjectColor.a / 255.f); + glColor4fv(realcolor); + } } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 5308da42b..e8de712f6 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -3,6 +3,7 @@ #include #include "gl/system/gl_interface.h" +#include "gl/data/gl_data.h" #include "c_cvars.h" #include "r_defs.h" @@ -10,81 +11,29 @@ class FVertexBuffer; 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 @@ -96,9 +45,10 @@ class FRenderState bool mBrightmapEnabled; int mSpecialEffect; int mTextureMode; + int mDesaturation; int mSoftLight; - float mLightParms[2]; - int mNumLights[3]; + float mLightParms[4]; + int mNumLights[4]; float *mLightData; int mSrcBlend, mDstBlend; int mAlphaFunc; @@ -109,7 +59,7 @@ class FRenderState FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FStateVec4 mColor; - FStateVec3 mCameraPos; + FStateVec4 mCameraPos; FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTopPlane, mGlowBottomPlane; PalEntry mFogColor; @@ -155,25 +105,25 @@ public: void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mColor.Set(r, g, b, a); - glColor4fv(mColor.vec); + 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); - glColor4fv(mColor.vec); + 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); - glColor4fv(mColor.vec); + mDesaturation = desat; } void ResetColor() { mColor.Set(1,1,1,1); - glColor4fv(mColor.vec); + mDesaturation = 0; } void SetTextureMode(int mode) @@ -213,7 +163,7 @@ public: 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) @@ -224,7 +174,8 @@ public: void SetSoftLightLevel(int level) { - mSoftLight = 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) @@ -235,7 +186,7 @@ public: void SetDynLight(float r, float g, float b) { - mDynColor = PalEntry(xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255)); + mDynColor = PalEntry(255, xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255)); } void SetDynLight(PalEntry pe) @@ -250,21 +201,23 @@ public: 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; + mLightParms[1] = f; + mLightParms[0] = d; } void SetLights(int *numlights, float *lightdata) { - mNumLights[0] = numlights[0]; - mNumLights[1] = numlights[1]; - mNumLights[2] = numlights[2]; + mNumLights[0] = 0; + mNumLights[1] = numlights[0]; + mNumLights[2] = numlights[1]; + mNumLights[3] = numlights[2]; mLightData = lightdata; // caution: the data must be preserved by the caller until the 'apply' call! } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 3804ea048..8670c1d49 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -842,6 +842,7 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) DrawPlayerSprites (viewsector, false); } gl_RenderState.SetFixedColormap(CM_DEFAULT); + gl_RenderState.SetSoftLightLevel(-1); DrawTargeterSprites(); DrawBlend(viewsector); @@ -1059,6 +1060,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei 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(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 41e94a73b..84ecbf0a1 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -287,7 +287,7 @@ void GLSprite::Draw(int pass) { // If we get here we know that we have colored fog and no fixed colormap. gl_SetFog(foglevel, rel, &Colormap, additivefog); - //gl_RenderState.SetFixedColormap(CM_FOGLAYER); fixme: does not work yet. + gl_RenderState.SetFixedColormap(CM_FOGLAYER); gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.Apply(); @@ -308,7 +308,7 @@ void GLSprite::Draw(int pass) glVertex3fv(&v4[0]); } glEnd(); - + gl_RenderState.SetFixedColormap(CM_DEFAULT); } } else diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index c6cd3c5dd..6991bed5c 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -283,6 +283,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) } PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; + ThingColor.a = 255; visstyle_t vis; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index a132e65dd..35916bd00 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -57,17 +57,6 @@ #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; - //========================================================================== // // @@ -81,6 +70,10 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * if (gl.hasGLSL()) { + 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); @@ -90,12 +83,18 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * FMemLump fp_data = Wads.ReadLump(fp_lump); - FString vp_comb; - FString fp_comb; - vp_comb = defines; - fp_comb = vp_comb; - // This uses GetChars on the strings to get rid of terminating 0 characters. + // + // The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break! + // + + FString vp_comb = "#version 130\n"; + if (gl.glslversion >= 3.3f) vp_comb = "#version 330 compatibility\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. + // todo when using shader storage buffers, add + // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. + 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"; @@ -107,12 +106,27 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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(); + + 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 + else { // Proc_prog_lump is not a lump name but the source itself (from generated shaders) - fp_comb << proc_prog_lump+1; + fp_comb << proc_prog_lump + 1; } } @@ -137,9 +151,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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); @@ -159,30 +170,34 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * error << "Linking:\n" << buffer << "\n"; } int linked; - glGetShaderiv(hShader, GL_LINK_STATUS, &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()); + I_Error("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"); - objectcolor_index = glGetUniformLocation(hShader, "objectcolor"); - glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor"); - glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor"); - glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane"); - glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane"); + + 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"); + muLightRange.Init(hShader, "uLightRange"); + 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"); + + timer_index = glGetUniformLocation(hShader, "timer"); + lights_index = glGetUniformLocation(hShader, "lights"); + glUseProgram(hShader); @@ -203,9 +218,12 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * FShader::~FShader() { - glDeleteProgram(hShader); - glDeleteShader(hVertProg); - glDeleteShader(hFragProg); + if (gl.hasGLSL()) + { + glDeleteProgram(hShader); + glDeleteShader(hVertProg); + glDeleteShader(hFragProg); + } } @@ -215,202 +233,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) { - 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"; + // this can't be in the shader code due to ATI strangeness. + const char *str = (gl.MaxLights() == 128)? "#define MAXLIGHTS128\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, str)) { - delete shader_cm; - shader_cm = NULL; + I_Error("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()); - } - - 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) - { - 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"; - } - 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()); - } + if (shader != NULL) delete shader; + shader = NULL; + I_Error("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage()); } + return 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; - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights) -{ - 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 = false;// 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; -} - - //========================================================================== // // @@ -454,8 +311,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, "" }, + { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n" }, + { "burn", "shaders/glsl/burn.vp", "shaders/glsl/burn.fp", NULL, "" }, + { "stencil", "shaders/glsl/stencil.vp", "shaders/glsl/stencil.fp", NULL, "" }, }; @@ -489,35 +348,46 @@ FShaderManager::~FShaderManager() void FShaderManager::CompileShaders() { - mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; - if (gl.hasGLSL()) + try { - for(int i=0;defaultshaders[i].ShaderName != NULL;i++) + mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; + if (gl.hasGLSL()) { - FShaderContainer * shc = new FShaderContainer(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); - mTextureEffects.Push(shc); - } - - for(unsigned i = 0; i < usershaders.Size(); i++) - { - FString name = ExtractFileBase(usershaders[i]); - FName sfn = name; - - FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]); - 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; defaultshaders[i].ShaderName != NULL; i++) { - delete eff; + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); + mTextureEffects.Push(shc); + } + + for (unsigned i = 0; i < usershaders.Size(); i++) + { + FString name = ExtractFileBase(usershaders[i]); + FName sfn = name; + + FShader *shc = Compile(sfn, usershaders[i]); + mTextureEffects.Push(shc); + } + + for (int i = 0; i < MAX_EFFECTS; i++) + { + FShader *eff = new FShader(effectshaders[i].ShaderName); + if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, + effectshaders[i].fp2, effectshaders[i].defines)) + { + delete eff; + } + else mEffectShaders[i] = eff; } - else mEffectShaders[i] = eff; } } + catch (CRecoverableError &err) + { + // If shader compilation failed we can still run the fixed function mode so do that instead of aborting. + Printf("%s\n", err.GetMessage()); + Printf(PRINT_HIGH, "Failed to compile shaders. Reverting to fixed function mode\n"); + gl_usevbo = false; + gl.glslversion = 0.0; + } } //========================================================================== @@ -528,17 +398,22 @@ void FShaderManager::CompileShaders() void FShaderManager::Clean() { - SetActiveShader(NULL); - for(unsigned int i=0;iName == sfn) + if (mTextureEffects[i]->mName == sfn) { return i; } @@ -569,26 +444,42 @@ 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.hasGLSL() && mActiveShader != sh) { - glUseProgram(sh == NULL? 0 : sh->GetHandle()); + glUseProgram(sh!= NULL? sh->GetHandle() : NULL); mActiveShader = sh; } } + //========================================================================== // +// To avoid maintenance this will be set when a warped texture is bound +// because at that point the draw buffer needs to be flushed anyway. // +//========================================================================== + +void FShaderManager::SetWarpSpeed(unsigned int eff, float speed) +{ + // indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom + if (eff < mTextureEffects.Size()) + { + FShader *sh = mTextureEffects[eff]; + + float warpphase = gl_frameMS * speed / 1000.f; + glProgramUniform1f(sh->GetHandle(), sh->timer_index, warpphase); + } +} + // //========================================================================== 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; } diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 62c87c1f9..3497ed3b0 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -7,80 +7,198 @@ extern bool gl_shaderactive; -const int VATTR_FOGPARAMS = 14; -const int VATTR_LIGHTLEVEL = 13; // Korshun. +//========================================================================== +// +// +//========================================================================== + +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 +{ + int 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; + FBufferedUniform1f muDesaturation; + FBufferedUniform1i muFogEnabled; + FBufferedUniform1i muTextureMode; + FBufferedUniform4f muCameraPos; + FBufferedUniform4f muLightParms; + FUniform1i muFixedColormap; + FUniform4f muColormapStart; + FUniform4f muColormapRange; + FBufferedUniform4i muLightRange; + FBufferedUniformPE muFogColor; + FBufferedUniformPE muDynLightColor; + FBufferedUniformPE muObjectColor; + FUniform4f muGlowBottomColor; + FUniform4f muGlowTopColor; + FUniform4f muGlowBottomPlane; + FUniform4f muGlowTopPlane; + 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; int lights_index; - int dlightcolor_index; - int glowbottomcolor_index; - int glowtopcolor_index; - int glowbottomplane_index; - int glowtopplane_index; - int objectcolor_index; - - PalEntry currentdlightcolor; - PalEntry currentobjectcolor; int currentglowstate; - int currentfogenabled; - int currenttexturemode; - float currentlightfactor; - float currentlightdist; - - PalEntry currentfogcolor; - float currentfogdensity; - - FStateVec3 currentcamerapos; + int currentfixedcolormap; public: - FShader() + FShader(const char *name) + : mName(name) { hShader = hVertProg = hFragProg = 0; - currentglowstate = currentfogenabled = currenttexturemode = 0; - currentlightfactor = currentlightdist = 0.0f; - currentfogdensity = -1; - currentdlightcolor = currentobjectcolor = 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; - objectcolor_index = -1; - glowtopplane_index = -1; - glowbottomplane_index = -1; - glowtopcolor_index = -1; - glowbottomcolor_index = -1; + currentglowstate = 0; + currentfixedcolormap = 0; } ~FShader(); @@ -91,34 +209,10 @@ 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; } -}; -//========================================================================== -// -// 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); }; @@ -129,14 +223,9 @@ public: //========================================================================== class FShaderManager { - enum - { - NUM_EFFECTS = 2 - }; - - TArray mTextureEffects; + TArray mTextureEffects; FShader *mActiveShader; - FShader *mEffectShaders[NUM_EFFECTS]; + FShader *mEffectShaders[MAX_EFFECTS]; void Clean(); void CompileShaders(); @@ -144,11 +233,13 @@ class FShaderManager public: FShaderManager(); ~FShaderManager(); + FShader *Compile(const char *ShaderName, const char *ShaderPath); int Find(const char *mame); FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); + void SetWarpSpeed(unsigned int eff, float speed); - FShaderContainer *Get(unsigned int eff) + FShader *Get(unsigned int eff) { // indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom if (eff < mTextureEffects.Size()) diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index 51e03aa98..83a92e0fe 100644 --- a/src/gl/textures/gl_bitmap.cpp +++ b/src/gl/textures/gl_bitmap.cpp @@ -136,7 +136,7 @@ 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 + // alpha map with 0==transparent and 1==opaque if (alphatex) { for(int i=0;i<256;i++) diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 5ab8ac717..0d4fb9a0d 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -1,8 +1,5 @@ -uniform int fogenabled; -uniform vec4 fogcolor; -uniform vec3 camerapos; -varying vec4 pixelpos; -varying vec4 fogparm; +in vec4 pixelpos; +in vec2 glowdist; //=========================================================================== // @@ -18,15 +15,15 @@ void main() // // calculate fog factor // - if (fogenabled == -1) + if (uFogEnabled == -1) { fogdist = pixelpos.w; } else { - fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); } - fogfactor = exp2 (fogparm.z * fogdist); - gl_FragColor = vec4(fogcolor.rgb, 1.0 - fogfactor); + fogfactor = exp2 (uFogDensity * fogdist); + gl_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..b8b2a9f20 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(gl_TexCoord[0].st); } +vec4 ProcessLight(vec4 color) +{ + vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].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..d3b0d182c 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(gl_TexCoord[0].st); } diff --git a/wadsrc/static/shaders/glsl/func_notexture.fp b/wadsrc/static/shaders/glsl/func_notexture.fp index 904d4a6cd..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*objectcolor; + return desaturate(uObjectColor); } diff --git a/wadsrc/static/shaders/glsl/func_warp1.fp b/wadsrc/static/shaders/glsl/func_warp1.fp index c4acb8854..2dbf8a420 100644 --- a/wadsrc/static/shaders/glsl/func_warp1.fp +++ b/wadsrc/static/shaders/glsl/func_warp1.fp @@ -1,6 +1,6 @@ uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { vec2 texCoord = gl_TexCoord[0].st; @@ -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..78044f970 100644 --- a/wadsrc/static/shaders/glsl/func_warp2.fp +++ b/wadsrc/static/shaders/glsl/func_warp2.fp @@ -1,6 +1,6 @@ uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { vec2 texCoord = gl_TexCoord[0].st; @@ -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..5172239c7 100644 --- a/wadsrc/static/shaders/glsl/func_wavex.fp +++ b/wadsrc/static/shaders/glsl/func_wavex.fp @@ -1,6 +1,6 @@ uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { vec2 texCoord = gl_TexCoord[0].st; @@ -8,6 +8,6 @@ vec4 Process(vec4 color) 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..103f34689 100644 --- a/wadsrc/static/shaders/glsl/fuzz_jagged.fp +++ b/wadsrc/static/shaders/glsl/fuzz_jagged.fp @@ -1,7 +1,7 @@ //created by Evil Space Tomato uniform float timer; -vec4 Process(vec4 color) +vec4 ProcessTexel() { vec2 texCoord = gl_TexCoord[0].st; @@ -10,7 +10,7 @@ vec4 Process(vec4 color) 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..02985a122 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; + 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..597debb53 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; + 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..196cca33a 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; + 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..bfd60de57 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; + 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..a1bd0ebaf 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; + 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..de91e47d6 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; + 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 086cda7f9..db5b8cb19 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -1,56 +1,93 @@ - -// 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 pixelpos; +in vec2 glowdist; -#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 = 3) buffer ParameterBuffer + { + vec4 lights[]; + }; +#elif defined MAXLIGHTS128 + uniform vec4 lights[256]; #else -uniform vec4 lights[128]; -#endif - + uniform vec4 lights[128]; #endif - -uniform int fogenabled; -uniform vec4 fogcolor; -uniform vec4 objectcolor; -uniform vec4 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 (vec4(gray,gray,gray,texel.a), texel, 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: + texel.rgb = vec3(1.0,1.0,1.0); + break; + + case 2: + texel.a = 1.0; + break; + + case 3: + texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a); + 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; @@ -66,106 +103,97 @@ 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), 0.0, 1.0); - #endif - #ifndef NO_FOG - // - // apply light diminishing - // - if (fogenabled > 0) + + if (uLightLevel >= 0.0) { - #if (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 == 3) - { - texel *=objectcolor; - texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a); - return texel; - } - else 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 * objectcolor); + // + // apply dynamic lights (except additive) + // + + vec4 dynlight = uDynLightColor; + + if (uLightRange.z > uLightRange.x) + { + // + // modulated lights + // + for(int i=uLightRange.x; i uLightRange.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=uLightRange.z; i Date: Mon, 12 May 2014 14:58:37 +0200 Subject: [PATCH 017/138] - fixed: fog density calculation for fixed function was not correct. --- src/gl/renderer/gl_renderstate.cpp | 9 +++++---- src/gl/renderer/gl_renderstate.h | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 7efa1d30f..746bbb176 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -69,7 +69,7 @@ void FRenderState::Reset() ffTextureEnabled = ffFogEnabled = false; mSpecialEffect = ffSpecialEffect = EFF_NONE; mFogColor.d = ffFogColor.d = -1; - mFogDensity = ffFogDensity = 0; + ffFogDensity = 0; mTextureMode = ffTextureMode = -1; mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; @@ -316,10 +316,11 @@ void FRenderState::Apply(bool forcenoshader) 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) + if (ffFogDensity != mLightParms[2]) { - glFogf(GL_FOG_DENSITY, mFogDensity/64000.f); - ffFogDensity=mFogDensity; + const float LOG2E = 1.442692f; // = 1/log(2) + glFogf(GL_FOG_DENSITY, -mLightParms[2] / LOG2E); + ffFogDensity = mLightParms[2]; } } if (mSpecialEffect != ffSpecialEffect) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index e8de712f6..888ead0d7 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -65,7 +65,6 @@ class FRenderState PalEntry mFogColor; PalEntry mObjectColor; PalEntry mDynColor; - float mFogDensity; int mEffectState; int mColormapState; From 9c659b948c8b857dbb56d26e1d367003a6324826 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 May 2014 15:13:07 +0200 Subject: [PATCH 018/138] - reactivated texture warping. --- src/gl/renderer/gl_renderstate.cpp | 5 ++--- src/gl/renderer/gl_renderstate.h | 3 +-- src/gl/textures/gl_material.cpp | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 746bbb176..4668bf2b7 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -94,15 +94,14 @@ void FRenderState::Reset() // //========================================================================== -int FRenderState::SetupShader(bool cameratexture, int &shaderindex, float warptime) +int FRenderState::SetupShader(int &shaderindex, float warptime) { int softwarewarp = 0; - if (gl.hasGLSL()) { mEffectState = shaderindex; - mWarpTime = warptime; + if (shaderindex > 0) GLRenderer->mShaderManager->SetWarpSpeed(shaderindex, warptime); } else { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 888ead0d7..79e277948 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -68,7 +68,6 @@ class FRenderState int mEffectState; int mColormapState; - float mWarpTime; int glSrcBlend, glDstBlend; int glAlphaFunc; @@ -93,7 +92,7 @@ public: void Reset(); - int SetupShader(bool cameratexture, int &shaderindex, float warptime); + int SetupShader(int &shaderindex, float warptime); void Apply(bool forcenoshader = false); void SetVertexBuffer(FVertexBuffer *vb) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index ce3c75181..988ac8121 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -842,7 +842,7 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader) int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT; - int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, tex->gl_info.shaderspeed); + int softwarewarp = gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); if (tex->bHasCanvas || tex->bWarped) clampmode = 0; else if (clampmode != -1) clampmode &= 3; @@ -889,7 +889,7 @@ void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; - int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, tex->gl_info.shaderspeed); + int softwarewarp = gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, alphatexture); // The only multitexture effect usable on sprites is the brightmap. From b514a815f4341c29ab05b075e7b3e36c7aa1f668 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 May 2014 20:23:54 +0200 Subject: [PATCH 019/138] - enable use of vertex buffer for sprite rendering. --- src/gl/data/gl_vertexbuffer.h | 8 ++++ src/gl/dynlights/a_dynlight.cpp | 2 +- src/gl/scene/gl_sprite.cpp | 80 ++++++++++++++++++++++----------- src/gl/scene/gl_walls_draw.cpp | 24 ++-------- 4 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 24fe5b4d5..0a32abf6b 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -26,6 +26,14 @@ struct FFlatVertex float u,v; // texture coordinates 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) diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 6ac50a785..1945e8bf5 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -528,7 +528,7 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius) touching_subsectors = AddLightNode(&subSec->lighthead[additive], subSec, this, touching_subsectors); if (subSec->sector->validcount != ::validcount) { - touching_sector = AddLightNode(&subSec->sector->lighthead[additive], subSec->sector, this, touching_sector); + touching_sector = AddLightNode(&subSec->render_sector->lighthead[additive], subSec->sector, this, touching_sector); subSec->sector->validcount = ::validcount; } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 84ecbf0a1..63c7bd46b 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); @@ -265,33 +267,10 @@ void GLSprite::Draw(int pass) v4 = Vector(x2, z2, y2); } - glBegin(GL_TRIANGLE_STRIP); - if (gltexture) + FFlatVertex *ptr; + unsigned int offset, count; + if (!gl_usevbo) { - 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(); - - if (foglayer) - { - // If we get here we know that we have colored fog and no fixed colormap. - gl_SetFog(foglevel, rel, &Colormap, additivefog); - gl_RenderState.SetFixedColormap(CM_FOGLAYER); - 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) { @@ -307,7 +286,56 @@ void GLSprite::Draw(int pass) glVertex3fv(&v3[0]); glVertex3fv(&v4[0]); } + glEnd(); + } + else + { + 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++; + count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_STRIP, offset, count); + } + + if (foglayer) + { + // If we get here we know that we have colored fog and no fixed colormap. + gl_SetFog(foglevel, rel, &Colormap, additivefog); + gl_RenderState.SetFixedColormap(CM_FOGLAYER); + gl_RenderState.BlendEquation(GL_FUNC_ADD); + gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_RenderState.Apply(); + + if (!gl_usevbo) + { + 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(); + } + else + { + glDrawArrays(GL_TRIANGLE_STRIP, offset, count); + } gl_RenderState.SetFixedColormap(CM_DEFAULT); } } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index dc7127690..ca32e98a6 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -290,32 +290,16 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) { FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - ptr->x = glseg.x1; - ptr->y = glseg.y1; - ptr->z = zbottom[0]; - ptr->u = tcs[0].u; - ptr->v = tcs[0].v; + ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v); ptr++; if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr); - ptr->x = glseg.x1; - ptr->y = glseg.y1; - ptr->z = ztop[0]; - ptr->u = tcs[1].u; - ptr->v = tcs[1].v; + ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v); ptr++; if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr); - ptr->x = glseg.x2; - ptr->y = glseg.y2; - ptr->z = ztop[1]; - ptr->u = tcs[2].u; - ptr->v = tcs[2].v; + ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v); ptr++; if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr); - ptr->x = glseg.x2; - ptr->y = glseg.y2; - ptr->z = zbottom[1]; - ptr->u = tcs[3].u; - ptr->v = tcs[3].v; + ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); unsigned int offset; From cf45f2d718eb9548f7eba91565fcaa860fab780a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 May 2014 22:24:26 +0200 Subject: [PATCH 020/138] - added missing shader files. --- src/gl/scene/gl_weapon.cpp | 31 +++++++++++++++---- wadsrc/static/shaders/glsl/burn.fp | 12 ++++++++ wadsrc/static/shaders/glsl/burn.vp | 7 +++++ wadsrc/static/shaders/glsl/shaderdefs.i | 41 +++++++++++++++++++++++++ wadsrc/static/shaders/glsl/stencil.fp | 7 +++++ wadsrc/static/shaders/glsl/stencil.vp | 14 +++++++++ 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 wadsrc/static/shaders/glsl/burn.fp create mode 100644 wadsrc/static/shaders/glsl/burn.vp create mode 100644 wadsrc/static/shaders/glsl/shaderdefs.i create mode 100644 wadsrc/static/shaders/glsl/stencil.fp create mode 100644 wadsrc/static/shaders/glsl/stencil.vp diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 6991bed5c..5fca4bb49 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" @@ -153,12 +154,30 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed gl_RenderState.EnableAlphaTest(false); } 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 (!gl_usevbo) + { + 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(); + } + else + { + 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++; + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_STRIP, offset, count); + } if (tex->GetTransparent() || OverrideShader != 0) { gl_RenderState.EnableAlphaTest(true); diff --git a/wadsrc/static/shaders/glsl/burn.fp b/wadsrc/static/shaders/glsl/burn.fp new file mode 100644 index 000000000..8ccb553f8 --- /dev/null +++ b/wadsrc/static/shaders/glsl/burn.fp @@ -0,0 +1,12 @@ +uniform sampler2D tex; +uniform sampler2D texture2; + +void main() +{ + vec4 frag = gl_Color; + + vec4 t1 = texture2D(texture2, gl_TexCoord[0].xy); + vec4 t2 = texture2D(tex, vec2(gl_TexCoord[0].x, 1.0-gl_TexCoord[0].y)); + + gl_FragColor = frag * vec4(t1.r, t1.g, t1.b, t2.a); +} diff --git a/wadsrc/static/shaders/glsl/burn.vp b/wadsrc/static/shaders/glsl/burn.vp new file mode 100644 index 000000000..6a8d2b37b --- /dev/null +++ b/wadsrc/static/shaders/glsl/burn.vp @@ -0,0 +1,7 @@ + +void main() +{ + gl_FrontColor = gl_Color; + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = ProjectionMatrix * gl_Vertex; +} diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i new file mode 100644 index 000000000..efedca5e5 --- /dev/null +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -0,0 +1,41 @@ +// This file contains common data definitions for both vertex and fragment shader + +uniform vec4 uCameraPos; + +uniform int uTextureMode; + +// colors +uniform vec4 uObjectColor; +uniform vec4 uDynLightColor; +uniform vec4 uFogColor; +uniform float uDesaturationFactor; + +// Fixed colormap stuff +uniform int uFixedColormap; // 0, when no fixed colormap, 1 for a light value, 2 for a color blend, 3 for a fog layer +uniform vec4 uFixedColormapStart; +uniform vec4 uFixedColormapRange; + +// Glowing walls stuff +uniform vec4 uGlowTopPlane; +uniform vec4 uGlowTopColor; +uniform vec4 uGlowBottomPlane; +uniform vec4 uGlowBottomColor; + +// Lighting + Fog +uniform vec4 uLightAttr; +#define uLightLevel uLightAttr.a +#define uFogDensity uLightAttr.b +#define uLightFactor uLightAttr.g +#define uLightDist uLightAttr.r +uniform int uFogEnabled; + +// dynamic lights +uniform ivec4 uLightRange; + + +// redefine the matrix names to what they actually represent. +#define ModelMatrix gl_TextureMatrix[7] +#define ViewMatrix gl_ModelViewMatrix +#define ProjectionMatrix gl_ProjectionMatrix +#define TextureMatrix gl_TextureMatrix[0] + diff --git a/wadsrc/static/shaders/glsl/stencil.fp b/wadsrc/static/shaders/glsl/stencil.fp new file mode 100644 index 000000000..9e4afec04 --- /dev/null +++ b/wadsrc/static/shaders/glsl/stencil.fp @@ -0,0 +1,7 @@ +in vec4 pixelpos; + +void main() +{ + gl_FragColor = vec4(1.0); +} + diff --git a/wadsrc/static/shaders/glsl/stencil.vp b/wadsrc/static/shaders/glsl/stencil.vp new file mode 100644 index 000000000..f5ac9fdd1 --- /dev/null +++ b/wadsrc/static/shaders/glsl/stencil.vp @@ -0,0 +1,14 @@ + +out vec4 pixelpos; + +void main() +{ + // perform exactly the same relevant steps as in the main shader to ensure matching results (that also means including the model matrix here!) + vec4 worldcoord = ModelMatrix * gl_Vertex; + vec4 eyeCoordPos = ViewMatrix * worldcoord; + + pixelpos.xyz = worldcoord.xyz; + pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w; + + gl_Position = ProjectionMatrix * eyeCoordPos; +} From 579eff5b9648d671579a4c68c8d4aa0e58496485 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 May 2014 22:46:30 +0200 Subject: [PATCH 021/138] - add vertex buffer based rendering for decals. --- src/gl/scene/gl_decal.cpp | 26 +++++++++++++++++++++----- src/gl/scene/gl_flats.cpp | 4 ++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 1d15ebcab..61c92d3fd 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" @@ -336,13 +337,28 @@ void GLWall::DrawDecal(DBaseDecal *decal) else gl_RenderState.AlphaFunc(GL_GREATER, 0.f); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - for(i=0;i<4;i++) + if (!gl_usevbo) { - glTexCoord2f(dv[i].u,dv[i].v); - glVertex3f(dv[i].x,dv[i].z,dv[i].y); + glBegin(GL_TRIANGLE_FAN); + for (i = 0; i < 4; i++) + { + glTexCoord2f(dv[i].u, dv[i].v); + glVertex3f(dv[i].x, dv[i].z, dv[i].y); + } + glEnd(); + } + else + { + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (i = 0; i < 4; i++) + { + ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); + ptr++; + } + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); } - glEnd(); rendered_decals++; gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.SetObjectColor(0xffffffff); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 7be264e68..4d3f4c3f6 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -153,14 +153,14 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) // Render the light glBegin(GL_TRIANGLE_FAN); - for(k = 0, v = sub->firstline; k < sub->numlines; k++, v++) + 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); + glTexCoord2f((nearToVert.Dot(right) * scale) + 0.5f, (nearToVert.Dot(up) * scale) + 0.5f); glVertex3f(vt->fx, zc, vt->fy); } From 60f0ab5f1b4de47ae4bfb01830edee896b490774 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 13 May 2014 12:00:11 +0200 Subject: [PATCH 022/138] - fixed Linux warning with type cast. --- src/gl/data/gl_vertexbuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 0a32abf6b..013e6d73a 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -64,7 +64,7 @@ public: } unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset) { - unsigned int newofs = unsigned int(newptr - map); + unsigned int newofs = (unsigned int)(newptr - map); unsigned int diff = newofs - mCurIndex; *poffset = mCurIndex; mCurIndex = newofs; From 23fbd6996390dc134f8e0d1098a5b4da34542613 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 20 May 2014 22:20:15 +0200 Subject: [PATCH 023/138] - 4 more places where immediate mode drawing has been substituted with a buffer-based alternative. --- src/gl/scene/gl_drawinfo.cpp | 99 ++++++++++++++++++++++++++++-------- src/gl/scene/gl_scene.cpp | 30 ++++++++--- 2 files changed, 101 insertions(+), 28 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 2c7a4a15a..e0e6cf8df 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -47,6 +47,7 @@ #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" @@ -990,12 +991,30 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws) 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(); + if (!gl_usevbo) + { + 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(); + } + else + { + 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++; + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); + } glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil @@ -1016,12 +1035,30 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws) 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(); + if (!gl_usevbo) + { + 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(); + } + else + { + 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++; + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); + } // restore old stencil op. glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); @@ -1078,7 +1115,6 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo 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); @@ -1094,19 +1130,38 @@ 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); + if (!gl_usevbo) + { + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(px1 / 64, -py1 / 64); + glVertex3f(px1, planez, py1); - glTexCoord2f(px2 / 64, -py2 / 64); - glVertex3f(px2, planez, py2); + glTexCoord2f(px2 / 64, -py2 / 64); + glVertex3f(px2, planez, py2); - glTexCoord2f(px3 / 64, -py3 / 64); - glVertex3f(px3, planez, py3); + glTexCoord2f(px3 / 64, -py3 / 64); + glVertex3f(px3, planez, py3); - glTexCoord2f(px4 / 64, -py4 / 64); - glVertex3f(px4, planez, py4); + glTexCoord2f(px4 / 64, -py4 / 64); + glVertex3f(px4, planez, py4); - glEnd(); + glEnd(); + } + else + { + 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++; + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); + } if (pushed) { diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 8670c1d49..809a516e7 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -617,12 +617,30 @@ static void FillScreen() gl_RenderState.EnableAlphaTest(false); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); - 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(); + if (!gl_usevbo) + { + 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(); + } + else + { + 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++; + unsigned int offset; + unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); + glDrawArrays(GL_TRIANGLE_FAN, offset, count); + } } //========================================================================== From 09ba62fbef5a858ea5ed35f5926baeca74988441 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 20 May 2014 22:37:38 +0200 Subject: [PATCH 024/138] - put all the common part of buffer based drawing into a separate method of the vertex buffer. --- src/gl/data/gl_vertexbuffer.h | 8 ++++++++ src/gl/scene/gl_decal.cpp | 4 +--- src/gl/scene/gl_drawinfo.cpp | 12 +++--------- src/gl/scene/gl_flats.cpp | 4 +--- src/gl/scene/gl_scene.cpp | 4 +--- src/gl/scene/gl_walls_draw.cpp | 4 +--- src/gl/scene/gl_weapon.cpp | 4 +--- 7 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 013e6d73a..80db0d64e 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -70,6 +70,14 @@ public: mCurIndex = newofs; 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 RenderCurrent(FFlatVertex *newptr, unsigned int primtype) + { + unsigned int offset; + unsigned int count = GetCount(newptr, &offset); + glDrawArrays(primtype, offset, count); + } +#endif void Reset() { mCurIndex = mIndex; diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 61c92d3fd..8f2e7977a 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -355,9 +355,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); ptr++; } - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } rendered_decals++; gl_RenderState.SetTextureMode(TM_MODULATE); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index e0e6cf8df..fc44c7896 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -1011,9 +1011,7 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws) ptr++; ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0); ptr++; - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil @@ -1055,9 +1053,7 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws) ptr++; ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0); ptr++; - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } // restore old stencil op. @@ -1158,9 +1154,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo ptr++; ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64); ptr++; - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } if (pushed) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 4d3f4c3f6..71bb2197b 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -295,9 +295,7 @@ void GLFlat::DrawSubsector(subsector_t * sub) ptr++; } } - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } flatvertices += sub->numlines; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 809a516e7..15f9444d4 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -637,9 +637,7 @@ static void FillScreen() ptr++; ptr->Set((float)SCREENWIDTH, (float)SCREENHEIGHT, 0, 0, 0); ptr++; - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index ca32e98a6..98ae66800 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -302,9 +302,7 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_FAN, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); vertexcount += 4; } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 5fca4bb49..a91fa252f 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -174,9 +174,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed ptr++; ptr->Set(x2, y2, 0, fU2, fV2); ptr++; - unsigned int offset; - unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_STRIP, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); } if (tex->GetTransparent() || OverrideShader != 0) { From f5ea31b51810d52642723e626344b5bc05f37ca8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 21 May 2014 00:36:04 +0200 Subject: [PATCH 025/138] - use vertex buffer for all the common 2D rendering functions. --- src/gl/data/gl_vertexbuffer.cpp | 5 +- src/gl/data/gl_vertexbuffer.h | 3 + src/gl/renderer/gl_renderer.cpp | 229 +++++++++++++++++++++++--------- 3 files changed, 172 insertions(+), 65 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index a0f9aa849..8c43d968f 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -49,8 +49,6 @@ #include "gl/data/gl_vertexbuffer.h" -const int BUFFER_SIZE = 2000000; - CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { if (self < -1 || self > 1 || !(gl.flags & RFL_BUFFER_STORAGE)) @@ -105,6 +103,7 @@ FFlatVertexBuffer::FFlatVertexBuffer() { map = NULL; } + mIndex = mCurIndex = 0; } FFlatVertexBuffer::~FFlatVertexBuffer() @@ -296,7 +295,7 @@ void FFlatVertexBuffer::CreateVBO() { CreateFlatVBO(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); - mIndex = vbo_shadowdata.Size(); + mCurIndex = mIndex = vbo_shadowdata.Size(); } else if (sectors) { diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 80db0d64e..806368ab0 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -47,6 +47,8 @@ class FFlatVertexBuffer : public FVertexBuffer void CheckPlanes(sector_t *sector); + const unsigned int BUFFER_SIZE = 2000000; + public: int vbo_arg; TArray vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer @@ -68,6 +70,7 @@ public: unsigned int diff = newofs - mCurIndex; *poffset = mCurIndex; mCurIndex = newofs; + if (mCurIndex >= BUFFER_SIZE) 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. diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index b6d64eeee..71595ffbc 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -53,6 +53,7 @@ #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" @@ -106,6 +107,7 @@ void FGLRenderer::Initialize() gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch); mVBO = new FFlatVertexBuffer; + gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; SetupLevel(); mShaderManager = new FShaderManager; @@ -278,20 +280,36 @@ void FGLRenderer::ClearBorders() gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); - 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(); + if (!gl_usevbo) + { + 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(); + } + else + { + 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); @@ -391,25 +409,8 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) gl_RenderState.SetColor(color); gl_RenderState.EnableAlphaTest(false); 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(); - - if (parms.colorOverlay) + if (!gl_usevbo) { - 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(); - glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(u1, v1); glVertex2d(x, y); @@ -421,6 +422,47 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) glVertex2d(x + w, y + h); glEnd(); } + else + { + 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(); + + if (!gl_usevbo) + { + 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(); + } + else + { + 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); @@ -442,10 +484,20 @@ void FGLRenderer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32 gl_RenderState.EnableTexture(false); gl_RenderState.SetColorAlpha(p, 1.f); gl_RenderState.Apply(); - glBegin(GL_LINES); - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glEnd(); + if (!gl_usevbo) + { + glBegin(GL_LINES); + glVertex2i(x1, y1); + glVertex2i(x2, y2); + glEnd(); + } + else + { + 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); } @@ -460,9 +512,18 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color) gl_RenderState.EnableTexture(false); gl_RenderState.SetColorAlpha(p, 1.f); gl_RenderState.Apply(); - glBegin(GL_POINTS); - glVertex2i(x1, y1); - glEnd(); + if (!gl_usevbo) + { + glBegin(GL_POINTS); + glVertex2i(x1, y1); + glEnd(); + } + else + { + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x1, y1, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS); + } gl_RenderState.EnableTexture(true); } @@ -480,13 +541,24 @@ void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int gl_RenderState.SetColorAlpha(color, damount); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - glVertex2i(x1, y1); - glVertex2i(x1, y1 + h); - glVertex2i(x1 + w, y1 + h); - glVertex2i(x1 + w, y1); - glEnd(); - + if (!gl_usevbo) + { + glBegin(GL_TRIANGLE_FAN); + glVertex2i(x1, y1); + glVertex2i(x1, y1 + h); + glVertex2i(x1 + w, y1 + h); + glVertex2i(x1 + w, y1); + glEnd(); + } + else + { + 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); } @@ -522,12 +594,24 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture * } gl_RenderState.ResetColor(); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_STRIP); - 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(); + if (!gl_usevbo) + { + glBegin(GL_TRIANGLE_STRIP); + 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(); + } + else + { + 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); + } } //========================================================================== @@ -615,20 +699,41 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint float oy = float(originy); gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); - for (i = 0; i < npoints; ++i) + if (!gl_usevbo) { - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) + glBegin(GL_TRIANGLE_FAN); + for (i = 0; i < npoints; ++i) { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; + float u = points[i].X - 0.5f - ox; + float v = points[i].Y - 0.5f - oy; + if (dorotate) + { + float t = u; + u = t * cosrot - v * sinrot; + v = v * cosrot + t * sinrot; + } + glTexCoord2f(u * uscale, v * vscale); + glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0); } - glTexCoord2f(u * uscale, v * vscale); - glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0); + glEnd(); + } + else + { + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (i = 0; i < npoints; ++i) + { + float u = points[i].X - 0.5f - ox; + float v = points[i].Y - 0.5f - oy; + if (dorotate) + { + float t = u; + u = t * cosrot - v * sinrot; + v = v * cosrot + t * sinrot; + } + ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale); + ptr++; + } + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } - glEnd(); } From 0cf37f2e512b4467b9826d54fff623cf5aee2d30 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 21 May 2014 12:36:29 +0200 Subject: [PATCH 026/138] - fixed problem with selecting special shaders. --- src/gl/renderer/gl_renderstate.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 4668bf2b7..7f5fd3b0d 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -129,12 +129,10 @@ bool FRenderState::ApplyShader() { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); } - FShader *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4); - - if (shd != NULL) + else { - activeShader = shd; - shd->Bind(); + activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); + activeShader->Bind(); } int fogset = 0; From 54425ee2efd4de0e8cb501dd214b3c9d6b1ade9e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 21 May 2014 13:40:46 +0200 Subject: [PATCH 027/138] - fixed: Desaturation factor was applied incorrectly. - Also fixed some very strange thing in the shader's desaturate function. For unknown reasons using the 'mix' function there did not work. - fixed: The fog boundary special shader could not be used. --- src/gl/renderer/gl_renderstate.cpp | 4 ++-- wadsrc/static/shaders/glsl/main.fp | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 7f5fd3b0d..673c201b8 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -125,7 +125,7 @@ bool FRenderState::ApplyShader() if (gl.hasGLSL()) { FShader *activeShader; - if (mSpecialEffect > 0) + if (mSpecialEffect > EFF_NONE) { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); } @@ -151,7 +151,7 @@ bool FRenderState::ApplyShader() glColor4fv(mColor.vec); - activeShader->muDesaturation.Set(mDesaturation); + activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); activeShader->muTextureMode.Set(mTextureMode); activeShader->muCameraPos.Set(mCameraPos.vec); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index db5b8cb19..35b355206 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -31,8 +31,13 @@ vec4 desaturate(vec4 texel) { if (uDesaturationFactor > 0.0) { - float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14); - return mix (vec4(gray,gray,gray,texel.a), texel, uDesaturationFactor); + float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14) * uDesaturationFactor; + + vec4 desaturated = vec4(gray,gray,gray,texel.a); + // I have absolutely no idea why this works and 'mix' doesn't... + texel *= (1.0-uDesaturationFactor); + return texel + desaturated; + //return mix (desaturated, texel, uDesaturationFactor); } else { From 39775cc904b34b7470abaef6c483eec5709c1471 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 21 May 2014 15:25:25 +0200 Subject: [PATCH 028/138] - mystery of desaturation shader solved: The old code passed '1-desaturation' to the shader, the new code 'desaturation', so for the 'mix' function to work its arguments must be swapped. --- wadsrc/static/shaders/glsl/main.fp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 35b355206..afd075984 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -31,13 +31,8 @@ vec4 desaturate(vec4 texel) { if (uDesaturationFactor > 0.0) { - float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14) * uDesaturationFactor; - - vec4 desaturated = vec4(gray,gray,gray,texel.a); - // I have absolutely no idea why this works and 'mix' doesn't... - texel *= (1.0-uDesaturationFactor); - return texel + desaturated; - //return mix (desaturated, texel, uDesaturationFactor); + 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 { From a1ec6ab1ba62361e3f9c35ba706369c6953422fa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 24 May 2014 16:53:57 +0200 Subject: [PATCH 029/138] - fixed some Linux warnings. --- src/gl/scene/gl_scene.cpp | 8 +++++--- src/gl/shaders/gl_shader.cpp | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 15f9444d4..a05aadde4 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -747,7 +747,7 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) // for various reasons (performance and keeping the lighting code clean) // we no longer do colormapped textures on pre GL 3.0 hardware and instead do // just a fullscreen overlay to emulate the inverse invulnerability effect or similar fullscreen blends. - if (gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP && gl_fixedcolormap < CM_MAXCOLORMAP) + if (gl_fixedcolormap >= (DWORD)CM_FIRSTSPECIALCOLORMAP && gl_fixedcolormap < (DWORD)CM_MAXCOLORMAP) { FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; @@ -764,13 +764,14 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) g = scm->ColorizeEnd[1]; b = scm->ColorizeEnd[2]; } - } else if (gl_enhanced_nightvision) { if (gl_fixedcolormap == CM_LITE) { - r = 0.375f, g = 1.0f, b = 0.375f; + r = 0.375f; + g = 1.0f; + b = 0.375f; } else if (gl_fixedcolormap >= CM_TORCH) { @@ -782,6 +783,7 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) } else r = g = b = 1.f; } + else r = g = b = 1.f; if (inverse) { diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 35916bd00..994fdbf97 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -400,7 +400,7 @@ void FShaderManager::Clean() { if (gl.hasGLSL()) { - glUseProgram(NULL); + glUseProgram(0); mActiveShader = NULL; for (unsigned int i = 0; i < mTextureEffects.Size(); i++) @@ -446,7 +446,7 @@ void FShaderManager::SetActiveShader(FShader *sh) { if (gl.hasGLSL() && mActiveShader != sh) { - glUseProgram(sh!= NULL? sh->GetHandle() : NULL); + glUseProgram(sh!= NULL? sh->GetHandle() : 0); mActiveShader = sh; } } From c39318f406a12c48d997d6169177edef91e3d320 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 31 May 2014 09:32:17 +0200 Subject: [PATCH 030/138] - use vertex buffer and reuse of data for stencil drawing. A stencil needs to be drawn multiple times with the same polygons so this is a good place to optimize. --- src/gl/models/gl_models.cpp | 1 - src/gl/scene/gl_portal.cpp | 78 ++++++++++---- src/gl/scene/gl_portal.h | 1 + src/gl/scene/gl_vertex.cpp | 189 +++++++++++++++++++-------------- src/gl/scene/gl_wall.h | 1 + src/gl/scene/gl_walls_draw.cpp | 30 ++++++ 6 files changed, 202 insertions(+), 98 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 9c5212468..568a2e3f2 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -68,7 +68,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; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index b49b0027d..18c6dcff5 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -54,6 +54,7 @@ #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" @@ -138,33 +139,74 @@ void GLPortal::ClearScreen() //----------------------------------------------------------------------------- void GLPortal::DrawPortalStencil() { - for(unsigned int i=0;i 1) + { + // 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(); + } } - - if (NeedCap() && lines.Size() > 1) + else { - // 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(); + if (mPrimIndices.Size() == 0) + { + bool cap = NeedCap() && lines.Size() > 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]); + } + } + for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) + { + glDrawArrays(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]); + } } } + + + //----------------------------------------------------------------------------- // // Start diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index b04873ec8..970fc3523 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -104,6 +104,7 @@ private: unsigned char clipsave; GLPortal *NextPortal; TArray savedmapsection; + TArray mPrimIndices; protected: TArray lines; diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index 03f7df520..b3ee9c8b5 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -89,6 +89,116 @@ void GLWall::SplitUpperEdge(texcoord * tcs) vertexcount += sidedef->numsegs-1; } +//========================================================================== +// +// Split upper edge of wall +// +//========================================================================== + +void GLWall::SplitLowerEdge(texcoord * tcs) +{ + if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; + + side_t *sidedef = seg->sidedef; + float polyw = glseg.fracright - glseg.fracleft; + float facu = (tcs[3].u - tcs[0].u) / polyw; + float facv = (tcs[3].v - tcs[0].v) / polyw; + float facb = (zbottom[1] - zbottom[0]) / polyw; + float facc = (zceil[1] - zceil[0]) / polyw; + float facf = (zfloor[1] - zfloor[0]) / polyw; + + for (int i = sidedef->numsegs-2; i >= 0; i--) + { + seg_t *cseg = sidedef->segs[i]; + float sidefrac = cseg->sidefrac; + if (sidefrac >= glseg.fracright) continue; + if (sidefrac <= glseg.fracleft) return; + + 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); + } + vertexcount += sidedef->numsegs-1; +} + +//========================================================================== +// +// Split left edge of wall +// +//========================================================================== + +void GLWall::SplitLeftEdge(texcoord * tcs) +{ + if (vertexes[0]==NULL) return; + + vertex_t * vi=vertexes[0]; + + if (vi->numheights) + { + 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; + + 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); + i++; + } + vertexcount+=i; + } +} + +//========================================================================== +// +// Split right edge of wall +// +//========================================================================== + +void GLWall::SplitRightEdge(texcoord * tcs) +{ + if (vertexes[1]==NULL) return; + + vertex_t * vi=vertexes[1]; + + if (vi->numheights) + { + 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; + + 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); + i--; + } + vertexcount+=i; + } +} + + +//========================================================================== +// +// same for vertex buffer mode +// +//========================================================================== + +//========================================================================== +// +// Split upper edge of wall +// +//========================================================================== + void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) { if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; @@ -126,33 +236,6 @@ void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) // //========================================================================== -void GLWall::SplitLowerEdge(texcoord * tcs) -{ - if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; - - side_t *sidedef = seg->sidedef; - float polyw = glseg.fracright - glseg.fracleft; - float facu = (tcs[3].u - tcs[0].u) / polyw; - float facv = (tcs[3].v - tcs[0].v) / polyw; - float facb = (zbottom[1] - zbottom[0]) / polyw; - float facc = (zceil[1] - zceil[0]) / polyw; - float facf = (zfloor[1] - zfloor[0]) / polyw; - - for (int i = sidedef->numsegs-2; i >= 0; i--) - { - seg_t *cseg = sidedef->segs[i]; - float sidefrac = cseg->sidefrac; - if (sidefrac >= glseg.fracright) continue; - if (sidefrac <= glseg.fracleft) return; - - 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); - } - vertexcount += sidedef->numsegs-1; -} - void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) { if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; @@ -190,32 +273,6 @@ void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) // //========================================================================== -void GLWall::SplitLeftEdge(texcoord * tcs) -{ - if (vertexes[0]==NULL) return; - - vertex_t * vi=vertexes[0]; - - if (vi->numheights) - { - 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; - - 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); - i++; - } - vertexcount+=i; - } -} - void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) { if (vertexes[0] == NULL) return; @@ -251,32 +308,6 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) // //========================================================================== -void GLWall::SplitRightEdge(texcoord * tcs) -{ - if (vertexes[1]==NULL) return; - - vertex_t * vi=vertexes[1]; - - if (vi->numheights) - { - 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; - - 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); - i--; - } - vertexcount+=i; - } -} - void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr) { if (vertexes[1] == NULL) return; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index a9d0c1087..dd1365193 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -160,6 +160,7 @@ private: void SetupLights(); bool PrepareLight(texcoord * tcs, ADynamicLight * light); void RenderWall(int textured, float * color2, ADynamicLight * light=NULL); + void GetPrimitive(unsigned int *store); void FloodPlane(int pass); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 98ae66800..9c5baae6a 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -309,6 +309,36 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) } +//========================================================================== +// +// Gets the vertex data for rendering a stencil which needs to be +// repeated several times +// +//========================================================================== + +void GLWall::GetPrimitive(unsigned int *store) +{ + static texcoord tcs[4] = { 0, 0, 0, 0 }; + bool split = (gl_seamless && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + + ptr->Set(glseg.x1, zbottom[0], glseg.y1, 0, 0); + ptr++; + if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr); + ptr->Set(glseg.x1, ztop[0], glseg.y1, 0, 0); + ptr++; + if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr); + ptr->Set(glseg.x2, ztop[1], glseg.y2, 0, 0); + ptr++; + if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr); + ptr->Set(glseg.x2, zbottom[1], glseg.y2, 0, 0); + ptr++; + if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); + store[1] = GLRenderer->mVBO->GetCount(ptr, &store[0]); + vertexcount += 4; + } + //========================================================================== // // From 8d9a90cd229edb2ba04e1c82cfd9e24f82be229c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jun 2014 01:24:28 +0200 Subject: [PATCH 031/138] - rewrote sky dome rendering to use a static vertex buffer if not on OpenGL 2.x. --- src/gl/data/gl_vertexbuffer.cpp | 1 + src/gl/data/gl_vertexbuffer.h | 43 ++++ src/gl/models/gl_voxels.cpp | 2 +- src/gl/renderer/gl_renderer.cpp | 3 + src/gl/renderer/gl_renderer.h | 2 + src/gl/renderer/gl_renderstate.h | 6 + src/gl/scene/gl_skydome.cpp | 331 +++++++++++++++++-------------- src/gl/system/gl_interface.cpp | 9 +- 8 files changed, 244 insertions(+), 153 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 8c43d968f..f7b4bdbf2 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -325,6 +325,7 @@ void FFlatVertexBuffer::BindVBO() glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); } } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 806368ab0..dfa2afbc3 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -95,4 +95,47 @@ private: }; + +struct FSkyVertex +{ + float x, y, z, u, v; + PalEntry color; +}; + +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, bool color); + +public: + + FSkyVertexBuffer(); + virtual ~FSkyVertexBuffer(); + virtual void BindVBO(); + void RenderDome(FMaterial *tex, int mode); + +}; + +#define VSO ((FSkyVertex*)NULL) + + #endif \ No newline at end of file diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index 99b565fc5..3a04cb5ca 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -284,7 +284,7 @@ void FVoxelVertexBuffer::BindVBO() glTexCoordPointer(2,GL_FLOAT, sizeof(FVoxelVertex), &VVO->u); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_INDEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 71595ffbc..1d1535d9a 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -94,6 +94,7 @@ 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; @@ -107,6 +108,7 @@ void FGLRenderer::Initialize() gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch); mVBO = new FFlatVertexBuffer; + mSkyVBO = new FSkyVertexBuffer; gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; SetupLevel(); @@ -122,6 +124,7 @@ FGLRenderer::~FGLRenderer() //if (mThreadManager != NULL) delete mThreadManager; if (mShaderManager != NULL) delete mShaderManager; if (mVBO != NULL) delete mVBO; + if (mSkyVBO != NULL) delete mSkyVBO; if (glpart2) delete glpart2; if (glpart) delete glpart; if (mirrortexture) delete mirrortexture; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index fde918d16..77a38e7ae 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -9,6 +9,7 @@ struct particle_t; class FCanvasTexture; class FFlatVertexBuffer; +class FSkyVertexBuffer; class OpenGLFrameBuffer; struct FDrawInfo; struct pspdef_t; @@ -69,6 +70,7 @@ public: FVector3 mCameraPos; FFlatVertexBuffer *mVBO; + FSkyVertexBuffer *mSkyVBO; FGLRenderer(OpenGLFrameBuffer *fb); diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 79e277948..8bcedcac7 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -100,6 +100,12 @@ public: mVertexBuffer = vb; } + void ResetVertexBuffer() + { + // forces rebinding with the next 'apply' call. + mCurrentVertexBuffer = NULL; + } + void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mColor.Set(r, g, b, a); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 5492a1649..7e33903c4 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,171 +64,208 @@ // //----------------------------------------------------------------------------- -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 bool skymirror; - -#define SKYHEMI_UPPER 0x1 -#define SKYHEMI_LOWER 0x2 - - //----------------------------------------------------------------------------- // // // //----------------------------------------------------------------------------- -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(); +} + +FSkyVertexBuffer::~FSkyVertexBuffer() +{ +} + +void FSkyVertexBuffer::BindVBO() +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x); + glTexCoordPointer(2, GL_FLOAT, sizeof(FSkyVertex), &VSO->u); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSkyVertex), &VSO->color); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); +} + + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +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. { - // this must not use the renderstate because it's inside a primitive. - glColor4f(1.f, 1.f, 1.f, 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; - - // Draw the cap as one solid color polygon - if (!foglayer) + // The total number of triangles per hemisphere can be calculated + // as follows: rows * columns * 2 + 2 (for the top cap). + for (r = 0; r < mRows; r++) { - columns = 4 * (gl_sky_detail > 0 ? gl_sky_detail : 1); - foglayer=true; - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - - - if (!secondlayer) + mPrimStart.Push(mVertices.Size()); + for (c = 0; c <= mColumns; c++) { - glBegin(GL_TRIANGLE_FAN); - for(c = 0; c < columns; c++) - { - SkyVertex(1, c); - } - glEnd(); - gl_RenderState.SetObjectColor(0xffffffff); // unset the cap's color + SkyVertex(r + yflip, c, yflip); + SkyVertex(r + 1 - yflip, c, yflip); } + } +} - gl_RenderState.EnableTexture(true); - foglayer=false; - gl_RenderState.Apply(); +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FSkyVertexBuffer::CreateDome() +{ + if (gl.version < 3.0f) + { + mColumns = 64; + mRows = 4; } else { - gl_RenderState.Apply(); - columns=4; // no need to do more! - glBegin(GL_TRIANGLE_FAN); - for(c = 0; c < columns; c++) + mColumns = 128; + mRows = 4; + } + CreateSkyHemisphere(SKYHEMI_UPPER); + CreateSkyHemisphere(SKYHEMI_LOWER); + mPrimStart.Push(mVertices.Size()); + if (gl.version >= 3.f) + { + // we won't bother with a real buffer for GL 2.x because the lack of shaders and therefore the objectColor uniform will require different handling. + // It'd also prevent changing to core features only. + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], GL_STATIC_DRAW); + } +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FSkyVertexBuffer::RenderRow(int prim, int row, bool color) +{ + if (gl.version < 3.f) + { + glBegin(prim); + for (unsigned int i = mPrimStart[row]; i < mPrimStart[row + 1]; i++) { - SkyVertex(0, c); + if (color) glColor4ubv((GLubyte*)&mVertices[i].color); + glTexCoord2fv(&mVertices[i].u); + glVertex3fv(&mVertices[i].x); } 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++) + else { - if (yflip) + glDrawArrays(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]); + } +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) +{ + int rc = mRows + 1; + + if (mode != SKYMODE_SECONDLAYER) + { + if (mode == SKYMODE_MAINLAYER && tex != NULL) { - 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(); + PalEntry pe = tex->tex->GetSkyCapColor(false); + gl_RenderState.SetObjectColor(pe); + gl_RenderState.EnableTexture(false); } - else + gl_RenderState.Apply(); + RenderRow(GL_TRIANGLE_FAN, 0, false); + + if (mode == SKYMODE_MAINLAYER && tex != NULL) { - 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(); + PalEntry pe = tex->tex->GetSkyCapColor(true); + gl_RenderState.SetObjectColor(pe); } + gl_RenderState.Apply(); + RenderRow(GL_TRIANGLE_FAN, rc, false); + if (mode == SKYMODE_MAINLAYER && tex != NULL) + { + gl_RenderState.EnableTexture(true); + } + } + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.Apply(); + for (int i = 1; i <= mRows; i++) + { + RenderRow(GL_TRIANGLE_STRIP, i, true); + RenderRow(GL_TRIANGLE_STRIP, rc + i, true); } } @@ -237,12 +275,11 @@ static void RenderSkyHemisphere(int hemi, bool mirror) // // //----------------------------------------------------------------------------- -CVAR(Float, skyoffset, 0, 0) // for testing -static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float y_offset, bool mirror) +void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, int mode) { int texh = 0; - bool texscale = false; + int texw = 0; // 57 world units roughly represent one sky texel for the glTranslate call. const float skyoffsetfactor = 57; @@ -255,8 +292,9 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float texh = tex->TextureHeight(GLUSE_TEXTURE); glRotatef(-180.0f+x_offset, 0.f, 1.f, 0.f); - yAdd = y_offset/texh; + float xscale = 1024.f / float(texw); + float yscale = 1.f; if (texh < 200) { glTranslatef(0.f, -1250.f, 0.f); @@ -271,37 +309,25 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float { 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; + yscale = 240.f / texh; } + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + glScalef(mirror? -xscale : xscale, yscale, 1.f); + glTranslatef(1.f, y_offset / texh, 1.f); + glMatrixMode(GL_MODELVIEW); } - if (tex && !secondlayer) - { - PalEntry pe = tex->tex->GetSkyCapColor(false); - gl_RenderState.SetObjectColor(pe); - } + GLRenderer->mSkyVBO->RenderDome(tex, mode); - RenderSkyHemisphere(SKYHEMI_UPPER, mirror); - - if (tex && !secondlayer) - { - PalEntry pe = tex->tex->GetSkyCapColor(true); - gl_RenderState.SetObjectColor(pe); - } - - RenderSkyHemisphere(SKYHEMI_LOWER, mirror); - if (texscale) + if (tex) { glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } - if (tex) glPopMatrix(); } @@ -527,12 +553,16 @@ void GLSkyPortal::DrawContents() } else { + if (gl.version >= 3.f) + { + 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); + RenderDome(origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER); gl_RenderState.SetTextureMode(TM_MODULATE); } @@ -541,19 +571,22 @@ void GLSkyPortal::DrawContents() if (origin->doublesky && origin->texture[1]) { - secondlayer=true; - RenderDome(FNullTextureID(), origin->texture[1], origin->x_offset[1], origin->y_offset, false); - 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)) { gl_RenderState.EnableTexture(false); - foglayer=true; gl_RenderState.SetColorAlpha(FadeColor, skyfog / 255.0f); - RenderDome(FNullTextureID(), NULL, 0, 0, false); + // for the fog layer we must temporarily disable the color part of the vertex buffer. + glDisableClientState(GL_COLOR_ARRAY); + RenderDome(NULL, 0, 0, false, FSkyVertexBuffer::SKYMODE_FOGLAYER); + glEnableClientState(GL_COLOR_ARRAY); gl_RenderState.EnableTexture(true); - foglayer=false; + } + if (gl.version >= 3.f) + { + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } } glPopMatrix(); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 5f35c4ec2..e0d363446 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -122,7 +122,10 @@ 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) @@ -139,9 +142,9 @@ void gl_LoadExtensions() if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC; if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; - gl.version = strtod((char*)glGetString(GL_VERSION), NULL); + gl.version = strtod(version, NULL); gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL); - if (Args->CheckParm("-noshader")) gl.glslversion = 0.0f; + if (gl.version < 3.f) gl.glslversion = 0.f; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); From 5e22c82e79a600c7031d2c86442ab38d857db597 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jun 2014 10:38:30 +0200 Subject: [PATCH 032/138] - use buffer for rendering the sky on all GL versions since the differences for making GL2.0 work are rather small. --- src/gl/data/gl_vertexbuffer.h | 11 +++ src/gl/scene/gl_skydome.cpp | 123 ++++++++++++++-------------------- 2 files changed, 61 insertions(+), 73 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index dfa2afbc3..d7aeab9a2 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -100,6 +100,17 @@ 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 diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 7e33903c4..0f5e86284 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -180,26 +180,32 @@ void FSkyVertexBuffer::CreateSkyHemisphere(int hemi) void FSkyVertexBuffer::CreateDome() { - if (gl.version < 3.0f) - { - mColumns = 64; - mRows = 4; - } - else - { - mColumns = 128; - mRows = 4; - } + // 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()); - if (gl.version >= 3.f) - { - // we won't bother with a real buffer for GL 2.x because the lack of shaders and therefore the objectColor uniform will require different handling. - // It'd also prevent changing to core features only. - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], GL_STATIC_DRAW); - } + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], GL_STATIC_DRAW); } //----------------------------------------------------------------------------- @@ -208,23 +214,9 @@ void FSkyVertexBuffer::CreateDome() // //----------------------------------------------------------------------------- -void FSkyVertexBuffer::RenderRow(int prim, int row, bool color) +inline void FSkyVertexBuffer::RenderRow(int prim, int row) { - if (gl.version < 3.f) - { - glBegin(prim); - for (unsigned int i = mPrimStart[row]; i < mPrimStart[row + 1]; i++) - { - if (color) glColor4ubv((GLubyte*)&mVertices[i].color); - glTexCoord2fv(&mVertices[i].u); - glVertex3fv(&mVertices[i].x); - } - glEnd(); - } - else - { - glDrawArrays(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]); - } + glDrawArrays(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]); } //----------------------------------------------------------------------------- @@ -237,35 +229,29 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) { int rc = mRows + 1; - if (mode != SKYMODE_SECONDLAYER) + if (mode == SKYMODE_MAINLAYER && tex != NULL) { - if (mode == SKYMODE_MAINLAYER && tex != NULL) - { - PalEntry pe = tex->tex->GetSkyCapColor(false); - gl_RenderState.SetObjectColor(pe); - gl_RenderState.EnableTexture(false); - } + // if there's no shader we cannot use the default color from the buffer because the object color is part of the preset vertex attribute. + if (!gl.hasGLSL()) glDisableClientState(GL_COLOR_ARRAY); + PalEntry pe = tex->tex->GetSkyCapColor(false); + gl_RenderState.SetObjectColor(pe); + gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); - RenderRow(GL_TRIANGLE_FAN, 0, false); + RenderRow(GL_TRIANGLE_FAN, 0); - if (mode == SKYMODE_MAINLAYER && tex != NULL) - { - PalEntry pe = tex->tex->GetSkyCapColor(true); - gl_RenderState.SetObjectColor(pe); - } + PalEntry pe = tex->tex->GetSkyCapColor(true); + gl_RenderState.SetObjectColor(pe); gl_RenderState.Apply(); - RenderRow(GL_TRIANGLE_FAN, rc, false); - if (mode == SKYMODE_MAINLAYER && tex != NULL) - { - gl_RenderState.EnableTexture(true); - } + RenderRow(GL_TRIANGLE_FAN, rc); + gl_RenderState.EnableTexture(true); + if (!gl.hasGLSL()) glEnableClientState(GL_COLOR_ARRAY); } gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.Apply(); for (int i = 1; i <= mRows; i++) { - RenderRow(GL_TRIANGLE_STRIP, i, true); - RenderRow(GL_TRIANGLE_STRIP, rc + i, true); + RenderRow(GL_TRIANGLE_STRIP, i); + RenderRow(GL_TRIANGLE_STRIP, rc + i); } } @@ -525,18 +511,12 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool void GLSkyPortal::DrawContents() { bool drawBoth = false; - 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) - { - FadeColor = origin->fadecolor; - } - gl_RenderState.ResetColor(); gl_RenderState.EnableFog(false); gl_RenderState.EnableAlphaTest(false); @@ -553,10 +533,7 @@ void GLSkyPortal::DrawContents() } else { - if (gl.version >= 3.f) - { - gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO); - } + gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO); if (origin->texture[0]==origin->texture[1] && origin->doublesky) origin->doublesky=false; if (origin->texture[0]) @@ -574,20 +551,20 @@ void GLSkyPortal::DrawContents() 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); - gl_RenderState.SetColorAlpha(FadeColor, skyfog / 255.0f); - // for the fog layer we must temporarily disable the color part of the vertex buffer. - glDisableClientState(GL_COLOR_ARRAY); - RenderDome(NULL, 0, 0, false, FSkyVertexBuffer::SKYMODE_FOGLAYER); - glEnableClientState(GL_COLOR_ARRAY); + gl_RenderState.SetObjectColor(FadeColor); + gl_RenderState.Apply(); + if (!gl.hasGLSL()) glDisableClientState(GL_COLOR_ARRAY); + glDrawArrays(GL_TRIANGLES, 0, 12); + if (!gl.hasGLSL()) glEnableClientState(GL_COLOR_ARRAY); gl_RenderState.EnableTexture(true); } - if (gl.version >= 3.f) - { - gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); - } + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } glPopMatrix(); glset.lightmode = oldlightmode; From 0ce6b406725407420df2a1fd10bd549d3b0e312b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jun 2014 14:58:17 +0200 Subject: [PATCH 033/138] - fixed compile error in gl_skydome.cpp - disable GL_ARB_buffer_storage when a -glversion parameter less than 4.0 is given. According to the spec this extension requires 4.0 so if emulating something lower it should not be used. --- src/gl/scene/gl_skydome.cpp | 3 ++- src/gl/system/gl_interface.cpp | 9 ++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 0f5e86284..1a8794c58 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -229,6 +229,7 @@ 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) { // if there's no shader we cannot use the default color from the buffer because the object color is part of the preset vertex attribute. @@ -239,7 +240,7 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) gl_RenderState.Apply(); RenderRow(GL_TRIANGLE_FAN, 0); - PalEntry pe = tex->tex->GetSkyCapColor(true); + pe = tex->tex->GetSkyCapColor(true); gl_RenderState.SetObjectColor(pe); gl_RenderState.Apply(); RenderRow(GL_TRIANGLE_FAN, rc); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index e0d363446..ac34bd2c1 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -132,6 +132,9 @@ void gl_LoadExtensions() { I_FatalError("Unsupported OpenGL version.\nAt least GL 2.0 is required to run " GAMENAME ".\n"); } + gl.version = strtod(version, NULL); + gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL); + if (gl.version < 3.f) gl.glslversion = 0.f; // This loads any function pointers and flags that require a vaild render context to // initialize properly @@ -140,11 +143,7 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; - - gl.version = strtod(version, NULL); - gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL); - if (gl.version < 3.f) gl.glslversion = 0.f; + if (gl.version >= 4.f && CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); From 5b302ed3a6157acb56820c0871b479aba7abd072 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jun 2014 15:16:33 +0200 Subject: [PATCH 034/138] - added benchmarking calls for glDrawArrays to see how well issunig draw calls performs on different hardware. --- src/gl/data/gl_vertexbuffer.h | 9 +++++++-- src/gl/scene/gl_flats.cpp | 2 ++ src/gl/scene/gl_sprite.cpp | 3 +-- src/gl/utility/gl_clock.cpp | 6 ++++-- src/gl/utility/gl_clock.h | 1 + 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index d7aeab9a2..0862106d7 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -2,6 +2,7 @@ #define __VERTEXBUFFER_H #include "tarray.h" +#include "gl/utility/gl_clock.h" struct vertex_t; struct secplane_t; @@ -74,11 +75,15 @@ public: 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 RenderCurrent(FFlatVertex *newptr, unsigned int primtype) + void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL) { unsigned int offset; unsigned int count = GetCount(newptr, &offset); + drawcalls.Clock(); glDrawArrays(primtype, offset, count); + drawcalls.Unclock(); + if (poffset) *poffset = offset; + if (pcount) *pcount = count; } #endif void Reset() @@ -135,7 +140,7 @@ private: void SkyVertex(int r, int c, bool yflip); void CreateSkyHemisphere(int hemi); void CreateDome(); - void RenderRow(int prim, int row, bool color); + void RenderRow(int prim, int row); public: diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 71bb2197b..39731bf74 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -332,7 +332,9 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + drawcalls.Clock(); glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); + drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 63c7bd46b..e36dd4b0e 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -300,8 +300,7 @@ void GLSprite::Draw(int pass) ptr++; ptr->Set(v4[0], v4[1], v4[2], ur, vb); ptr++; - count = GLRenderer->mVBO->GetCount(ptr, &offset); - glDrawArrays(GL_TRIANGLE_STRIP, offset, count); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); } if (foglayer) diff --git a/src/gl/utility/gl_clock.cpp b/src/gl/utility/gl_clock.cpp index 7759f5582..d8d3c28be 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) diff --git a/src/gl/utility/gl_clock.h b/src/gl/utility/gl_clock.h index cb9d0173e..604a40a02 100644 --- a/src/gl/utility/gl_clock.h +++ b/src/gl/utility/gl_clock.h @@ -108,6 +108,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; From 3644073bbd57161c571b666b0cdcade298637c8a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 01:14:41 +0200 Subject: [PATCH 035/138] - use a software buffer for immediate mode rendering. This allows using the regular buffer code to collect data for both render modes and allows removal of a lot of duplicated code. --- src/gl/data/gl_vertexbuffer.cpp | 26 +++- src/gl/data/gl_vertexbuffer.h | 27 +++- src/gl/renderer/gl_renderer.cpp | 229 +++++++++----------------------- src/gl/scene/gl_decal.cpp | 24 +--- src/gl/scene/gl_drawinfo.cpp | 105 +++++---------- src/gl/scene/gl_flats.cpp | 73 +++------- src/gl/scene/gl_scene.cpp | 32 ++--- src/gl/scene/gl_sprite.cpp | 68 ++-------- src/gl/scene/gl_vertex.cpp | 142 -------------------- src/gl/scene/gl_wall.h | 7 +- src/gl/scene/gl_walls_draw.cpp | 103 +++++--------- src/gl/scene/gl_weapon.cpp | 32 ++--- 12 files changed, 232 insertions(+), 636 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index f7b4bdbf2..8093a57a0 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -53,7 +53,7 @@ CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA { if (self < -1 || self > 1 || !(gl.flags & RFL_BUFFER_STORAGE)) { - self = 0; + if (self != 0) self = 0; } else if (self == -1) { @@ -101,7 +101,8 @@ FFlatVertexBuffer::FFlatVertexBuffer() } else { - map = NULL; + vbo_shadowdata.Reserve(BUFFER_SIZE); + map = &vbo_shadowdata[0]; } mIndex = mCurIndex = 0; } @@ -113,6 +114,25 @@ FFlatVertexBuffer::~FFlatVertexBuffer() glBindBuffer(GL_ARRAY_BUFFER, 0); } +//========================================================================== +// +// Renders the buffer's contents with immediate mode functions +// This is here so that the immediate mode fallback does not need +// to double all rendering code and can instead reuse the buffer-based version +// +//========================================================================== + +void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count) +{ + glBegin(primtype); + for (unsigned int i = 0; i < count; i++) + { + glTexCoord2fv(&map[offset + i].u); + glVertex3fv(&map[offset + i].x); + } + glEnd(); +} + //========================================================================== // // Initialize a single vertex @@ -369,7 +389,7 @@ void FFlatVertexBuffer::CheckPlanes(sector_t *sector) void FFlatVertexBuffer::CheckUpdate(sector_t *sector) { - if (vbo_arg == 2) + if (gl.flags & RFL_BUFFER_STORAGE) { CheckPlanes(sector); sector_t *hs = sector->GetHeightSec(); diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 0862106d7..50ddd7d13 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -3,6 +3,7 @@ #include "tarray.h" #include "gl/utility/gl_clock.h" +#include "gl/system/gl_interface.h" struct vertex_t; struct secplane_t; @@ -43,6 +44,7 @@ struct FFlatVertex class FFlatVertexBuffer : public FVertexBuffer { FFlatVertex *map; + FFlatVertex mDrawBuffer[1000]; unsigned int mIndex; unsigned int mCurIndex; @@ -50,9 +52,10 @@ class FFlatVertexBuffer : public FVertexBuffer const unsigned int BUFFER_SIZE = 2000000; + void ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count); + public: - int vbo_arg; - TArray vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer + 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(); @@ -67,6 +70,7 @@ public: } unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset) { + unsigned int newofs = (unsigned int)(newptr - map); unsigned int diff = newofs - mCurIndex; *poffset = mCurIndex; @@ -75,16 +79,29 @@ public: 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); - drawcalls.Clock(); - glDrawArrays(primtype, offset, count); - drawcalls.Unclock(); + RenderArray(primtype, offset, count); if (poffset) *poffset = offset; if (pcount) *pcount = count; } + #endif void Reset() { diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 1d1535d9a..78ec2e34e 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -283,36 +283,17 @@ void FGLRenderer::ClearBorders() gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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); @@ -412,28 +393,13 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) gl_RenderState.SetColor(color); gl_RenderState.EnableAlphaTest(false); gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + + 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) { @@ -443,28 +409,12 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) gl_RenderState.SetColor(PalEntry(parms.colorOverlay)); gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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); @@ -487,20 +437,12 @@ void FGLRenderer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32 gl_RenderState.EnableTexture(false); gl_RenderState.SetColorAlpha(p, 1.f); gl_RenderState.Apply(); - if (!gl_usevbo) - { - glBegin(GL_LINES); - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glEnd(); - } - else - { - 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); - } + + 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); } @@ -515,18 +457,11 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color) gl_RenderState.EnableTexture(false); gl_RenderState.SetColorAlpha(p, 1.f); gl_RenderState.Apply(); - if (!gl_usevbo) - { - glBegin(GL_POINTS); - glVertex2i(x1, y1); - glEnd(); - } - else - { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - ptr->Set(x1, y1, 0, 0, 0); ptr++; - GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS); - } + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + ptr->Set(x1, y1, 0, 0, 0); ptr++; + GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS); + gl_RenderState.EnableTexture(true); } @@ -544,24 +479,13 @@ void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int gl_RenderState.SetColorAlpha(color, damount); gl_RenderState.Apply(); - if (!gl_usevbo) - { - glBegin(GL_TRIANGLE_FAN); - glVertex2i(x1, y1); - glVertex2i(x1, y1 + h); - glVertex2i(x1 + w, y1 + h); - glVertex2i(x1 + w, y1); - glEnd(); - } - else - { - 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); - } + 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); } @@ -597,24 +521,13 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture * } gl_RenderState.ResetColor(); gl_RenderState.Apply(); - if (!gl_usevbo) - { - glBegin(GL_TRIANGLE_STRIP); - 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(); - } - else - { - 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); - } + + 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); } //========================================================================== @@ -702,41 +615,21 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint float oy = float(originy); gl_RenderState.Apply(); - if (!gl_usevbo) + + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (i = 0; i < npoints; ++i) { - glBegin(GL_TRIANGLE_FAN); - for (i = 0; i < npoints; ++i) + float u = points[i].X - 0.5f - ox; + float v = points[i].Y - 0.5f - oy; + if (dorotate) { - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - glTexCoord2f(u * uscale, v * vscale); - glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0); + float t = u; + u = t * cosrot - v * sinrot; + v = v * cosrot + t * sinrot; } - glEnd(); - } - else - { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - for (i = 0; i < npoints; ++i) - { - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale); - ptr++; - } - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale); + ptr++; } + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); } diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 8f2e7977a..e6d5c144f 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -337,26 +337,14 @@ void GLWall::DrawDecal(DBaseDecal *decal) else gl_RenderState.AlphaFunc(GL_GREATER, 0.f); gl_RenderState.Apply(); - if (!gl_usevbo) + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + for (i = 0; i < 4; i++) { - glBegin(GL_TRIANGLE_FAN); - for (i = 0; i < 4; i++) - { - glTexCoord2f(dv[i].u, dv[i].v); - glVertex3f(dv[i].x, dv[i].z, dv[i].y); - } - glEnd(); - } - else - { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - for (i = 0; i < 4; i++) - { - ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); - ptr++; - } - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); + ptr++; } + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + rendered_decals++; gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.SetObjectColor(0xffffffff); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index fc44c7896..8c620d93e 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -991,28 +991,17 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws) glDepthMask(true); gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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 @@ -1033,28 +1022,16 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws) gl_RenderState.ResetColor(); gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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); @@ -1126,36 +1103,16 @@ 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); - if (!gl_usevbo) - { - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(px1 / 64, -py1 / 64); - glVertex3f(px1, planez, py1); - - 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(); - } - else - { - 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); - } + 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); if (pushed) { diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 39731bf74..59d4192e7 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -239,64 +239,35 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) void GLFlat::DrawSubsector(subsector_t * sub) { - if (!gl_usevbo) + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + if (plane.plane.a | plane.plane.b) { - glBegin(GL_TRIANGLE_FAN); - - if (plane.plane.a | plane.plane.b) + for (unsigned int k = 0; k < sub->numlines; k++) { - for (unsigned int k = 0; k < sub->numlines; k++) - { - 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); - } + 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++; } - else - { - float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz; - for (unsigned int k = 0; k < sub->numlines; k++) - { - vertex_t *vt = sub->firstline[k].v1; - glTexCoord2f(vt->fx / 64.f, -vt->fy / 64.f); - glVertex3f(vt->fx, zc, vt->fy); - } - } - glEnd(); } else { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - if (plane.plane.a | plane.plane.b) + float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz; + for (unsigned int k = 0; k < sub->numlines; k++) { - 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++; - } + 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++; } - 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); } + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); flatvertices += sub->numlines; flatprimitives++; @@ -332,9 +303,9 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); - drawcalls.Clock(); + //drawcalls.Clock(); glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); - drawcalls.Unclock(); + //drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index a05aadde4..8f8d50532 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -617,28 +617,16 @@ static void FillScreen() gl_RenderState.EnableAlphaTest(false); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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); } //========================================================================== diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index e36dd4b0e..00f2ccada 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -269,39 +269,16 @@ void GLSprite::Draw(int pass) FFlatVertex *ptr; unsigned int offset, count; - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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) { @@ -311,30 +288,7 @@ 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(); - - if (!gl_usevbo) - { - 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(); - } - else - { - glDrawArrays(GL_TRIANGLE_STRIP, offset, count); - } + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); gl_RenderState.SetFixedColormap(CM_DEFAULT); } } diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index b3ee9c8b5..c0f21adce 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -54,144 +54,6 @@ #include "gl/utility/gl_templates.h" EXTERN_CVAR(Bool, gl_seamless) -extern int vertexcount; - -//========================================================================== -// -// Split upper edge of wall -// -//========================================================================== - -void GLWall::SplitUpperEdge(texcoord * tcs) -{ - if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; - - side_t *sidedef = seg->sidedef; - float polyw = glseg.fracright - glseg.fracleft; - float facu = (tcs[2].u - tcs[1].u) / polyw; - float facv = (tcs[2].v - tcs[1].v) / polyw; - float fact = (ztop[1] - ztop[0]) / polyw; - float facc = (zceil[1] - zceil[0]) / polyw; - float facf = (zfloor[1] - zfloor[0]) / polyw; - - for (int i=0; i < sidedef->numsegs - 1; i++) - { - seg_t *cseg = sidedef->segs[i]; - float sidefrac = cseg->sidefrac; - if (sidefrac <= glseg.fracleft) continue; - if (sidefrac >= glseg.fracright) return; - - 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); - } - vertexcount += sidedef->numsegs-1; -} - -//========================================================================== -// -// Split upper edge of wall -// -//========================================================================== - -void GLWall::SplitLowerEdge(texcoord * tcs) -{ - if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return; - - side_t *sidedef = seg->sidedef; - float polyw = glseg.fracright - glseg.fracleft; - float facu = (tcs[3].u - tcs[0].u) / polyw; - float facv = (tcs[3].v - tcs[0].v) / polyw; - float facb = (zbottom[1] - zbottom[0]) / polyw; - float facc = (zceil[1] - zceil[0]) / polyw; - float facf = (zfloor[1] - zfloor[0]) / polyw; - - for (int i = sidedef->numsegs-2; i >= 0; i--) - { - seg_t *cseg = sidedef->segs[i]; - float sidefrac = cseg->sidefrac; - if (sidefrac >= glseg.fracright) continue; - if (sidefrac <= glseg.fracleft) return; - - 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); - } - vertexcount += sidedef->numsegs-1; -} - -//========================================================================== -// -// Split left edge of wall -// -//========================================================================== - -void GLWall::SplitLeftEdge(texcoord * tcs) -{ - if (vertexes[0]==NULL) return; - - vertex_t * vi=vertexes[0]; - - if (vi->numheights) - { - 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; - - 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); - i++; - } - vertexcount+=i; - } -} - -//========================================================================== -// -// Split right edge of wall -// -//========================================================================== - -void GLWall::SplitRightEdge(texcoord * tcs) -{ - if (vertexes[1]==NULL) return; - - vertex_t * vi=vertexes[1]; - - if (vi->numheights) - { - 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; - - 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); - i--; - } - vertexcount+=i; - } -} - - -//========================================================================== -// -// same for vertex buffer mode -// -//========================================================================== //========================================================================== // @@ -227,7 +89,6 @@ void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr) ptr->v = tcs[1].v + facv * fracfac; ptr++; } - vertexcount += sidedef->numsegs - 1; } //========================================================================== @@ -264,7 +125,6 @@ void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr) ptr->v = tcs[0].v + facv * fracfac; ptr++; } - vertexcount += sidedef->numsegs - 1; } //========================================================================== @@ -298,7 +158,6 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr) ptr++; i++; } - vertexcount += i; } } @@ -333,7 +192,6 @@ void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr) ptr++; i--; } - vertexcount += i; } } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index dd1365193..25815ab76 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -159,7 +159,7 @@ private: void SetupLights(); bool PrepareLight(texcoord * tcs, ADynamicLight * light); - void RenderWall(int textured, float * color2, ADynamicLight * light=NULL); + void RenderWall(int textured, ADynamicLight * light=NULL); void GetPrimitive(unsigned int *store); void FloodPlane(int pass); @@ -212,11 +212,6 @@ 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); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 9c5baae6a..1388eb782 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -215,6 +215,7 @@ void GLWall::SetupLights() } } + //========================================================================== // // General purpose wall rendering function @@ -222,7 +223,7 @@ void GLWall::SetupLights() // //========================================================================== -void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) +void GLWall::RenderWall(int textured, ADynamicLight * light) { texcoord tcs[4]; bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); @@ -249,64 +250,22 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) gl_RenderState.Apply(); // the rest of the code is identical for textured rendering and lights + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - - if (!gl_usevbo) - { - 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 (do not set in render state!) - 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; - } - else - { - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - - 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); - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); - 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); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + vertexcount += 4; } //========================================================================== @@ -356,7 +315,7 @@ void GLWall::RenderFogBoundary() gl_SetFog(lightlevel, rel, &Colormap, false); gl_RenderState.SetEffect(EFF_FOGBOUNDARY); gl_RenderState.EnableAlphaTest(false); - RenderWall(0, NULL); + RenderWall(0); gl_RenderState.EnableAlphaTest(true); gl_RenderState.SetEffect(EFF_NONE); } @@ -385,8 +344,17 @@ void GLWall::RenderFogBoundary() glDepthFunc(GL_LEQUAL); gl_RenderState.SetColor(fc[0], fc[1], fc[2], fogd1); - flags &= ~GLWF_GLOW; - RenderWall(4,fc); + // this case is special because it needs to change the color in the middle of the polygon so it cannot use the standard function + // This also needs no splits so it's relatively simple. + gl_RenderState.Apply(); + glBegin(GL_TRIANGLE_FAN); + glVertex3f(glseg.x1, zbottom[0], glseg.y1); + glVertex3f(glseg.x1, ztop[0], glseg.y1); + glColor4fv(fc); + glVertex3f(glseg.x2, ztop[1], glseg.y2); + glVertex3f(glseg.x2, zbottom[1], glseg.y2); + glEnd(); + vertexcount += 4; glDepthFunc(GL_LESS); gl_RenderState.EnableFog(true); @@ -424,8 +392,7 @@ void GLWall::RenderMirrorSurface() pat->BindPatch(0); flags &= ~GLWF_GLOW; - //flags |= GLWF_NOSHADER; - RenderWall(0,NULL); + RenderWall(0); gl_RenderState.SetEffect(EFF_NONE); @@ -486,7 +453,7 @@ void GLWall::RenderTranslucentWall() if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive); else gl_SetFog(255, 0, NULL, false); - RenderWall(5,NULL); + RenderWall(5); // restore default settings if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -540,7 +507,7 @@ void GLWall::Draw(int pass) gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); gltexture->Bind(flags, 0); - RenderWall(3, NULL); + RenderWall(3); gl_RenderState.EnableGlow(false); gl_RenderState.EnableLight(false); break; @@ -561,14 +528,14 @@ void GLWall::Draw(int pass) { gltexture->Bind(flags, 0); } - RenderWall(pass == GLPASS_BASE? 2:3, NULL); + RenderWall(pass == GLPASS_BASE? 2:3); gl_RenderState.EnableGlow(false); gl_RenderState.EnableLight(false); break; case GLPASS_TEXTURE: // modulated texture gltexture->Bind(flags, 0); - RenderWall(1, NULL); + RenderWall(1); break; case GLPASS_LIGHT: @@ -597,7 +564,7 @@ void GLWall::Draw(int pass) if (!(node->lightsource->flags2&MF2_DORMANT)) { iter_dlight++; - RenderWall(1, NULL, node->lightsource); + RenderWall(1, node->lightsource); } node = node->nextLight; } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index a91fa252f..8f76b0571 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -154,28 +154,16 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed gl_RenderState.EnableAlphaTest(false); } gl_RenderState.Apply(); - if (!gl_usevbo) - { - 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(); - } - else - { - 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); - } + 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); if (tex->GetTransparent() || OverrideShader != 0) { gl_RenderState.EnableAlphaTest(true); From 1b91a8f88cf7cf2fc5dc802f6d11d28918c2b600 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 10:15:44 +0200 Subject: [PATCH 036/138] - removed old immediate mode path for generating stencils. --- src/gl/scene/gl_portal.cpp | 78 +++++++++++----------------------- src/gl/scene/gl_wall.h | 13 +++++- src/gl/scene/gl_walls_draw.cpp | 72 ++++++++++++------------------- 3 files changed, 63 insertions(+), 100 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 18c6dcff5..2d5fcd3a3 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -139,66 +139,36 @@ void GLPortal::ClearScreen() //----------------------------------------------------------------------------- void GLPortal::DrawPortalStencil() { - if (!gl_usevbo) + if (mPrimIndices.Size() == 0) { + bool cap = NeedCap() && lines.Size() > 1; + mPrimIndices.Resize(2 * lines.Size() + 4 * cap); + for (unsigned int i = 0; i 1) + if (cap) { - // 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(); + // Cap the stencil at the top and bottom + int n = lines.Size() * 2; + FFlatVertex *ptr = GLRenderer->mVBO->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]); } } - else + for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) { - if (mPrimIndices.Size() == 0) - { - bool cap = NeedCap() && lines.Size() > 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]); - } - } - for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) - { - glDrawArrays(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]); - } + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]); } } @@ -244,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 @@ -268,7 +238,7 @@ bool GLPortal::Start(bool usestencil, bool doquery) GLuint sampleCount; - glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount); + glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount); if (sampleCount==0) // not visible { diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 25815ab76..28fa51868 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -104,6 +104,16 @@ public: GLWF_NOSPLITLOWER=128, }; + 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; @@ -159,8 +169,7 @@ private: void SetupLights(); bool PrepareLight(texcoord * tcs, ADynamicLight * light); - void RenderWall(int textured, ADynamicLight * light=NULL); - void GetPrimitive(unsigned int *store); + void RenderWall(int textured, ADynamicLight * light=NULL, unsigned int *store = NULL); void FloodPlane(int pass); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 1388eb782..7648625d3 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -223,10 +223,10 @@ void GLWall::SetupLights() // //========================================================================== -void GLWall::RenderWall(int textured, ADynamicLight * light) +void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store) { texcoord tcs[4]; - bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); + bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); if (!light) { @@ -234,7 +234,7 @@ void GLWall::RenderWall(int textured, ADynamicLight * light) tcs[1]=uplft; tcs[2]=uprgt; tcs[3]=lorgt; - if (!!(flags&GLWF_GLOW) && (textured & 2)) + if ((flags&GLWF_GLOW) && (textured & RWF_GLOW)) { gl_RenderState.SetGlowPlanes(topplane, bottomplane); gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); @@ -247,10 +247,14 @@ void GLWall::RenderWall(int textured, ADynamicLight * light) } - gl_RenderState.Apply(); + if (!(textured & RWF_NORENDER)) + { + gl_RenderState.Apply(); + } // the rest of the code is identical for textured rendering and lights FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); + unsigned int count, offset; ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v); ptr++; @@ -264,40 +268,19 @@ void GLWall::RenderWall(int textured, ADynamicLight * light) ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v); ptr++; if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); - vertexcount += 4; + 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; + } } -//========================================================================== -// -// Gets the vertex data for rendering a stencil which needs to be -// repeated several times -// -//========================================================================== - -void GLWall::GetPrimitive(unsigned int *store) -{ - static texcoord tcs[4] = { 0, 0, 0, 0 }; - bool split = (gl_seamless && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); - - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - - ptr->Set(glseg.x1, zbottom[0], glseg.y1, 0, 0); - ptr++; - if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr); - ptr->Set(glseg.x1, ztop[0], glseg.y1, 0, 0); - ptr++; - if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr); - ptr->Set(glseg.x2, ztop[1], glseg.y2, 0, 0); - ptr++; - if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr); - ptr->Set(glseg.x2, zbottom[1], glseg.y2, 0, 0); - ptr++; - if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr); - store[1] = GLRenderer->mVBO->GetCount(ptr, &store[0]); - vertexcount += 4; - } - //========================================================================== // // @@ -315,13 +298,14 @@ void GLWall::RenderFogBoundary() gl_SetFog(lightlevel, rel, &Colormap, false); gl_RenderState.SetEffect(EFF_FOGBOUNDARY); gl_RenderState.EnableAlphaTest(false); - RenderWall(0); + RenderWall(RWF_BLANK); gl_RenderState.EnableAlphaTest(true); gl_RenderState.SetEffect(EFF_NONE); } else { - // otherwise some approximation is needed. This won't look as good + // If we use the fixed function pipeline (GL 2.x) + // 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); @@ -392,7 +376,7 @@ void GLWall::RenderMirrorSurface() pat->BindPatch(0); flags &= ~GLWF_GLOW; - RenderWall(0); + RenderWall(RWF_BLANK); gl_RenderState.SetEffect(EFF_NONE); @@ -453,7 +437,7 @@ void GLWall::RenderTranslucentWall() if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive); else gl_SetFog(255, 0, NULL, false); - RenderWall(5); + RenderWall(RWF_TEXTURED|RWF_NOSPLIT); // restore default settings if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -507,7 +491,7 @@ void GLWall::Draw(int pass) gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); gltexture->Bind(flags, 0); - RenderWall(3); + RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); gl_RenderState.EnableLight(false); break; @@ -528,14 +512,14 @@ void GLWall::Draw(int pass) { gltexture->Bind(flags, 0); } - RenderWall(pass == GLPASS_BASE? 2:3); + RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); gl_RenderState.EnableLight(false); break; case GLPASS_TEXTURE: // modulated texture gltexture->Bind(flags, 0); - RenderWall(1); + RenderWall(RWF_TEXTURED); break; case GLPASS_LIGHT: @@ -564,7 +548,7 @@ void GLWall::Draw(int pass) if (!(node->lightsource->flags2&MF2_DORMANT)) { iter_dlight++; - RenderWall(1, node->lightsource); + RenderWall(RWF_TEXTURED, node->lightsource); } node = node->nextLight; } From 2abf1644a443e72bff06ee5afb68527a2850ff57 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 10:18:46 +0200 Subject: [PATCH 037/138] - fixed: Plane height changes only updated the first buffered vertex for the respective plane. --- src/gl/data/gl_vertexbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 8093a57a0..559131d36 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -294,7 +294,7 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) secplane_t &splane = sec->GetSecPlane(plane); FFlatVertex *vt = &vbo_shadowdata[startvt]; FFlatVertex *mapvt = &map[startvt]; - for(int i=0; iz = splane.ZatPoint(vt->x, vt->y); if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; From 6b038a5daed5a4db7e4452d835957b827f53158e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 10:30:03 +0200 Subject: [PATCH 038/138] - fixed: GLPortal::DrawPortalStencil must apply the render state before drawing anything. --- src/gl/scene/gl_portal.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 2d5fcd3a3..4e07fc1a8 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -166,6 +166,7 @@ void GLPortal::DrawPortalStencil() mPrimIndices[n + 3] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n + 2]); } } + gl_RenderState.Apply(); for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) { GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]); From ea332383a8de95e3d379ae171a6983f023ae8747 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 11:50:54 +0200 Subject: [PATCH 039/138] - convert skybox rendering to use the buffer interface. --- src/gl/scene/gl_skydome.cpp | 216 +++++++++++++++--------------------- 1 file changed, 89 insertions(+), 127 deletions(-) diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 1a8794c58..d36e5fdba 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -336,6 +336,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool else glRotatef(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y); + FFlatVertex *ptr; if (sb->faces[5]) { faces=4; @@ -344,164 +345,125 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool tex = FMaterial::ValidateTexture(sb->faces[0]); tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); 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(GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX | GLT_CLAMPY, 0); 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(GLT_CLAMPX|GLT_CLAMPY, 0); + tex->Bind(GLT_CLAMPX | GLT_CLAMPY, 0); 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(GLT_CLAMPX|GLT_CLAMPY, 0); 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(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(GLT_CLAMPX|GLT_CLAMPY, 0); 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(GLT_CLAMPX|GLT_CLAMPY, 0); 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); } //----------------------------------------------------------------------------- From 1aaa1b7bad8a83ca7689d37b94c4c55e896d969d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 12:12:24 +0200 Subject: [PATCH 040/138] - removed gl_usevbo CVAR because with recent code changes it has become useless. If GL_ARB_buffer_storage is present, buffers will always be used. --- src/gl/data/gl_vertexbuffer.cpp | 14 -------------- src/gl/scene/gl_flats.cpp | 6 +++--- src/gl/shaders/gl_shader.cpp | 2 +- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 559131d36..6ba9f794e 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -49,19 +49,6 @@ #include "gl/data/gl_vertexbuffer.h" -CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - if (self < -1 || self > 1 || !(gl.flags & RFL_BUFFER_STORAGE)) - { - if (self != 0) self = 0; - } - else if (self == -1) - { - if (!(gl.flags & RFL_BUFFER_STORAGE)) self = 0; - else self = 1; - } -} - //========================================================================== // // Create / destroy the VBO @@ -71,7 +58,6 @@ CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA FVertexBuffer::FVertexBuffer() { vbo_id = 0; - if (gl_usevbo == -1) gl_usevbo.Callback(); glGenBuffers(1, &vbo_id); } diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 59d4192e7..6b34fb659 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -293,7 +293,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) } else { - if (gl_usevbo && vboindex >= 0) + if (vboindex >= 0) { int index = vboindex; for (int i=0; isubsectorcount; i++) @@ -303,9 +303,9 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); - //drawcalls.Clock(); + drawcalls.Clock(); glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); - //drawcalls.Unclock(); + drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 0b55fbd35..b90974222 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -385,8 +385,8 @@ void FShaderManager::CompileShaders() // If shader compilation failed we can still run the fixed function mode so do that instead of aborting. Printf("%s\n", err.GetMessage()); Printf(PRINT_HIGH, "Failed to compile shaders. Reverting to fixed function mode\n"); - gl_usevbo = false; gl.glslversion = 0.0; + gl.flags &= ~RFL_BUFFER_STORAGE; } } From e6f14b055a6b10aaea80a952d79b9ec2ee91a621 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 20:28:23 +0200 Subject: [PATCH 041/138] - use buffer based rendering for dynamic light pass and horizon portals. --- src/gl/scene/gl_flats.cpp | 10 ++--- src/gl/scene/gl_portal.cpp | 77 +++++++++++++++------------------- src/gl/scene/gl_walls_draw.cpp | 2 +- src/gl/system/gl_cvars.h | 4 -- 4 files changed, 38 insertions(+), 55 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 6b34fb659..56d2bd8d6 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -152,7 +152,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) gl_RenderState.Apply(); // Render the light - glBegin(GL_TRIANGLE_FAN); + FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); for (k = 0, v = sub->firstline; k < sub->numlines; k++, v++) { vertex_t *vt = v->v1; @@ -160,12 +160,10 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) 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); + ptr->Set(vt->fx, zc, vt->fy, (nearToVert.Dot(right) * scale) + 0.5f, (nearToVert.Dot(up) * scale) + 0.5f); + ptr++; } - - glEnd(); + GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); node = node->nextLight; } } diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 4e07fc1a8..a7400ec22 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -999,26 +999,21 @@ void GLHorizonPortal::DrawContents() 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); } } @@ -1029,34 +1024,28 @@ 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(); + 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); if (pushed) { diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 7648625d3..2879ade62 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -331,7 +331,7 @@ void GLWall::RenderFogBoundary() // this case is special because it needs to change the color in the middle of the polygon so it cannot use the standard function // This also needs no splits so it's relatively simple. gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); + glBegin(GL_TRIANGLE_FAN); // only used on GL 2.x! glVertex3f(glseg.x1, zbottom[0], glseg.y1); glVertex3f(glseg.x1, ztop[0], glseg.y1); glColor4fv(fc); diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index 79321f5b5..d0e18bca4 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -43,8 +43,4 @@ 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 From 965a2a2d791c9f966f7e0eae4f63eb931d83c176 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jun 2014 21:56:37 +0200 Subject: [PATCH 042/138] definition for model vertex buffer. --- src/gl/data/gl_vertexbuffer.h | 33 ++++++++++++++++++++++++++++++++- src/gl/models/gl_models.h | 2 ++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 50ddd7d13..f82172d08 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -44,7 +44,6 @@ struct FFlatVertex class FFlatVertexBuffer : public FVertexBuffer { FFlatVertex *map; - FFlatVertex mDrawBuffer[1000]; unsigned int mIndex; unsigned int mCurIndex; @@ -170,5 +169,37 @@ public: #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; + } +}; + + +class FModelVertexBuffer : public FVertexBuffer +{ + int mIndexFrame[2]; + +public: + TArray vbo_shadowdata; // this is kept around for interpolating on GL 2.0 + + FModelVertexBuffer(); + ~FModelVertexBuffer(); + + void BindVBO(); + void UpdateBufferPointers(int frame1, int frame2); +}; + +#define VMO ((FModelVertex*)NULL) + #endif \ No newline at end of file diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index ebfb8b8c5..4ba206983 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 }; From 59522f7065f6d32fb75e8d966e36f88380da51e3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Jun 2014 13:37:30 +0200 Subject: [PATCH 043/138] - simplified MD2 drawing code as preparation for a buffer based implementation. --- src/gl/models/gl_models.h | 2 +- src/gl/models/gl_models_md2.cpp | 116 ++++++++++---------------------- src/gl/system/gl_interface.cpp | 1 + src/gl/system/gl_interface.h | 1 + 4 files changed, 39 insertions(+), 81 deletions(-) diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 4ba206983..a4effd51d 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -125,7 +125,7 @@ protected: char *vertexUsage; // Bitfield for each vertex. bool allowTexComp; // Allow texture compression with this. - static void RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices); + static void RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices, FModelVertex *vertices2, double inter); public: FDMDModel() diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index 12c8bebe7..46a7238a7 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -263,11 +263,13 @@ 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::RenderGLCommands(void *glCommands, unsigned int numVertices, FModelVertex * vertices, FModelVertex *vertices2, double inter) { char *pos; FGLCommandVertex * v; int count; + const bool interpolate = (vertices2 != NULL && inter != 0.); gl_RenderState.Apply(); for(pos = (char*)glCommands; *pos;) @@ -277,101 +279,55 @@ void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices,FMod // The type of primitive depends on the sign. glBegin(count > 0 ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN); + count = abs(count); - while(count--) + while (count--) { - v = (FGLCommandVertex *) pos; + v = (FGLCommandVertex *)pos; pos += sizeof(FGLCommandVertex); glTexCoord2fv(&v->s); - glVertex3fv((float*)&vertices[v->index]); + if (!interpolate) + { + glVertex3fv(vertices[v->index].xyz); + } + else + { + float interp[3]; + for (int i = 0; i < 3; i++) + interp[i] = inter * vertices[v->index].xyz[i] + (1. - inter) * vertices2[v->index].xyz[i]; + glVertex3fv(interp); + } } - glEnd(); } } +void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int translation) +{ + 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); + + tex->Bind(0, translation); + + RenderGLCommands(lods[0].glCommands, info.numVertices, frames[frameno].vertices, frames[frameno2].vertices, inter); +} + void FDMDModel::RenderFrame(FTexture * skin, int frameno, 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(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*/); + RenderFrameInterpolated(skin, frameno, frameno, 0., translation); } -void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, 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(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; -} - - //=========================================================================== // // FMD2Model::Load diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index ac34bd2c1..d9816e120 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -144,6 +144,7 @@ void gl_LoadExtensions() 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 (gl.version >= 4.f && CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; + if (gl.version >= 3.2f || CheckExtension("GL_ARB_draw_elements_base_vertex")) gl.flags |= RFL_BASEINDEX; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 45e0a09ac..d280242e1 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -12,6 +12,7 @@ enum RenderFlags RFL_FRAMEBUFFER = 4, RFL_BUFFER_STORAGE = 8, RFL_SHADER_STORAGE_BUFFER = 16, + RFL_BASEINDEX = 32, }; enum TexMode From 03916d75de18162fb7efb1bb6c6ad25b7b60b4ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Jun 2014 13:58:49 +0200 Subject: [PATCH 044/138] - cleaned up MD3 rendering and merged RenderFrame and RenderFrameInterpolated into one function. --- src/gl/models/gl_models.cpp | 4 +-- src/gl/models/gl_models.h | 15 +++----- src/gl/models/gl_models_md2.cpp | 9 ++--- src/gl/models/gl_models_md3.cpp | 64 +++++++++------------------------ src/gl/models/gl_voxels.cpp | 15 ++------ 5 files changed, 28 insertions(+), 79 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 568a2e3f2..76e8006aa 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -675,9 +675,9 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, if (mdl!=NULL) { if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) - mdl->RenderFrameInterpolated(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, translation); + mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, translation); else - mdl->RenderFrame(smf->skins[i], smf->modelframes[i], translation); + mdl->RenderFrame(smf->skins[i], smf->modelframes[i], NULL, 0.f, translation); } } } diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index a4effd51d..181784b9b 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -29,9 +29,7 @@ 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 translation=0) = 0; - // [BB] Added RenderFrameInterpolated - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; virtual void MakeGLData() {} virtual void CleanGLData() {} @@ -140,8 +138,7 @@ public: 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 translation=0); - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); }; @@ -222,7 +219,7 @@ class FMD3Model : public FModel MD3Frame * frames; MD3Surface * surfaces; - void RenderTriangles(MD3Surface * surf, MD3Vertex * vert); + void RenderTriangles(MD3Surface * surf, MD3Vertex * vert, MD3Vertex *vert2, double inter); public: FMD3Model() { } @@ -230,8 +227,7 @@ public: 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 translation=0); - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); }; class FVoxelVertexBuffer; @@ -293,8 +289,7 @@ public: void MakeGLData(); void CleanGLData(); virtual int FindFrame(const char * name); - virtual void RenderFrame(FTexture * skin, int frame, int translation=0); - virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); FTexture *GetPaletteTexture() const { return mPalette; } }; diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index 46a7238a7..8fa8310f7 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -269,7 +269,7 @@ void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, FMo char *pos; FGLCommandVertex * v; int count; - const bool interpolate = (vertices2 != NULL && inter != 0.); + const bool interpolate = (vertices2 != NULL && inter != 0. && vertices != vertices2); gl_RenderState.Apply(); for(pos = (char*)glCommands; *pos;) @@ -304,7 +304,7 @@ void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, FMo } } -void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int translation) +void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation) { if (frameno >= info.numFrames || frameno2 >= info.numFrames) return; @@ -323,11 +323,6 @@ void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int framen } -void FDMDModel::RenderFrame(FTexture * skin, int frameno, int translation) -{ - RenderFrameInterpolated(skin, frameno, frameno, 0., translation); -} - //=========================================================================== // // FMD2Model::Load diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index bd1b4e972..6b380ea29 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -215,8 +215,10 @@ int FMD3Model::FindFrame(const char * name) return -1; } -void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert) +void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert, MD3Vertex *vert2, double inter) { + const bool interpolate = (vert2 != NULL && inter != 0. && vert != vert2); + gl_RenderState.Apply(); glBegin(GL_TRIANGLES); for(int i=0; inumTriangles;i++) @@ -226,44 +228,24 @@ void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert) int x = surf->tris[i].VertIndex[j]; glTexCoord2fv(&surf->texcoords[x].s); - glVertex3f(vert[x].x, vert[x].z, vert[x].y); + if (!interpolate) + { + glVertex3f(vert[x].x, vert[x].z, vert[x].y); + } + else + { + float interp[3]; + interp[0] = inter * vert[x].x + (1. - inter) * vert2[x].x; + interp[1] = inter * vert[x].z + (1. - inter) * vert2[x].z; + interp[2] = inter * vert[x].y + (1. - inter) * vert2[x].y; + glVertex3fv(interp); + } } } glEnd(); } -void FMD3Model::RenderFrame(FTexture * skin, int frameno, 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(0, translation); - RenderTriangles(surf, surf->vertices + frameno * surf->numVertices); - } -} - -void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int translation) +void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation) { if (frameno>=numFrames || frameno2>=numFrames) return; @@ -285,22 +267,10 @@ void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int framen tex->Bind(0, translation); - 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; + RenderTriangles(surf, vertices1, vertices2, inter); } } diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index 3a04cb5ca..873390f9c 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -498,11 +498,11 @@ int FVoxelModel::FindFrame(const char * name) //=========================================================================== // -// +// Voxels never interpolate between frames // //=========================================================================== -void FVoxelModel::RenderFrame(FTexture * skin, int frame, int translation) +void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation) { FMaterial * tex = FMaterial::ValidateTexture(skin); tex->Bind(0, translation); @@ -529,14 +529,3 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int translation) } } -//=========================================================================== -// -// Voxels never interpolate between frames -// -//=========================================================================== - -void FVoxelModel::RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int translation) -{ - RenderFrame(skin, frame, translation); -} - From 412d6499d967c9ab660c76756df39c1ee7cec0ed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Jun 2014 14:46:55 +0200 Subject: [PATCH 045/138] - removed the voxel vertex buffer because it needs to be gone before implementing a model vertex buffer. --- src/gl/models/gl_models.cpp | 13 --- src/gl/models/gl_models.h | 6 -- src/gl/models/gl_voxels.cpp | 139 ++------------------------------ src/gl/renderer/gl_renderer.cpp | 1 - 4 files changed, 7 insertions(+), 152 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 76e8006aa..fc248b2cc 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -899,16 +899,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 181784b9b..e20010931 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -30,8 +30,6 @@ 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 frame2, double inter, int translation=0) = 0; - virtual void MakeGLData() {} - virtual void CleanGLData() {} @@ -274,7 +272,6 @@ protected: bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object TArray mVertices; TArray mIndices; - FVoxelVertexBuffer *mVBO; FTexture *mPalette; void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check); @@ -286,8 +283,6 @@ public: ~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 frame2, double inter, int translation=0); FTexture *GetPaletteTexture() const { return mPalette; } @@ -345,6 +340,5 @@ void gl_RenderModel(GLSprite * spr); // [BB] HUD weapon model rendering functions. 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_voxels.cpp b/src/gl/models/gl_voxels.cpp index 873390f9c..e1fb094af 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); - glDisableClientState(GL_COLOR_ARRAY); -} - - - //=========================================================================== // // @@ -299,7 +213,6 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) { mVoxel = voxel; mOwningVoxel = owned; - mVBO = NULL; mPalette = new FVoxelTexture(voxel); Initialize(); } @@ -312,7 +225,6 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) FVoxelModel::~FVoxelModel() { - CleanGLData(); delete mPalette; if (mOwningVoxel) delete mVoxel; } @@ -459,32 +371,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 @@ -507,25 +393,14 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double int FMaterial * tex = FMaterial::ValidateTexture(skin); tex->Bind(0, translation); - if (mVBO == NULL) MakeGLData(); - if (mVBO != NULL) + gl_RenderState.Apply(); + glBegin(GL_QUADS); + for (unsigned i = 0; i < mIndices.Size(); i++) { - gl_RenderState.SetVertexBuffer(mVBO); - gl_RenderState.Apply(); - glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0); - gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); - } - else - { - gl_RenderState.Apply(); - glBegin(GL_QUADS); - for (unsigned i = 0; i < mIndices.Size(); i++) - { - FVoxelVertex *vert = &mVertices[mIndices[i]]; - glTexCoord2fv(&vert->u); - glVertex3fv(&vert->x); - } - glEnd(); + FVoxelVertex *vert = &mVertices[mIndices[i]]; + glTexCoord2fv(&vert->u); + glVertex3fv(&vert->x); } + glEnd(); } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 78ec2e34e..a51e1fc37 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -118,7 +118,6 @@ void FGLRenderer::Initialize() FGLRenderer::~FGLRenderer() { - gl_CleanModelData(); gl_DeleteAllAttachedLights(); FMaterial::FlushAll(); //if (mThreadManager != NULL) delete mThreadManager; From 3e9b9c280bcddadca4c2b7854535ef4deb3884c5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Jun 2014 15:22:00 +0200 Subject: [PATCH 046/138] - initialize model data at engine start, not at level start. --- src/gl/data/gl_data.cpp | 5 ++--- src/gl/data/gl_data.h | 1 + src/gl/data/gl_setup.cpp | 10 ---------- src/gl/models/gl_models.h | 1 - src/gl/scene/gl_scene.cpp | 1 + src/r_data/sprites.cpp | 4 ++++ 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index da72f6313..641b6b14c 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -477,9 +477,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 6a1589cde..42b6df26e 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -57,6 +57,7 @@ extern TArray currentmapsection; void gl_InitPortals(); void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal); +void gl_InitData(); extern long gl_frameMS; diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index a76e618d9..458019b41 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(); //========================================================================== // @@ -613,15 +612,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/models/gl_models.h b/src/gl/models/gl_models.h index e20010931..7b32be085 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -333,7 +333,6 @@ struct FSpriteModelFrame class GLSprite; -void gl_InitModels(); FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); void gl_RenderModel(GLSprite * spr); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 8f8d50532..b1bf9e343 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -1224,6 +1224,7 @@ void FGLInterface::RenderView(player_t *player) void FGLInterface::Init() { gl_ParseDefs(); + gl_InitData(); } //=========================================================================== diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index c1e59c415..236355f3b 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; @@ -988,6 +990,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() From 59448941389c01f1b7fcfc2d9b89f28d5e8781b5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Jun 2014 17:06:26 +0200 Subject: [PATCH 047/138] - create vertex buffer data for MD2/DMD models. --- src/gl/data/gl_vertexbuffer.h | 7 +++ src/gl/models/gl_models.h | 15 +++-- src/gl/models/gl_models_md2.cpp | 98 +++++++++++++++++++++++++++++++-- 3 files changed, 111 insertions(+), 9 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index f82172d08..ad09fb5d9 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -182,6 +182,11 @@ struct FModelVertex 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. + } }; @@ -190,7 +195,9 @@ class FModelVertexBuffer : public FVertexBuffer int mIndexFrame[2]; 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(); diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 7b32be085..cc900649b 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -30,6 +30,7 @@ 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 frame2, double inter, int translation=0) = 0; + virtual void BuildVertexBuffer(FModelVertexBuffer *buf); @@ -54,7 +55,7 @@ protected: int flags; }; - struct FModelVertex + struct DMDModelVertex { float xyz[3]; }; @@ -90,8 +91,9 @@ protected: struct ModelFrame { char name[16]; - FModelVertex *vertices; - FModelVertex *normals; + DMDModelVertex *vertices; + DMDModelVertex *normals; + unsigned int vindex; }; struct DMDLoDInfo @@ -114,6 +116,9 @@ protected: DMDInfo info; FTexture ** skins; FTexCoord * texCoords; + + unsigned int ib_index; + unsigned int ib_count; ModelFrame * frames; DMDLoDInfo lodInfo[MAX_LODS]; @@ -121,7 +126,7 @@ protected: char *vertexUsage; // Bitfield for each vertex. bool allowTexComp; // Allow texture compression with this. - static void RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices, FModelVertex *vertices2, double inter); + static void RenderGLCommands(void *glCommands, unsigned int numVertices,DMDModelVertex * vertices, DMDModelVertex *vertices2, double inter); public: FDMDModel() @@ -131,12 +136,14 @@ public: skins = NULL; lods[0].glCommands = NULL; info.numLODs = 0; + ib_count = 0; } 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 frame2, double inter, int translation=0); + virtual void BuildVertexBuffer(FModelVertexBuffer *buf); }; diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index 8fa8310f7..ccf604dca 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -163,6 +163,7 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length) temp = (char*)buffer + info.offsetFrames; frames = new ModelFrame[info.numFrames]; + ib_count = 0; for(i = 0, frame = frames; i < info.numFrames; i++, frame++) { @@ -170,8 +171,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++) @@ -244,6 +246,91 @@ FDMDModel::~FDMDModel() if (vertexUsage != NULL) delete [] vertexUsage; } + +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; + void *glCommands = lods[0].glCommands; + + frame->vindex = buf->vbo_shadowdata.Size(); + + for (char *pos = (char*)glCommands; *pos;) + { + int count = *(int *)pos; + pos += 4; + + // The type of primitive depends on the sign. + int primtype = count > 0 ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN; + count = abs(count); + + if (i == 0) + { + // build the index buffer - we'll use the same buffer for all frames so only create it once + unsigned int bufindex = buf->vbo_shadowdata.Size() - frame->vindex; + unsigned int bufp = bufindex; + + if (primtype == GL_TRIANGLE_STRIP) + { + for (int t = 0; t < count - 2; t++) + { + unsigned int *p = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(3)]; + if ((t & 1) == 0) + { + p[0] = bufp; + p[1] = bufp + 1; + p[2] = bufp + 2; + } + else + { + p[0] = bufp; + p[2] = bufp + 2; + p[1] = bufp + 1; + } + bufp++; + } + } + else + { + bufp++; + for (int t = 0; t < count - 2; t++) + { + unsigned int *p = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(3)]; + p[0] = bufindex; + p[1] = bufp; + p[2] = bufp + 1; + bufp++; + } + } + } + + while (count--) + { + FModelVertex bvert; + + FGLCommandVertex * v = (FGLCommandVertex *)pos; + pos += sizeof(FGLCommandVertex); + + bvert.Set(vert[v->index].xyz[0], vert[v->index].xyz[1], vert[v->index].xyz[2], v->s, v->t); + bvert.SetNormal(norm[v->index].xyz[0], norm[v->index].xyz[1], norm[v->index].xyz[2]); + buf->vbo_shadowdata.Push(bvert); + } + } + } +} + + + + + + + + + + //=========================================================================== // // FDMDModel::FindFrame @@ -264,7 +351,7 @@ int FDMDModel::FindFrame(const char * name) // //=========================================================================== -void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, FModelVertex * vertices, FModelVertex *vertices2, double inter) +void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, DMDModelVertex * vertices, DMDModelVertex *vertices2, double inter) { char *pos; FGLCommandVertex * v; @@ -418,8 +505,9 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length) 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++) From ca76c2525e63fd9ae5fd6586017bdc3511fff74e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Jun 2014 22:24:33 +0200 Subject: [PATCH 048/138] - more vertex buffer stuff for models, still not tested. --- src/gl/models/gl_models.h | 28 +++++++++---------- src/gl/models/gl_models_md3.cpp | 31 +++++++++++++++++++++ src/gl/models/gl_voxels.cpp | 48 +++++++++++++++++++++++++-------- 3 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index cc900649b..f9f8f4f22 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -30,7 +30,7 @@ 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 frame2, double inter, int translation=0) = 0; - virtual void BuildVertexBuffer(FModelVertexBuffer *buf); + virtual void BuildVertexBuffer(FModelVertexBuffer *buf) = 0; @@ -193,11 +193,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() @@ -233,20 +237,13 @@ public: 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 frame2, double inter, int translation=0); -}; - -class FVoxelVertexBuffer; - -struct FVoxelVertex -{ - float x,y,z; - float u,v; + 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); @@ -255,7 +252,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; } @@ -269,7 +266,7 @@ struct FIndexInit } }; -typedef TMap FVoxelMap; +typedef TMap FVoxelMap; class FVoxelModel : public FModel @@ -277,13 +274,15 @@ 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; 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); @@ -293,6 +292,7 @@ public: virtual int FindFrame(const char * name); virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0); FTexture *GetPaletteTexture() const { return mPalette; } + void BuildVertexBuffer(FModelVertexBuffer *buf); }; diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 6b380ea29..2c6f39d05 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -206,6 +206,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;ivbo_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()); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +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; } //=========================================================================== @@ -257,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; @@ -266,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[2]); + mIndices.Push(indx[1]); + mIndices.Push(indx[3]); + mIndices.Push(indx[2]); } //=========================================================================== @@ -384,7 +410,7 @@ int FVoxelModel::FindFrame(const char * name) //=========================================================================== // -// Voxels never interpolate between frames +// Voxels never interpolate between frames, they only have one. // //=========================================================================== @@ -394,10 +420,10 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double int tex->Bind(0, translation); gl_RenderState.Apply(); - glBegin(GL_QUADS); + glBegin(GL_TRIANGLES); for (unsigned i = 0; i < mIndices.Size(); i++) { - FVoxelVertex *vert = &mVertices[mIndices[i]]; + FModelVertex *vert = &mVertices[mIndices[i]]; glTexCoord2fv(&vert->u); glVertex3fv(&vert->x); } From d5dceb68748e93d1949136104e8b8a17a21bf84f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 21 Jun 2014 12:52:19 +0200 Subject: [PATCH 049/138] - changed alpha texture handling to avoid using the deprecated GL_ALPHA8 texture format unless we have a compatibility context of an older GL version. --- src/gl/system/gl_interface.cpp | 1 - src/gl/system/gl_interface.h | 5 +++++ src/gl/textures/gl_bitmap.cpp | 26 ++++++++++++++++++++------ src/gl/textures/gl_hwtexture.cpp | 27 +++++++++++++++++++++++++-- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index d9816e120..7d979f921 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -153,7 +153,6 @@ void gl_LoadExtensions() { gl.flags|=RFL_FRAMEBUFFER; } - } //========================================================================== diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index d280242e1..d5346fa7d 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -41,6 +41,11 @@ struct RenderContext { return glslversion >= 1.3f; } + + bool hasCompatibility() // will return false, once transition to a core profile is possible and a core profile is used. + { + return true; + } }; extern RenderContext gl; diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index 83a92e0fe..c37e7a90e 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" //=========================================================================== // @@ -54,7 +55,7 @@ void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, { int i; - if (!alphatex) + if (!alphatex || gl.version >= 3.3f) // GL 3.3+ uses a GL_R8 texture for alpha textures so the channels can remain as they are. { for(i=0;i 0) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 7aa8b610c..a2a83e5db 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -190,8 +190,26 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i bool deletebuffer=false; bool use_mipmapping = TexFilter[gl_texture_filter].mipmapping; - if (alphatexture) texformat=GL_ALPHA8; - else if (forcenocompression) texformat = GL_RGBA8; + if (alphatexture) + { + // thanks to deprecation and delayed introduction of a suitable replacement feature this has become a bit messy... + if (gl.version >= 3.3f) + { + texformat = GL_R8; + } + else if (gl.version <= 3.0f || gl.hasCompatibility()) + { + texformat = GL_ALPHA8; + } + else + { + texformat = GL_RGBA8; + } + } + else if (forcenocompression) + { + texformat = GL_RGBA8; + } if (glTexID==0) glGenTextures(1,&glTexID); glBindTexture(GL_TEXTURE_2D, glTexID); lastbound[texunit]=glTexID; @@ -238,6 +256,11 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i 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); + if (alphatexture && gl.version >= 3.3f) + { + static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } clampmode = wrapparam==GL_CLAMP? GLT_CLAMPX|GLT_CLAMPY : 0; if (forcenofiltering) From 2925c96b596ce71a4e01463a611318465e8c4661 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 21 Jun 2014 15:50:32 +0200 Subject: [PATCH 050/138] removed all GL 2.x code. After thinking about it for a day or so I believe it's the best option to remove all compatibility code because it's a major obstacle for a transition to a core profile. --- src/gl/data/gl_data.cpp | 8 - src/gl/dynlights/gl_dynlight1.cpp | 6 +- src/gl/models/gl_models.cpp | 34 +-- src/gl/renderer/gl_lightdata.cpp | 2 - src/gl/renderer/gl_renderer.cpp | 15 +- src/gl/renderer/gl_renderstate.cpp | 291 +++++++++---------------- src/gl/renderer/gl_renderstate.h | 4 +- src/gl/scene/gl_flats.cpp | 2 +- src/gl/scene/gl_scene.cpp | 83 +------- src/gl/scene/gl_skydome.cpp | 5 - src/gl/scene/gl_sprite.cpp | 19 +- src/gl/scene/gl_walls.cpp | 4 +- src/gl/scene/gl_walls_draw.cpp | 61 +----- src/gl/scene/gl_weapon.cpp | 4 +- src/gl/shaders/gl_shader.cpp | 329 ++++++++++++++--------------- src/gl/system/gl_interface.cpp | 17 +- src/gl/system/gl_interface.h | 11 - src/gl/system/gl_menu.cpp | 36 ---- src/gl/system/gl_wipe.cpp | 47 +---- src/gl/textures/gl_hqresize.cpp | 4 - src/gl/textures/gl_hwtexture.cpp | 41 ++-- src/gl/textures/gl_material.cpp | 143 ++----------- src/gl/textures/gl_material.h | 10 +- src/gl/textures/gl_texture.cpp | 1 - 24 files changed, 339 insertions(+), 838 deletions(-) diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index 641b6b14c..47a08af83 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -356,14 +356,6 @@ void InitGLRMapinfoData() glset.map_notexturefill = opt->notexturefill; glset.skyrotatevector = opt->skyrotatevector; glset.skyrotatevector2 = opt->skyrotatevector2; - if (!gl.hasGLSL()) - { - // light modes 2 and 8 require shaders - if (glset.map_lightmode == 2 || glset.map_lightmode == 8) - { - glset.map_lightmode = 3; - } - } } else { diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index f13f24ab6..42053e8a5 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -72,11 +72,7 @@ CUSTOM_CVAR (Bool, gl_dynlight_shader, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | { if (self) { - if (!gl.hasGLSL()) - { - self = false; - } - else if (gl.maxuniforms < 1024 && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (gl.maxuniforms < 1024 && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { self = false; } diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index fc248b2cc..0ee9c563f 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -744,17 +744,9 @@ void gl_RenderModel(GLSprite * spr) 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.hasGLSL()) - { - 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(); - } + glActiveTexture(GL_TEXTURE7); // Hijack the otherwise unused seventh texture matrix for the model to world transformation. + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); // Model space => World space glTranslatef(spr->x, spr->z, spr->y ); @@ -786,7 +778,7 @@ void gl_RenderModel(GLSprite * spr) glRotatef(smf->pitchoffset, 0, 0, 1); glRotatef(-smf->rolloffset, 1, 0, 0); - if (gl.hasGLSL()) glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); #if 0 if (gl_light_models) @@ -805,19 +797,11 @@ void gl_RenderModel(GLSprite * spr) gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), NULL, translation ); - if (!gl.hasGLSL()) - { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - else - { - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glActiveTexture(GL_TEXTURE0); - glMatrixMode(GL_MODELVIEW); - } + glActiveTexture(GL_TEXTURE7); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_MODELVIEW); glDepthFunc(GL_LESS); if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] )) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 60ecf70be..29013f280 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -109,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.hasGLSL()) self = 1; } CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL) @@ -117,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.hasGLSL()) newself = 3; if (self != newself) self = newself; glset.lightmode = newself; } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index a51e1fc37..97cf6d10f 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -216,13 +216,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; } //=========================================================================== @@ -233,10 +229,7 @@ bool FGLRenderer::StartOffscreen() void FGLRenderer::EndOffscreen() { - if (gl.flags & RFL_FRAMEBUFFER) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + glBindFramebuffer(GL_FRAMEBUFFER, 0); } //=========================================================================== diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 673c201b8..8ce695cbc 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -94,22 +94,10 @@ void FRenderState::Reset() // //========================================================================== -int FRenderState::SetupShader(int &shaderindex, float warptime) +void FRenderState::SetupShader(int &shaderindex, float warptime) { - int softwarewarp = 0; - - if (gl.hasGLSL()) - { - mEffectState = shaderindex; - if (shaderindex > 0) GLRenderer->mShaderManager->SetWarpSpeed(shaderindex, warptime); - } - else - { - softwarewarp = shaderindex > 0 && shaderindex < 3? shaderindex : 0; - shaderindex = 0; - } - - return softwarewarp; + mEffectState = shaderindex; + if (shaderindex > 0) GLRenderer->mShaderManager->SetWarpSpeed(shaderindex, warptime); } @@ -121,124 +109,119 @@ int FRenderState::SetupShader(int &shaderindex, float warptime) bool FRenderState::ApplyShader() { - - if (gl.hasGLSL()) + FShader *activeShader; + if (mSpecialEffect > EFF_NONE) { - FShader *activeShader; - if (mSpecialEffect > EFF_NONE) + activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); + } + else + { + activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); + activeShader->Bind(); + } + + int fogset = 0; + //glColor4fv(mColor.vec); + if (mFogEnabled) + { + if ((mFogColor & 0xffffff) == 0) { - activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); + fogset = gl_fogmode; } else { - activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); - activeShader->Bind(); + fogset = -gl_fogmode; } + } - int fogset = 0; - //glColor4fv(mColor.vec); - if (mFogEnabled) + glColor4fv(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); + + if (mGlowEnabled) + { + 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 (mLightEnabled) + { + activeShader->muLightRange.Set(mNumLights); + glUniform4fv(activeShader->lights_index, mNumLights[3], mLightData); + } + else + { + static const int nulint[] = { 0, 0, 0, 0 }; + activeShader->muLightRange.Set(nulint); + } + + 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); } - - glColor4fv(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); - - if (mGlowEnabled) + else if (mColormapState >= CM_TORCH) { - activeShader->muGlowTopColor.Set(mGlowTop.vec); - activeShader->muGlowBottomColor.Set(mGlowBottom.vec); - activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec); - activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec); - activeShader->currentglowstate = 1; + 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); } - 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 (mLightEnabled) - { - activeShader->muLightRange.Set(mNumLights); - glUniform4fv(activeShader->lights_index, mNumLights[3], mLightData); - } - else - { - static const int nulint[] = { 0, 0, 0, 0 }; - activeShader->muLightRange.Set(nulint); - } - - if (mColormapState != activeShader->currentfixedcolormap) - { - float r, g, b; - activeShader->currentfixedcolormap = mColormapState; - if (mColormapState == CM_DEFAULT) - { - 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) - { - r = 0.375f, g = 1.0f, b = 0.375f; - } - else - { - r = g = b = 1.f; - } - activeShader->muFixedColormap.Set(2); - activeShader->muColormapStart.Set(r, g, b, 1.f); - } - else if (mColormapState >= CM_TORCH) - { - 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); - } - } - return true; } - return false; + return true; } @@ -248,7 +231,7 @@ bool FRenderState::ApplyShader() // //========================================================================== -void FRenderState::Apply(bool forcenoshader) +void FRenderState::Apply() { if (!gl_direct_state_change) { @@ -283,78 +266,6 @@ void FRenderState::Apply(bool forcenoshader) else mVertexBuffer->BindVBO(); mCurrentVertexBuffer = mVertexBuffer; } - if (forcenoshader || !ApplyShader()) - { - //if (mColor.vec[0] >= 0.f) glColor4fv(mColor.vec); - - 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 != mLightParms[2]) - { - const float LOG2E = 1.442692f; // = 1/log(2) - glFogf(GL_FOG_DENSITY, -mLightParms[2] / LOG2E); - ffFogDensity = mLightParms[2]; - } - } - 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; - } - // Now compose the final color for this... - float realcolor[4]; - realcolor[0] = clamp((mColor.vec[0] + mDynColor.r / 255.f), 0.f, 1.f) * (mObjectColor.r / 255.f); - realcolor[1] = clamp((mColor.vec[1] + mDynColor.g / 255.f), 0.f, 1.f) * (mObjectColor.g / 255.f); - realcolor[2] = clamp((mColor.vec[2] + mDynColor.b / 255.f), 0.f, 1.f) * (mObjectColor.b / 255.f); - realcolor[3] = mColor.vec[3] * (mObjectColor.a / 255.f); - glColor4fv(realcolor); - - } - + ApplyShader(); } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 8bcedcac7..c3ca1e273 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -92,8 +92,8 @@ public: void Reset(); - int SetupShader(int &shaderindex, float warptime); - void Apply(bool forcenoshader = false); + void SetupShader(int &shaderindex, float warptime); + void Apply(); void SetVertexBuffer(FVertexBuffer *vb) { diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 56d2bd8d6..7e327ab9c 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -501,7 +501,7 @@ inline void GLFlat::PutFlat(bool fog) else foggy = false; list = list_indices[light][masked][foggy]; - if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap && gl.hasGLSL()) list = GLDL_LIGHTBRIGHT; + if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap) list = GLDL_LIGHTBRIGHT; gl_drawinfo->drawlists[list].AddFlat (this); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index b1bf9e343..4868d07bd 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -287,12 +287,10 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) void FGLRenderer::SetViewMatrix(bool mirror, bool planemirror) { - if (gl.hasGLSL()) - { - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - } + glActiveTexture(GL_TEXTURE7); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_TEXTURE); glLoadIdentity(); @@ -725,69 +723,6 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, blendv.a / 255.0f, blend); } } - else if (!gl.hasGLSL()) - { - float r, g, b; - bool inverse = false; - const float BLACK_THRESH = 0.05f; - const float WHITE_THRESH = 0.95f; - - // for various reasons (performance and keeping the lighting code clean) - // we no longer do colormapped textures on pre GL 3.0 hardware and instead do - // just a fullscreen overlay to emulate the inverse invulnerability effect or similar fullscreen blends. - if (gl_fixedcolormap >= (DWORD)CM_FIRSTSPECIALCOLORMAP && gl_fixedcolormap < (DWORD)CM_MAXCOLORMAP) - { - FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; - - if (scm->ColorizeEnd[0] < BLACK_THRESH && scm->ColorizeEnd[1] < BLACK_THRESH && scm->ColorizeEnd[2] < BLACK_THRESH) - { - r = scm->ColorizeStart[0]; - g = scm->ColorizeStart[1]; - b = scm->ColorizeStart[2]; - inverse = true; - } - else - { - r = scm->ColorizeEnd[0]; - g = scm->ColorizeEnd[1]; - b = scm->ColorizeEnd[2]; - } - } - else if (gl_enhanced_nightvision) - { - if (gl_fixedcolormap == CM_LITE) - { - r = 0.375f; - g = 1.0f; - b = 0.375f; - } - 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; - g = r; - b = g * 0.75f; - } - else r = g = b = 1.f; - } - else r = g = b = 1.f; - - if (inverse) - { - gl_RenderState.BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - gl_RenderState.ResetColor(); - FillScreen(); - } - - if (r < WHITE_THRESH || g < WHITE_THRESH || b < WHITE_THRESH) - { - gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - gl_RenderState.SetColor(r, g, b, 1.0f); - FillScreen(); - } - } - // This mostly duplicates the code in shared_sbar.cpp // When I was writing this the original was called too late so that I @@ -1245,15 +1180,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in 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(); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index d36e5fdba..ad3b1c90b 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -232,8 +232,6 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) // The caps only get drawn for the main layer but not for the overlay. if (mode == SKYMODE_MAINLAYER && tex != NULL) { - // if there's no shader we cannot use the default color from the buffer because the object color is part of the preset vertex attribute. - if (!gl.hasGLSL()) glDisableClientState(GL_COLOR_ARRAY); PalEntry pe = tex->tex->GetSkyCapColor(false); gl_RenderState.SetObjectColor(pe); gl_RenderState.EnableTexture(false); @@ -245,7 +243,6 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) gl_RenderState.Apply(); RenderRow(GL_TRIANGLE_FAN, rc); gl_RenderState.EnableTexture(true); - if (!gl.hasGLSL()) glEnableClientState(GL_COLOR_ARRAY); } gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.Apply(); @@ -522,9 +519,7 @@ void GLSkyPortal::DrawContents() gl_RenderState.EnableTexture(false); gl_RenderState.SetObjectColor(FadeColor); gl_RenderState.Apply(); - if (!gl.hasGLSL()) glDisableClientState(GL_COLOR_ARRAY); glDrawArrays(GL_TRIANGLES, 0, 12); - if (!gl.hasGLSL()) glEnableClientState(GL_COLOR_ARRAY); gl_RenderState.EnableTexture(true); } gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 00f2ccada..ab0586f58 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -199,18 +199,9 @@ void GLSprite::Draw(int pass) // non-black fog with subtractive style needs special treatment if (!gl_isBlack(Colormap.FadeColor)) { - if (gl.hasGLSL() && !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. @@ -668,7 +659,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.hasGLSL() || !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 ? @@ -737,7 +728,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) RenderStyle.CheckFuzz(); if (RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl.hasGLSL() && gl_fuzztype != 0) + if (gl_fuzztype != 0) { // Todo: implement shader selection here RenderStyle = LegacyRenderStyles[STYLE_Translucent]; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 2d6b78fd5..bf9d52066 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -71,7 +71,7 @@ void GLWall::CheckGlowing() { bottomglowcolor[3] = topglowcolor[3] = 0; - if (!gl_isFullbright(Colormap.LightColor, lightlevel) && gl.hasGLSL()) + if (!gl_isFullbright(Colormap.LightColor, lightlevel)) { FTexture *tex = TexMan[topflat]; if (tex != NULL && tex->isGlowing()) @@ -184,7 +184,7 @@ void GLWall::PutWall(bool translucent) list = list_indices[light][masked][!!(flags&GLWF_FOGGY)]; if (list == GLDL_LIGHT) { - if (gltexture->tex->gl_info.Brightmap && gl.hasGLSL()) list = GLDL_LIGHTBRIGHT; + if (gltexture->tex->gl_info.Brightmap) list = GLDL_LIGHTBRIGHT; if (flags & GLWF_GLOW) list = GLDL_LIGHTBRIGHT; } gl_drawinfo->drawlists[list].AddWall(this); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 2879ade62..8e3a4b955 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -291,60 +291,13 @@ void GLWall::RenderFogBoundary() { if (gl_fogmode && gl_fixedcolormap == 0) { - // with shaders this can be done properly - if (gl.hasGLSL()) - { - int rel = rellight + getExtraLight(); - gl_SetFog(lightlevel, rel, &Colormap, false); - gl_RenderState.SetEffect(EFF_FOGBOUNDARY); - gl_RenderState.EnableAlphaTest(false); - RenderWall(RWF_BLANK); - gl_RenderState.EnableAlphaTest(true); - gl_RenderState.SetEffect(EFF_NONE); - } - else - { - // If we use the fixed function pipeline (GL 2.x) - // 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; - - 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); - gl_RenderState.SetColor(fc[0], fc[1], fc[2], fogd1); - - // this case is special because it needs to change the color in the middle of the polygon so it cannot use the standard function - // This also needs no splits so it's relatively simple. - gl_RenderState.Apply(); - glBegin(GL_TRIANGLE_FAN); // only used on GL 2.x! - glVertex3f(glseg.x1, zbottom[0], glseg.y1); - glVertex3f(glseg.x1, ztop[0], glseg.y1); - glColor4fv(fc); - glVertex3f(glseg.x2, ztop[1], glseg.y2); - glVertex3f(glseg.x2, zbottom[1], glseg.y2); - glEnd(); - vertexcount += 4; - - 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.EnableAlphaTest(false); + RenderWall(RWF_BLANK); + gl_RenderState.EnableAlphaTest(true); + gl_RenderState.SetEffect(EFF_NONE); } } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 8f76b0571..219eaf115 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -208,7 +208,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { bool disablefullbright = false; FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL); - if (lump.isValid() && gl.hasGLSL()) + if (lump.isValid()) { FMaterial * tex=FMaterial::ValidateTexture(lump, false); if (tex) @@ -316,7 +316,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) vis.RenderStyle.CheckFuzz(); if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl.hasGLSL() && gl_fuzztype != 0) + if (gl_fuzztype != 0) { // Todo: implement shader selection here vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index b90974222..ca7f8be72 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -68,146 +68,142 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * static char buffer[10000]; FString error; - if (gl.hasGLSL()) + 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! +// + + FString vp_comb = "#version 130\n"; + if (gl.glslversion >= 3.3f) vp_comb = "#version 330 compatibility\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. + // todo when using shader storage buffers, add + // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. + 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) { - 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! - // - - FString vp_comb = "#version 130\n"; - if (gl.glslversion >= 3.3f) vp_comb = "#version 330 compatibility\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. - // todo when using shader storage buffers, add - // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. - 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 != '#') { - 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) { - 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); + // this looks like an old custom hardware shader. + // We need to replace the ProcessTexel call to make it work. - 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(); - - 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(); - } + fp_comb.Substitute("vec4 frag = ProcessTexel();", "vec4 frag = Process(vec4(1.0));"); } - else + fp_comb << pp_data.GetString().GetChars(); + + if (pp_data.GetString().IndexOf("ProcessLight") < 0) { - // Proc_prog_lump is not a lump name but the source itself (from generated shaders) - fp_comb << proc_prog_lump + 1; + 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(); } } - - 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); - - glLinkProgram(hShader); - - glGetShaderInfoLog(hVertProg, 10000, NULL, buffer); - if (*buffer) + else { - error << "Vertex shader:\n" << buffer << "\n"; + // Proc_prog_lump is not a lump name but the source itself (from generated shaders) + fp_comb << proc_prog_lump + 1; } - 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"); - muLightRange.Init(hShader, "uLightRange"); - 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"); - - timer_index = glGetUniformLocation(hShader, "timer"); - lights_index = glGetUniformLocation(hShader, "lights"); - - - glUseProgram(hShader); - - int texture_index = glGetUniformLocation(hShader, "texture2"); - if (texture_index > 0) glUniform1i(texture_index, 1); - - glUseProgram(0); - return !!linked; } - return false; + + 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); + + 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"); + muLightRange.Init(hShader, "uLightRange"); + 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"); + + timer_index = glGetUniformLocation(hShader, "timer"); + lights_index = glGetUniformLocation(hShader, "lights"); + + + glUseProgram(hShader); + + int texture_index = glGetUniformLocation(hShader, "texture2"); + if (texture_index > 0) glUniform1i(texture_index, 1); + + glUseProgram(0); + return !!linked; } //========================================================================== @@ -218,12 +214,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * FShader::~FShader() { - if (gl.hasGLSL()) - { - glDeleteProgram(hShader); - glDeleteShader(hVertProg); - glDeleteShader(hFragProg); - } + glDeleteProgram(hShader); + glDeleteShader(hVertProg); + glDeleteShader(hFragProg); } @@ -351,33 +344,30 @@ void FShaderManager::CompileShaders() try { mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; - if (gl.hasGLSL()) + for (int i = 0; defaultshaders[i].ShaderName != NULL; i++) { - for (int i = 0; defaultshaders[i].ShaderName != NULL; i++) - { - FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); - mTextureEffects.Push(shc); - } + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); + mTextureEffects.Push(shc); + } - for (unsigned i = 0; i < usershaders.Size(); i++) - { - FString name = ExtractFileBase(usershaders[i]); - FName sfn = name; + for (unsigned i = 0; i < usershaders.Size(); i++) + { + FString name = ExtractFileBase(usershaders[i]); + FName sfn = name; - FShader *shc = Compile(sfn, usershaders[i]); - mTextureEffects.Push(shc); - } + FShader *shc = Compile(sfn, usershaders[i]); + mTextureEffects.Push(shc); + } - for (int i = 0; i < MAX_EFFECTS; i++) + for (int i = 0; i < MAX_EFFECTS; i++) + { + FShader *eff = new FShader(effectshaders[i].ShaderName); + if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, + effectshaders[i].fp2, effectshaders[i].defines)) { - FShader *eff = new FShader(effectshaders[i].ShaderName); - if (!eff->Load(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; } } catch (CRecoverableError &err) @@ -398,22 +388,19 @@ void FShaderManager::CompileShaders() void FShaderManager::Clean() { - if (gl.hasGLSL()) - { - glUseProgram(0); - mActiveShader = NULL; + glUseProgram(0); + mActiveShader = NULL; - for (unsigned int i = 0; i < mTextureEffects.Size(); i++) - { - if (mTextureEffects[i] != NULL) delete mTextureEffects[i]; - } - for (int i = 0; i < MAX_EFFECTS; i++) - { - if (mEffectShaders[i] != NULL) delete mEffectShaders[i]; - mEffectShaders[i] = NULL; - } - mTextureEffects.Clear(); + for (unsigned int i = 0; i < mTextureEffects.Size(); i++) + { + if (mTextureEffects[i] != NULL) delete mTextureEffects[i]; } + for (int i = 0; i < MAX_EFFECTS; i++) + { + if (mEffectShaders[i] != NULL) delete mEffectShaders[i]; + mEffectShaders[i] = NULL; + } + mTextureEffects.Clear(); } //========================================================================== @@ -444,7 +431,7 @@ int FShaderManager::Find(const char * shn) void FShaderManager::SetActiveShader(FShader *sh) { - if (gl.hasGLSL() && mActiveShader != sh) + if (mActiveShader != sh) { glUseProgram(sh!= NULL? sh->GetHandle() : 0); mActiveShader = sh; diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 7d979f921..aaa9568f9 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -127,17 +127,13 @@ void gl_LoadExtensions() 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 GL 3.0 is required to run " GAMENAME ".\n"); } gl.version = strtod(version, NULL); gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL); - if (gl.version < 3.f) gl.glslversion = 0.f; - - // This loads any function pointers and flags that require a vaild render context to - // initialize properly gl.vendorstring=(char*)glGetString(GL_VENDOR); @@ -148,11 +144,6 @@ void gl_LoadExtensions() glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if (gl.version >= 3.f) - { - gl.flags|=RFL_FRAMEBUFFER; - } } //========================================================================== @@ -176,7 +167,7 @@ void gl_PrintStartupLog() Printf ("Max. texture units: %d\n", v); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); Printf ("Max. fragment uniforms: %d\n", v); - if (gl.hasGLSL()) gl.maxuniforms = v; + gl.maxuniforms = v; glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &v); Printf ("Max. vertex uniforms: %d\n", v); glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index d5346fa7d..74beb72a4 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -9,7 +9,6 @@ enum RenderFlags RFL_TEXTURE_COMPRESSION=1, RFL_TEXTURE_COMPRESSION_S3TC=2, - RFL_FRAMEBUFFER = 4, RFL_BUFFER_STORAGE = 8, RFL_SHADER_STORAGE_BUFFER = 16, RFL_BASEINDEX = 32, @@ -36,16 +35,6 @@ struct RenderContext { return maxuniforms>=2048? 128:64; } - - bool hasGLSL() const - { - return glslversion >= 1.3f; - } - - bool hasCompatibility() // will return false, once transition to a core profile is possible and a core profile is used. - { - return true; - } }; extern RenderContext gl; diff --git a/src/gl/system/gl_menu.cpp b/src/gl/system/gl_menu.cpp index 0518606b9..972b9421e 100644 --- a/src/gl/system/gl_menu.cpp +++ b/src/gl/system/gl_menu.cpp @@ -59,40 +59,4 @@ CUSTOM_CVAR (Float, vid_contrast, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // when they are actually valid. void gl_SetupMenu() { - if (!gl.hasGLSL()) - { - // 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; - } } diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 28cfa0e6d..18c4ebfdf 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -505,52 +505,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) glVertex2i(fb->Width, fb->Height); glEnd(); - 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); - - // Burn the new screen on top of it. - fb->wipeendscreen->Bind(1); - //BurnTexture->Bind(0, CM_DEFAULT); - - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0); - 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); - - - 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); + // the old burn warp code is obsolete and has to be replaced. // 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_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp index 837977145..59e84051e 100644 --- a/src/gl/textures/gl_hqresize.cpp +++ b/src/gl/textures/gl_hqresize.cpp @@ -224,10 +224,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 (inputTexture->bWarped && !gl.hasGLSL()) - return inputBuffer; - switch (inputTexture->UseType) { case FTexture::TEX_Sprite: diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index a2a83e5db..3330d1f0c 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -54,7 +54,6 @@ extern TexFilter_s TexFilter[]; extern int TexFormat[]; -EXTERN_CVAR(Bool, gl_clamp_per_texture) //=========================================================================== @@ -197,10 +196,6 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i { texformat = GL_R8; } - else if (gl.version <= 3.0f || gl.hasCompatibility()) - { - texformat = GL_ALPHA8; - } else { texformat = GL_RGBA8; @@ -251,16 +246,17 @@ 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); if (alphatexture && gl.version >= 3.3f) { static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } + + // 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) @@ -439,19 +435,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; } @@ -463,11 +455,8 @@ int FHardwareTexture::GetDepthBuffer() void FHardwareTexture::BindToFrameBuffer() { - if (gl.flags & RFL_FRAMEBUFFER) - { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTexID, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); - } + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTexID, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); } diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index d949addc8..b6d83eb52 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -85,7 +85,6 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches) for(int i=0;i<5;i++) gltexture[i]=NULL; HiresLump=-1; hirestexture = NULL; - currentwarp = 0; bHasColorkey = false; bIsTransparent = -1; bExpand = expandpatches; @@ -186,84 +185,6 @@ void FGLTexture::Clean(bool all) } } -//=========================================================================== -// -// 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 +192,7 @@ BYTE *FGLTexture::WarpBuffer(BYTE *buffer, int Width, int Height, int warp) // //=========================================================================== -unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp, bool alphatexture) +unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, bool alphatexture) { unsigned char * buffer; int W, H; @@ -329,21 +250,9 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b 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 || alphatexture); - } - currentwarp = warp; - currentwarptime = gl_frameMS; - - return buffer; + // [BB] Potentially upsample the buffer. + return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || alphatexture); } @@ -387,7 +296,7 @@ bool FGLTexture::CreatePatch() // //=========================================================================== -const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck, int warp) +const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck) { int usebright = false; @@ -414,15 +323,8 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla 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); @@ -439,7 +341,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(translation, w, h, false, hirescheck, warp); + buffer = CreateTexBuffer(translation, w, h, false, hirescheck); tex->ProcessData(buffer, w, h, false); } if (!hwtex->CreateTexture(buffer, w, h, true, texunit, translation)) @@ -464,7 +366,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla // Binds a sprite to the renderer // //=========================================================================== -const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, int warp, bool alphatexture) +const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, bool alphatexture) { bool usebright = false; int transparm = translation; @@ -474,15 +376,8 @@ const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, int 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()) + if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified()) { Clean(true); CreatePatch(); @@ -495,7 +390,7 @@ const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, int int w, h; // Create this texture - unsigned char * buffer = CreateTexBuffer(translation, w, h, bExpand, NULL, warp, alphatexture); + unsigned char * buffer = CreateTexBuffer(translation, w, h, bExpand, NULL, alphatexture); tex->ProcessData(buffer, w, h, true); if (!glpatch->CreateTexture(buffer, w, h, false, texunit, translation, alphatexture)) { @@ -625,7 +520,7 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand) { expanded = false; } - else if (gl.hasGLSL()) + else { if (tx->gl_info.shaderindex >= FIRST_USER_SHADER) { @@ -671,7 +566,7 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand) tex = tx; tx->gl_info.mExpanded = expanded; - FTexture *basetex = tx->GetRedirect(!gl.hasGLSL()); + FTexture *basetex = tx->GetRedirect(false); if (!expanded && !basetex->gl_info.mExpanded && basetex->UseType != FTexture::TEX_Sprite) { // check if the texture is just a simple redirect to a patch @@ -842,13 +737,13 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader) int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT; - int softwarewarp = gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); + gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); if (tex->bHasCanvas || tex->bWarped) clampmode = 0; else if (clampmode != -1) clampmode &= 3; else clampmode = 4; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL, softwarewarp); + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL); if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) { for(unsigned i=0;igl_info.SystemTexture->Bind(i+1, clampmode, 0, NULL, false); + layer->gl_info.SystemTexture->Bind(i+1, clampmode, 0, NULL); maxbound = i+1; } } @@ -889,13 +784,13 @@ void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; - int softwarewarp = gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); + gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); - const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, alphatexture); + const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, alphatexture); // The only multitexture effect usable on sprites is the brightmap. if (glpatch != NULL && shaderindex == 3) { - mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, 0, 0, false); + mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, 0, false); maxbound = 1; } // unbind everything from the last texture that's still active @@ -1013,7 +908,7 @@ void FMaterial::BindToFrameBuffer() if (mBaseLayer->gltexture[0] == NULL) { // must create the hardware texture first - mBaseLayer->Bind(0, 0, 0, NULL, 0); + mBaseLayer->Bind(0, 0, 0, NULL); FHardwareTexture::Unbind(0); } mBaseLayer->gltexture[0]->BindToFrameBuffer(); diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index e1a5e93cd..81f4dd10f 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -61,28 +61,24 @@ private: FHardwareTexture *gltexture[5]; FHardwareTexture *glpatch; - int currentwarp; - int currentwarptime; - bool bHasColorkey; // only for hires bool bExpand; float AlphaThreshold; unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture); - BYTE *WarpBuffer(BYTE *buffer, int Width, int Height, int warp); FHardwareTexture *CreateTexture(int clampmode); //bool CreateTexture(); bool CreatePatch(); - const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck, int warp); - const FHardwareTexture *BindPatch(int texunit, int translation, int warp, bool alphatexture); + const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck); + const FHardwareTexture *BindPatch(int texunit, int translation, bool alphatexture); public: FGLTexture(FTexture * tx, bool expandpatches); ~FGLTexture(); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp, bool alphatexture = false); + unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, bool alphatexture = false); void Clean(bool all); int Dump(int i); diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index 53adb9551..a864c7e3e 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -94,7 +94,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); From 1f0c69a0e9d7ab988497e2cfaa0501cb20a33045 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 21 Jun 2014 16:41:45 +0200 Subject: [PATCH 051/138] - some cleanup after GL 2.x code removal - reinstated burn warp with shader based code. --- src/gl/system/gl_interface.cpp | 56 -------------------------------- src/gl/system/gl_wipe.cpp | 23 ++++++++++++- src/gl/textures/gl_hwtexture.cpp | 4 +-- 3 files changed, 23 insertions(+), 60 deletions(-) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index aaa9568f9..42224767b 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -179,59 +179,3 @@ void gl_PrintStartupLog() } -//========================================================================== -// -// -// -//========================================================================== - -void gl_SetTextureMode(int type) -{ - 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_INVERSE) - { - 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_MODULATE) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } -} - -//} // extern "C" diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 18c4ebfdf..e2fe134f6 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -53,6 +53,7 @@ #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/utility/gl_templates.h" @@ -505,7 +506,27 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) glVertex2i(fb->Width, fb->Height); glEnd(); - // the old burn warp code is obsolete and has to be replaced. + gl_RenderState.SetTextureMode(TM_MODULATE); + gl_RenderState.SetEffect(EFF_BURN); + gl_RenderState.ResetColor(); + gl_RenderState.Apply(); + + // Burn the new screen on top of it. + fb->wipeendscreen->Bind(1); + + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0); + + 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.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_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 3330d1f0c..9d81b54ce 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -218,7 +218,6 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i // The texture must at least be initialized if no data is present. mipmap=false; - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, false); buffer=(unsigned char *)calloc(4,rw * (rh+1)); deletebuffer=true; //texheight=-h; @@ -228,8 +227,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. @@ -246,6 +243,7 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i if (deletebuffer) free(buffer); + if (mipmap && use_mipmapping && !forcenofiltering) glGenerateMipmap(GL_TEXTURE_2D); if (alphatexture && gl.version >= 3.3f) { static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; From e2e71e072e33a49e1a20277426120b5359323377 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 23 Jun 2014 09:26:29 +0200 Subject: [PATCH 052/138] removed error suppression code from shader compilation. With GL 2.x support the engine still had something to fall back on, with that removed it needs to abort. --- src/gl/shaders/gl_shader.cpp | 63 ++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index ca7f8be72..33381eb88 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -249,14 +249,14 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath shader = new FShader(ShaderName); if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str)) { - I_Error("Unable to load shader %s\n", ShaderName); + I_FatalError("Unable to load shader %s\n", ShaderName); } } catch(CRecoverableError &err) { if (shader != NULL) delete shader; shader = NULL; - I_Error("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage()); + I_FatalError("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage()); } return shader; } @@ -341,42 +341,32 @@ FShaderManager::~FShaderManager() void FShaderManager::CompileShaders() { - try + mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; + + for(int i=0;defaultshaders[i].ShaderName != NULL;i++) { - mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; - for (int i = 0; defaultshaders[i].ShaderName != NULL; i++) - { - FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); - mTextureEffects.Push(shc); - } - - for (unsigned i = 0; i < usershaders.Size(); i++) - { - FString name = ExtractFileBase(usershaders[i]); - FName sfn = name; - - FShader *shc = Compile(sfn, usershaders[i]); - mTextureEffects.Push(shc); - } - - for (int i = 0; i < MAX_EFFECTS; i++) - { - FShader *eff = new FShader(effectshaders[i].ShaderName); - if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, - effectshaders[i].fp2, effectshaders[i].defines)) - { - delete eff; - } - else mEffectShaders[i] = eff; - } + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); + mTextureEffects.Push(shc); } - catch (CRecoverableError &err) + + for(unsigned i = 0; i < usershaders.Size(); i++) { - // If shader compilation failed we can still run the fixed function mode so do that instead of aborting. - Printf("%s\n", err.GetMessage()); - Printf(PRINT_HIGH, "Failed to compile shaders. Reverting to fixed function mode\n"); - gl.glslversion = 0.0; - gl.flags &= ~RFL_BUFFER_STORAGE; + FString name = ExtractFileBase(usershaders[i]); + FName sfn = name; + + FShader *shc = Compile(sfn, usershaders[i]); + mTextureEffects.Push(shc); + } + + 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; } } @@ -458,6 +448,9 @@ void FShaderManager::SetWarpSpeed(unsigned int eff, float speed) } } +//========================================================================== +// +// // //========================================================================== From ffcb6cb70a5940b45d483a506b5ce0d25b4a3bde Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Jun 2014 11:00:21 +0200 Subject: [PATCH 053/138] - added second vertex coordinate attribute for model interpolation. --- src/gl/renderer/gl_renderstate.cpp | 9 ++++----- src/gl/renderer/gl_renderstate.h | 13 ++++++------- src/gl/shaders/gl_shader.cpp | 2 ++ src/gl/shaders/gl_shader.h | 7 +++++++ src/gl/system/gl_framebuffer.cpp | 5 +++++ wadsrc/static/shaders/glsl/main.vp | 4 +++- wadsrc/static/shaders/glsl/shaderdefs.i | 1 + 7 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 8ce695cbc..cf8604924 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -66,11 +66,8 @@ void FRenderState::Reset() { mTextureEnabled = true; mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false; - ffTextureEnabled = ffFogEnabled = false; - mSpecialEffect = ffSpecialEffect = EFF_NONE; - mFogColor.d = ffFogColor.d = -1; - ffFogDensity = 0; - mTextureMode = ffTextureMode = -1; + mFogColor.d = -1; + mTextureMode = -1; mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA; @@ -85,6 +82,7 @@ void FRenderState::Reset() mVertexBuffer = mCurrentVertexBuffer = NULL; mColormapState = CM_DEFAULT; mLightParms[3] = -1.f; + mSpecialEffect = EFF_NONE; } @@ -144,6 +142,7 @@ bool FRenderState::ApplyShader() activeShader->muFogColor.Set(mFogColor); activeShader->muObjectColor.Set(mObjectColor); activeShader->muDynLightColor.Set(mDynColor); + activeShader->muInterpolationFactor.Set(mInterpolationFactor); if (mGlowEnabled) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index c3ca1e273..1bfaf7135 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -56,6 +56,7 @@ class FRenderState bool mAlphaTest; int mBlendEquation; bool m2D; + float mInterpolationFactor; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FStateVec4 mColor; @@ -75,13 +76,6 @@ class FRenderState bool glAlphaTest; int glBlendEquation; - bool ffTextureEnabled; - bool ffFogEnabled; - int ffTextureMode; - int ffSpecialEffect; - PalEntry ffFogColor; - float ffFogDensity; - bool ApplyShader(); public: @@ -290,6 +284,11 @@ public: { m2D = on; } + + void SetInterpolationFactor(float fac) + { + mInterpolationFactor = fac; + } }; extern FRenderState gl_RenderState; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 33381eb88..76049eb1f 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -192,10 +192,12 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muGlowBottomPlane.Init(hShader, "uGlowBottomPlane"); muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muFixedColormap.Init(hShader, "uFixedColormap"); + muInterpolationFactor.Init(hShader, "uInterpolationFactor"); timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); + glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); glUseProgram(hShader); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 3497ed3b0..173a1c781 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -7,6 +7,12 @@ extern bool gl_shaderactive; +enum +{ + VATTR_VERTEX2 = 15 +}; + + //========================================================================== // // @@ -186,6 +192,7 @@ class FShader FUniform4f muGlowTopColor; FUniform4f muGlowBottomPlane; FUniform4f muGlowTopPlane; + FBufferedUniform1f muInterpolationFactor; int timer_index; int lights_index; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index d22c6a5ed..30f791d50 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -386,6 +386,11 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap) //========================================================================== bool OpenGLFrameBuffer::Begin2D(bool) { + glActiveTexture(GL_TEXTURE7); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glActiveTexture(GL_TEXTURE0); + glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 2cde5324b..5e7890a61 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -1,10 +1,12 @@ +in vec4 aVertex2; out vec4 pixelpos; out vec2 glowdist; + void main() { - vec4 worldcoord = ModelMatrix * gl_Vertex; + vec4 worldcoord = /* ModelMatrix * */ mix(gl_Vertex, aVertex2, uInterpolationFactor); vec4 eyeCoordPos = ViewMatrix * worldcoord; gl_FrontColor = gl_Color; diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index efedca5e5..5a36473bf 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -9,6 +9,7 @@ uniform vec4 uObjectColor; uniform vec4 uDynLightColor; uniform vec4 uFogColor; uniform float uDesaturationFactor; +uniform float uInterpolationFactor; // Fixed colormap stuff uniform int uFixedColormap; // 0, when no fixed colormap, 1 for a light value, 2 for a color blend, 3 for a fog layer From 9d1dbf4eab1ad27390f44e729b1e99d6bc522bd4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Jun 2014 14:08:44 +0200 Subject: [PATCH 054/138] - fixed: FBufferedUniform1f didn'T work because it used an int as its buffered value. --- src/gl/shaders/gl_shader.h | 2 +- wadsrc/static/shaders/glsl/main.vp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 173a1c781..d1518088d 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -80,7 +80,7 @@ public: class FBufferedUniform1f { - int mBuffer; + float mBuffer; int mIndex; public: diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 5e7890a61..66ef3b51e 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -6,7 +6,7 @@ out vec2 glowdist; void main() { - vec4 worldcoord = /* ModelMatrix * */ mix(gl_Vertex, aVertex2, uInterpolationFactor); + vec4 worldcoord = mix(gl_Vertex, aVertex2, uInterpolationFactor); vec4 eyeCoordPos = ViewMatrix * worldcoord; gl_FrontColor = gl_Color; From 1efc2938b77925bb931b1063e6aa2814aaae6dce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Jun 2014 23:24:16 +0200 Subject: [PATCH 055/138] - implement model vertex buffer and draw MD2 models using it instead of using the GLCommands from the model. --- src/gl/data/gl_vertexbuffer.cpp | 2 + src/gl/data/gl_vertexbuffer.h | 3 +- src/gl/models/gl_models.cpp | 77 ++++++++++++++- src/gl/models/gl_models.h | 15 ++- src/gl/models/gl_models_md2.cpp | 154 ++++++----------------------- src/gl/models/gl_models_md3.cpp | 1 + src/gl/renderer/gl_renderer.cpp | 2 + src/gl/renderer/gl_renderer.h | 2 + src/gl/scene/gl_skydome.cpp | 1 + wadsrc/static/shaders/glsl/main.vp | 2 +- 10 files changed, 122 insertions(+), 137 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 6ba9f794e..3ea401dcd 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -45,6 +45,7 @@ #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" @@ -332,6 +333,7 @@ void FFlatVertexBuffer::BindVBO() glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + glDisableVertexAttribArray(VATTR_VERTEX2); } } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index ad09fb5d9..a183a7a2e 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -193,6 +193,7 @@ struct FModelVertex 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. @@ -203,7 +204,7 @@ public: ~FModelVertexBuffer(); void BindVBO(); - void UpdateBufferPointers(int frame1, int frame2); + unsigned int SetupFrame(unsigned int frame1, unsigned int frame2, float factor); }; #define VMO ((FModelVertex*)NULL) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 0ee9c563f..f6aad15fa 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() { @@ -91,6 +92,76 @@ 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); + } + + 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); + +} + +FModelVertexBuffer::~FModelVertexBuffer() +{ + if (ibo_id != 0) + { + glDeleteBuffers(1, &ibo_id); + } +} + + +//=========================================================================== +// +// +// +//=========================================================================== + +void FModelVertexBuffer::BindVBO() +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); + //glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO->x); + //glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &VMO->u); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glEnableVertexAttribArray(VATTR_VERTEX2); +} + +//=========================================================================== +// +// 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) +{ + glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].x); + glTexCoordPointer(2, GL_FLOAT, 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; @@ -674,10 +745,14 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf, if (mdl!=NULL) { + gl_RenderState.SetVertexBuffer(GLRenderer->mModelVBO); + if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] ) mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, translation); else - mdl->RenderFrame(smf->skins[i], smf->modelframes[i], NULL, 0.f, translation); + mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smf->modelframes[i], 0.f, translation); + + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } } } diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index f9f8f4f22..00df383ba 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -107,7 +107,6 @@ protected: struct DMDLoD { FTriangle * triangles; - int * glCommands; }; @@ -116,27 +115,24 @@ protected: DMDInfo info; FTexture ** skins; FTexCoord * texCoords; - - unsigned int ib_index; - unsigned int ib_count; 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,DMDModelVertex * vertices, DMDModelVertex *vertices2, double inter); - 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; - ib_count = 0; + texCoords = NULL; } virtual ~FDMDModel(); @@ -195,6 +191,7 @@ class FMD3Model : public FModel unsigned int vindex; // contains numframes arrays of vertices unsigned int iindex; + unsigned int icount; MD3Surface() { diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index ccf604dca..df6d8f88e 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,10 +162,11 @@ 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]; - ib_count = 0; for(i = 0, frame = frames; i < info.numFrames; i++, frame++) { @@ -193,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; } @@ -240,10 +229,10 @@ 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; } @@ -254,83 +243,33 @@ void FDMDModel::BuildVertexBuffer(FModelVertexBuffer *buf) ModelFrame *frame = &frames[i]; DMDModelVertex *vert = frame->vertices; DMDModelVertex *norm = frame->normals; - void *glCommands = lods[0].glCommands; frame->vindex = buf->vbo_shadowdata.Size(); - for (char *pos = (char*)glCommands; *pos;) + + FTriangle *tri = lods[0].triangles; + + for (int i = 0; i < lodInfo[0].numTriangles; i++) { - int count = *(int *)pos; - pos += 4; - - // The type of primitive depends on the sign. - int primtype = count > 0 ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN; - count = abs(count); - - if (i == 0) - { - // build the index buffer - we'll use the same buffer for all frames so only create it once - unsigned int bufindex = buf->vbo_shadowdata.Size() - frame->vindex; - unsigned int bufp = bufindex; - - if (primtype == GL_TRIANGLE_STRIP) - { - for (int t = 0; t < count - 2; t++) - { - unsigned int *p = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(3)]; - if ((t & 1) == 0) - { - p[0] = bufp; - p[1] = bufp + 1; - p[2] = bufp + 2; - } - else - { - p[0] = bufp; - p[2] = bufp + 2; - p[1] = bufp + 1; - } - bufp++; - } - } - else - { - bufp++; - for (int t = 0; t < count - 2; t++) - { - unsigned int *p = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(3)]; - p[0] = bufindex; - p[1] = bufp; - p[2] = bufp + 1; - bufp++; - } - } - } - - while (count--) + for (int j = 0; j < 3; j++) { FModelVertex bvert; - FGLCommandVertex * v = (FGLCommandVertex *)pos; - pos += sizeof(FGLCommandVertex); + int ti = tri->textureIndices[j]; + int vi = tri->vertexIndices[j]; - bvert.Set(vert[v->index].xyz[0], vert[v->index].xyz[1], vert[v->index].xyz[2], v->s, v->t); - bvert.SetNormal(norm[v->index].xyz[0], norm[v->index].xyz[1], norm[v->index].xyz[2]); + 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 @@ -347,50 +286,10 @@ int FDMDModel::FindFrame(const char * name) //=========================================================================== // -// Render a set of GL commands using the given data. +// // //=========================================================================== -void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices, DMDModelVertex * vertices, DMDModelVertex *vertices2, double inter) -{ - char *pos; - FGLCommandVertex * v; - int count; - const bool interpolate = (vertices2 != NULL && inter != 0. && vertices != vertices2); - - 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); - if (!interpolate) - { - glVertex3fv(vertices[v->index].xyz); - } - else - { - float interp[3]; - for (int i = 0; i < 3; i++) - interp[i] = inter * vertices[v->index].xyz[i] + (1. - inter) * vertices2[v->index].xyz[i]; - glVertex3fv(interp); - } - } - glEnd(); - } -} - void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation) { if (frameno >= info.numFrames || frameno2 >= info.numFrames) return; @@ -406,7 +305,9 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double i tex->Bind(0, translation); - RenderGLCommands(lods[0].glCommands, info.numVertices, frames[frameno].vertices, frames[frameno2].vertices, inter); + gl_RenderState.Apply(); + GLRenderer->mModelVBO->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, inter); + glDrawArrays(GL_TRIANGLES, 0, lodInfo[0].numTriangles * 3); } @@ -464,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); @@ -496,9 +396,12 @@ 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); @@ -526,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 2c6f39d05..4ae403fb4 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -233,6 +233,7 @@ void FMD3Model::BuildVertexBuffer(FModelVertexBuffer *buf) buf->ibo_shadowdata.Push(surf->tris[k].VertIndex[l]); } } + surf->icount = buf->ibo_shadowdata.Size() - surf->iindex; } } diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 97cf6d10f..b2b3edd8e 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -109,6 +109,7 @@ void FGLRenderer::Initialize() mVBO = new FFlatVertexBuffer; mSkyVBO = new FSkyVertexBuffer; + mModelVBO = new FModelVertexBuffer; gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; SetupLevel(); @@ -123,6 +124,7 @@ FGLRenderer::~FGLRenderer() //if (mThreadManager != NULL) delete mThreadManager; if (mShaderManager != NULL) delete mShaderManager; if (mVBO != NULL) delete mVBO; + if (mModelVBO) delete mModelVBO; if (mSkyVBO != NULL) delete mSkyVBO; if (glpart2) delete glpart2; if (glpart) delete glpart; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 77a38e7ae..733123599 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -10,6 +10,7 @@ struct particle_t; class FCanvasTexture; class FFlatVertexBuffer; class FSkyVertexBuffer; +class FModelVertexBuffer; class OpenGLFrameBuffer; struct FDrawInfo; struct pspdef_t; @@ -71,6 +72,7 @@ public: FFlatVertexBuffer *mVBO; FSkyVertexBuffer *mSkyVBO; + FModelVertexBuffer *mModelVBO; FGLRenderer(OpenGLFrameBuffer *fb); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index ad3b1c90b..0d9026ea6 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -93,6 +93,7 @@ void FSkyVertexBuffer::BindVBO() glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); + glDisableVertexAttribArray(VATTR_VERTEX2); } diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 66ef3b51e..3ec5990b2 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -6,7 +6,7 @@ out vec2 glowdist; void main() { - vec4 worldcoord = mix(gl_Vertex, aVertex2, uInterpolationFactor); + vec4 worldcoord = ModelMatrix * mix(gl_Vertex, aVertex2, uInterpolationFactor); vec4 eyeCoordPos = ViewMatrix * worldcoord; gl_FrontColor = gl_Color; From 9c5cec0056ca64544293657acb05ce60b7289f74 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 30 Jun 2014 10:05:15 +0200 Subject: [PATCH 056/138] - draw wipes with buffers Only two things left that still use immediate mode directly: MD3 models and voxels. --- src/gl/system/gl_wipe.cpp | 114 ++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index e2fe134f6..e4627fd35 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -57,6 +57,7 @@ #include "gl/textures/gl_translate.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_templates.h" +#include "gl/data/gl_vertexbuffer.h" #ifndef _WIN32 struct POINT { @@ -283,30 +284,24 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.ResetColor(); gl_RenderState.Apply(); fb->wipestartscreen->Bind(0); - 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(); + + 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); gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f)); gl_RenderState.Apply(); - 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(); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); gl_RenderState.EnableAlphaTest(true); gl_RenderState.SetTextureMode(TM_MODULATE); @@ -351,16 +346,17 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.ResetColor(); gl_RenderState.Apply(); fb->wipeendscreen->Bind(0); - 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(); + 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; @@ -384,7 +380,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; @@ -400,16 +398,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; - 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); } } } @@ -495,16 +494,18 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.ResetColor(); gl_RenderState.Apply(); fb->wipestartscreen->Bind(0); - 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(); + 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.SetEffect(EFF_BURN); @@ -516,16 +517,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0); - 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(); + 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 From 54297acde4a3bd826e27656387657dab0ce9cfc3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 30 Jun 2014 13:30:10 +0200 Subject: [PATCH 057/138] - removed obsolete gl_lightbuffer code. This never worked properly and by now far better options are available to solve the problem of dynamic light data uploads. --- src/CMakeLists.txt | 1 - src/gl/dynlights/gl_lightbuffer.cpp | 243 ---------------------------- src/gl/dynlights/gl_lightbuffer.h | 66 -------- src/gl/renderer/gl_renderer.cpp | 1 - src/gl/scene/gl_drawinfo.cpp | 1 - src/gl/scene/gl_flats.cpp | 1 - src/gl/scene/gl_scene.cpp | 1 - src/gl/scene/gl_walls.cpp | 1 - 8 files changed, 315 deletions(-) delete mode 100644 src/gl/dynlights/gl_lightbuffer.cpp delete mode 100644 src/gl/dynlights/gl_lightbuffer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bf750ce80..fad134fc3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1086,7 +1086,6 @@ add_executable( zdoom WIN32 gl/dynlights/gl_dynlight.cpp gl/dynlights/gl_glow.cpp gl/dynlights/gl_dynlight1.cpp - gl/dynlights/gl_lightbuffer.cpp gl/shaders/gl_shader.cpp gl/shaders/gl_texshader.cpp gl/system/gl_interface.cpp diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp deleted file mode 100644 index 9f141e6af..000000000 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* -** gl_dynlight1.cpp -** dynamic light buffer for shader rendering -** -**--------------------------------------------------------------------------- -** Copyright 2009 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. -** 5. Full disclosure of the entire project's source code, except for third -** party libraries is mandatory. (NOTE: This clause is non-negotiable!) -** -** 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. -**--------------------------------------------------------------------------- -** -*/ - -#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" - - -//========================================================================== -// -// -// -//========================================================================== - -FLightBuffer::FLightBuffer() -{ - glGenBuffers(1, &mIDbuf_RGB); - glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_RGB); - - glGenBuffers(1, &mIDbuf_Position); - glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_Position); - - glGenTextures(1, &mIDtex_RGB); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_RGB); - gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, mIDbuf_RGB); - - glGenTextures(1, &mIDtex_Position); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_Position); - gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA32F, mIDbuf_Position); -} - - -//========================================================================== -// -// -// -//========================================================================== - -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); - -} - -//========================================================================== -// -// -// -//========================================================================== - -void FLightBuffer::BindTextures(int texunit1, int texunit2) -{ - glActiveTexture(texunit1); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_RGB); - glActiveTexture(texunit2); - glBindTexture(GL_TEXTURE_BUFFER, mIDtex_Position); - glActiveTexture(GL_TEXTURE0); -} - - -//========================================================================== -// -// This collects all currently actove -// -//========================================================================== - -void FLightBuffer::CollectLightSources() -{ - if (gl_dynlight_shader && gl_lights && GLRenderer->mLightCount && gl_fixedcolormap == CM_DEFAULT) - { - TArray pLights(100); - TArray pPos(100); - TThinkerIterator it(STAT_DLIGHT); - - ADynamicLight *light; - - while ((light = it.Next()) != NULL) - { - if (!(light->flags2 & MF2_DORMANT)) - { - 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); - } - else light->bufferindex = -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); - - } -} - - -//========================================================================== -// -// -// -//========================================================================== - -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) - { - mBuffer.Push(light->bufferindex); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FLightIndexBuffer::SendBuffer() -{ - glBindBuffer(GL_TEXTURE_BUFFER, mIDBuffer); - glBufferData(GL_TEXTURE_BUFFER, mBuffer.Size() * sizeof (short), &mBuffer[0], GL_STREAM_DRAW); - glBindBuffer(GL_TEXTURE_BUFFER, 0); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FLightIndexBuffer::BindTexture(int texunit1) -{ - glActiveTexture(texunit1); - glBindTexture(GL_TEXTURE_BUFFER, mIDTexture); - glActiveTexture(GL_TEXTURE0); -} - - - -#endif \ No newline at end of file diff --git a/src/gl/dynlights/gl_lightbuffer.h b/src/gl/dynlights/gl_lightbuffer.h deleted file mode 100644 index d0da46b98..000000000 --- a/src/gl/dynlights/gl_lightbuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -#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; -}; - -class FLightBuffer -{ - unsigned int mIDbuf_RGB; - unsigned int mIDbuf_Position; - - unsigned int mIDtex_RGB; - unsigned int mIDtex_Position; - -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(); - } - -}; - -#endif - -#endif \ No newline at end of file diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index b2b3edd8e..ece007c19 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -59,7 +59,6 @@ #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" diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 8c620d93e..7dcf6319e 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -50,7 +50,6 @@ #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" diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 7e327ab9c..9f0195307 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -56,7 +56,6 @@ #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/shaders/gl_shader.h" #include "gl/textures/gl_material.h" diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 4868d07bd..d013d7b30 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -65,7 +65,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" diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index bf9d52066..f720f1678 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" From 6efefd9b7f4098c878a04637dedd7bbd93413d58 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 30 Jun 2014 18:02:52 +0200 Subject: [PATCH 058/138] - use vertex buffer to render MD3 models. --- src/gl/models/gl_models.h | 3 --- src/gl/models/gl_models_md3.cpp | 39 ++++----------------------------- 2 files changed, 4 insertions(+), 38 deletions(-) diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 00df383ba..d608f9874 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -191,7 +191,6 @@ class FMD3Model : public FModel unsigned int vindex; // contains numframes arrays of vertices unsigned int iindex; - unsigned int icount; MD3Surface() { @@ -225,8 +224,6 @@ class FMD3Model : public FModel MD3Frame * frames; MD3Surface * surfaces; - void RenderTriangles(MD3Surface * surf, MD3Vertex * vert, MD3Vertex *vert2, double inter); - public: FMD3Model() { } virtual ~FMD3Model(); diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 4ae403fb4..cb9bb6c25 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" @@ -233,7 +234,6 @@ void FMD3Model::BuildVertexBuffer(FModelVertexBuffer *buf) buf->ibo_shadowdata.Push(surf->tris[k].VertIndex[l]); } } - surf->icount = buf->ibo_shadowdata.Size() - surf->iindex; } } @@ -247,36 +247,6 @@ int FMD3Model::FindFrame(const char * name) return -1; } -void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert, MD3Vertex *vert2, double inter) -{ - const bool interpolate = (vert2 != NULL && inter != 0. && vert != vert2); - - gl_RenderState.Apply(); - glBegin(GL_TRIANGLES); - 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); - if (!interpolate) - { - glVertex3f(vert[x].x, vert[x].z, vert[x].y); - } - else - { - float interp[3]; - interp[0] = inter * vert[x].x + (1. - inter) * vert2[x].x; - interp[1] = inter * vert[x].z + (1. - inter) * vert2[x].z; - interp[2] = inter * vert[x].y + (1. - inter) * vert2[x].y; - glVertex3fv(interp); - } - } - } - glEnd(); -} - void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation) { if (frameno>=numFrames || frameno2>=numFrames) return; @@ -299,10 +269,9 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i tex->Bind(0, translation); - MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices; - MD3Vertex* vertices2 = surf->vertices + frameno2 * surf->numVertices; - - RenderTriangles(surf, vertices1, vertices2, inter); + 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))); } } From f7105189036de62db1ddef10be818c21c20d18bb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 30 Jun 2014 18:10:55 +0200 Subject: [PATCH 059/138] - use a uniform array to store vertex data to render dynamic stuff on GL 3.x hardware without the ARB_buffer_storage extension. Due to the way the engine works it needs to render a lot of small primitives with frequent state changes. But due to the performance of buffer uploads it is impossible to upload each primitive's vertices to a buffer separately because buffer uploads nearly always stall the GPU. On the other hand, in order to reduce the amount of buffer uploads all the necessary state changes would have to be saved in an array until they can finally be used. This method also imposed an unacceptable overhead. Fortunately, uploading uniform arrays is very fast and doesn't cause GPU stalls, so now the engine puts the vertex data per primitive into a uniform array and uses a static vertex buffer to index the array in the vertex shader. This method offers the same performance as immediate mode but only uses core profile features. --- src/gl/data/gl_vertexbuffer.cpp | 60 +++++++++++++++++++++++++++--- src/gl/shaders/gl_shader.cpp | 8 ++++ src/gl/shaders/gl_shader.h | 7 ++++ wadsrc/static/shaders/glsl/main.vp | 28 +++++++++++++- 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 3ea401dcd..b6d33dacd 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -90,6 +90,14 @@ FFlatVertexBuffer::FFlatVertexBuffer() { vbo_shadowdata.Reserve(BUFFER_SIZE); map = &vbo_shadowdata[0]; + + FFlatVertex fill[20]; + for (int i = 0; i < 20; i++) + { + fill[i].Set(0, 0, 0, 100001.f, i); + } + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, 20 * sizeof(FFlatVertex), fill, GL_STATIC_DRAW); } mIndex = mCurIndex = 0; } @@ -109,15 +117,55 @@ FFlatVertexBuffer::~FFlatVertexBuffer() // //========================================================================== +CVAR(Bool, gl_testbuffer, false, 0) + void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count) { - glBegin(primtype); - for (unsigned int i = 0; i < count; i++) + if (!gl_testbuffer) // todo: remove the immediate mode calls once the uniform array method has been tested. { - glTexCoord2fv(&map[offset + i].u); - glVertex3fv(&map[offset + i].x); + glBegin(primtype); + for (unsigned int i = 0; i < count; i++) + { + glTexCoord2fv(&map[offset + i].u); + glVertex3fv(&map[offset + i].x); + } + glEnd(); + } + else + { + if (count > 20) + { + int start = offset; + FFlatVertex ff = map[offset]; + while (count > 20) + { + + if (primtype == GL_TRIANGLE_FAN) + { + // split up the fan into multiple sub-fans + map[offset] = map[start]; + glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, 20 * 5, &map[offset].x); + glDrawArrays(primtype, 0, 20); + offset += 18; + count -= 18; + } + else + { + // we only have triangle fans of this size so don't bother with strips and triangles here. + break; + } + } + map[offset] = map[start]; + glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, count * 5, &map[offset].x); + glDrawArrays(primtype, 0, count); + map[offset] = ff; + } + else + { + glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, count * 5, &map[offset].x); + glDrawArrays(primtype, 0, count); + } } - glEnd(); } //========================================================================== @@ -324,7 +372,7 @@ void FFlatVertexBuffer::CreateVBO() void FFlatVertexBuffer::BindVBO() { - if (gl.flags & RFL_BUFFER_STORAGE) + //if (gl.flags & RFL_BUFFER_STORAGE) { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 76049eb1f..bd96c1ce2 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -90,6 +90,13 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * if (gl.glslversion >= 3.3f) vp_comb = "#version 330 compatibility\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. // todo when using shader storage buffers, add // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. + + if (!(gl.flags & RFL_BUFFER_STORAGE)) + { + // we only want the uniform array hack in the shader if we actually need it. + vp_comb << "#define UNIFORM_VB\n"; + } + vp_comb << defines << i_data.GetString().GetChars(); FString fp_comb = vp_comb; @@ -196,6 +203,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); + fakevb_index = glGetUniformLocation(hShader, "fakeVB"); glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index d1518088d..b079e74c4 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -196,6 +196,9 @@ class FShader int timer_index; int lights_index; +public: + int fakevb_index; +private: int currentglowstate; int currentfixedcolormap; @@ -245,6 +248,10 @@ public: FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); void SetWarpSpeed(unsigned int eff, float speed); + FShader *GetActiveShader() const + { + return mActiveShader; + } FShader *Get(unsigned int eff) { diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 3ec5990b2..81b0601c5 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -3,10 +3,34 @@ in vec4 aVertex2; out vec4 pixelpos; out vec2 glowdist; +#ifdef UNIFORM_VB +uniform float fakeVB[100]; +#endif void main() { - vec4 worldcoord = ModelMatrix * mix(gl_Vertex, aVertex2, uInterpolationFactor); + +#ifdef UNIFORM_VB + vec4 vert; + vec4 tc; + + if (gl_MultiTexCoord0.x >= 100000.0) + { + int fakeVI = int(gl_MultiTexCoord0.y)*5; + vert = gl_Vertex + vec4(fakeVB[fakeVI], fakeVB[fakeVI+1], fakeVB[fakeVI+2], 0.0); + tc = vec4(fakeVB[fakeVI+3], fakeVB[fakeVI+4], 0.0, 0.0); + } + else + { + vert = gl_Vertex; + tc = gl_MultiTexCoord0; + } +#else + #define vert gl_Vertex + #define tc gl_MultiTexCoord0 +#endif + + vec4 worldcoord = ModelMatrix * mix(vert, aVertex2, uInterpolationFactor); vec4 eyeCoordPos = ViewMatrix * worldcoord; gl_FrontColor = gl_Color; @@ -25,7 +49,7 @@ void main() vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5); gl_TexCoord[0].xy = sst; #else - gl_TexCoord[0] = TextureMatrix * gl_MultiTexCoord0; + gl_TexCoord[0] = TextureMatrix * tc; #endif gl_Position = ProjectionMatrix * eyeCoordPos; From 5ee626459d1926fe96e11d3fb7bc47c9520f23e8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 30 Jun 2014 18:57:24 +0200 Subject: [PATCH 060/138] - use model vertex buffer to render voxels. --- src/gl/models/gl_voxels.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index c81dfcec0..ffd2a65de 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -305,7 +305,7 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 mIndices.Push(indx[0]); mIndices.Push(indx[1]); - mIndices.Push(indx[2]); + mIndices.Push(indx[3]); mIndices.Push(indx[1]); mIndices.Push(indx[3]); mIndices.Push(indx[2]); @@ -420,13 +420,7 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double int tex->Bind(0, translation); gl_RenderState.Apply(); - glBegin(GL_TRIANGLES); - for (unsigned i = 0; i < mIndices.Size(); i++) - { - FModelVertex *vert = &mVertices[mIndices[i]]; - glTexCoord2fv(&vert->u); - glVertex3fv(&vert->x); - } - glEnd(); + GLRenderer->mModelVBO->SetupFrame(vindex, vindex, 0.f); + glDrawElements(GL_TRIANGLES, mIndices.Size(), GL_UNSIGNED_INT, (void*)(intptr_t)(iindex * sizeof(unsigned int))); } From 9a6bc64381434e631c96358cba19159697b873a3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 1 Jul 2014 00:51:02 +0200 Subject: [PATCH 061/138] - use vertex array objects to manage vertex buffers. --- src/gl/data/gl_vertexbuffer.cpp | 42 ++++++++++++++++----------------- src/gl/data/gl_vertexbuffer.h | 6 ++--- src/gl/models/gl_models.cpp | 24 +++++-------------- src/gl/scene/gl_skydome.cpp | 15 +++++------- 4 files changed, 34 insertions(+), 53 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index b6d33dacd..d9d96c855 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -58,8 +58,10 @@ FVertexBuffer::FVertexBuffer() { - vbo_id = 0; + vao_id = vbo_id = 0; glGenBuffers(1, &vbo_id); + glGenVertexArrays(1, &vao_id); + } FVertexBuffer::~FVertexBuffer() @@ -68,6 +70,15 @@ FVertexBuffer::~FVertexBuffer() { glDeleteBuffers(1, &vbo_id); } + if (vao_id != 0) + { + glDeleteVertexArrays(1, &vao_id); + } +} + +void FVertexBuffer::BindVBO() +{ + glBindVertexArray(vao_id); } //========================================================================== @@ -100,6 +111,14 @@ FFlatVertexBuffer::FFlatVertexBuffer() glBufferData(GL_ARRAY_BUFFER, 20 * sizeof(FFlatVertex), fill, GL_STATIC_DRAW); } mIndex = mCurIndex = 0; + + glBindVertexArray(vao_id); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + 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); + glBindVertexArray(0); } FFlatVertexBuffer::~FFlatVertexBuffer() @@ -370,27 +389,6 @@ void FFlatVertexBuffer::CreateVBO() // //========================================================================== -void FFlatVertexBuffer::BindVBO() -{ - //if (gl.flags & RFL_BUFFER_STORAGE) - { - 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_COLOR_ARRAY); - glDisableVertexAttribArray(VATTR_VERTEX2); - } -} - -//========================================================================== -// -// -// -//========================================================================== - void FFlatVertexBuffer::CheckPlanes(sector_t *sector) { if (gl.flags & RFL_BUFFER_STORAGE) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index a183a7a2e..d9e259db6 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -15,11 +15,12 @@ class FVertexBuffer { protected: unsigned int vbo_id; + unsigned int vao_id; public: FVertexBuffer(); virtual ~FVertexBuffer(); - virtual void BindVBO() = 0; + void BindVBO(); }; struct FFlatVertex @@ -60,7 +61,6 @@ public: ~FFlatVertexBuffer(); void CreateVBO(); - void BindVBO(); void CheckUpdate(sector_t *sector); FFlatVertex *GetBuffer() @@ -162,7 +162,6 @@ public: FSkyVertexBuffer(); virtual ~FSkyVertexBuffer(); - virtual void BindVBO(); void RenderDome(FMaterial *tex, int mode); }; @@ -203,7 +202,6 @@ public: FModelVertexBuffer(); ~FModelVertexBuffer(); - void BindVBO(); unsigned int SetupFrame(unsigned int frame1, unsigned int frame2, float factor); }; diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index f6aad15fa..67ec241e3 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -109,11 +109,17 @@ FModelVertexBuffer::FModelVertexBuffer() 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); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(VATTR_VERTEX2); + glBindVertexArray(0); } FModelVertexBuffer::~FModelVertexBuffer() @@ -125,24 +131,6 @@ FModelVertexBuffer::~FModelVertexBuffer() } -//=========================================================================== -// -// -// -//=========================================================================== - -void FModelVertexBuffer::BindVBO() -{ - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); - //glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO->x); - //glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &VMO->u); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glEnableVertexAttribArray(VATTR_VERTEX2); -} - //=========================================================================== // // Sets up the buffer starts for frame interpolation diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 0d9026ea6..221f2203b 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -77,25 +77,22 @@ extern int skyfog; FSkyVertexBuffer::FSkyVertexBuffer() { CreateDome(); -} -FSkyVertexBuffer::~FSkyVertexBuffer() -{ -} - -void FSkyVertexBuffer::BindVBO() -{ + glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x); glTexCoordPointer(2, GL_FLOAT, sizeof(FSkyVertex), &VSO->u); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSkyVertex), &VSO->color); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glDisableVertexAttribArray(VATTR_VERTEX2); + glBindVertexArray(0); + } +FSkyVertexBuffer::~FSkyVertexBuffer() +{ +} //----------------------------------------------------------------------------- // From 92185f96ebf0e7afc8389ba9fb8a0c165082deec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 1 Jul 2014 09:52:41 +0200 Subject: [PATCH 062/138] - fixed overflow with storing a sprite's dynamic light color in a PalEntry. --- src/gl/renderer/gl_renderstate.cpp | 2 +- src/gl/renderer/gl_renderstate.h | 9 ++------- src/gl/shaders/gl_shader.h | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index cf8604924..64647b670 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -141,7 +141,7 @@ bool FRenderState::ApplyShader() activeShader->muLightParms.Set(mLightParms); activeShader->muFogColor.Set(mFogColor); activeShader->muObjectColor.Set(mObjectColor); - activeShader->muDynLightColor.Set(mDynColor); + activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muInterpolationFactor.Set(mInterpolationFactor); if (mGlowEnabled) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 1bfaf7135..f569c3eab 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -65,7 +65,7 @@ class FRenderState FStateVec4 mGlowTopPlane, mGlowBottomPlane; PalEntry mFogColor; PalEntry mObjectColor; - PalEntry mDynColor; + FStateVec4 mDynColor; int mEffectState; int mColormapState; @@ -184,12 +184,7 @@ public: void SetDynLight(float r, float g, float b) { - mDynColor = PalEntry(255, xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255)); - } - - void SetDynLight(PalEntry pe) - { - mDynColor = pe; + mDynColor.Set(r, g, b, 0); } void SetObjectColor(PalEntry pe) diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index b079e74c4..833f97fbb 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -186,7 +186,7 @@ class FShader FUniform4f muColormapRange; FBufferedUniform4i muLightRange; FBufferedUniformPE muFogColor; - FBufferedUniformPE muDynLightColor; + FBufferedUniform4f muDynLightColor; FBufferedUniformPE muObjectColor; FUniform4f muGlowBottomColor; FUniform4f muGlowTopColor; From a936629cec470e3c4bdf6bfcf9481c6bae39e5ec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 10 Jul 2014 10:33:07 +0200 Subject: [PATCH 063/138] - use default fragment shader for burn and stencil shader, with the time consuming parts disabled by a #define, to avoid code duplication. --- src/gl/shaders/gl_shader.cpp | 25 +++++++++++++++++++++++-- wadsrc/static/shaders/glsl/burn.vp | 7 ------- wadsrc/static/shaders/glsl/main.vp | 21 +++++++++++++++------ wadsrc/static/shaders/glsl/stencil.vp | 14 -------------- 4 files changed, 38 insertions(+), 29 deletions(-) delete mode 100644 wadsrc/static/shaders/glsl/burn.vp delete mode 100644 wadsrc/static/shaders/glsl/stencil.vp diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index bd96c1ce2..013e56709 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -212,6 +212,27 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int texture_index = glGetUniformLocation(hShader, "texture2"); if (texture_index > 0) glUniform1i(texture_index, 1); + + GLint binaryLength; + void* binary; + FILE* outfile; + GLenum binaryFormat; + // + // Retrieve the binary from the program object + // + glGetProgramiv(hShader, GL_PROGRAM_BINARY_LENGTH, &binaryLength); + binary = (void*)malloc(binaryLength); + glGetProgramBinary(hShader, binaryLength, NULL, &binaryFormat, binary); + + // + // Cache the program binary for future runs + // + outfile = fopen(name, "wb"); + fwrite(binary, binaryLength, 1, outfile); + fclose(outfile); + free(binary); + + glUseProgram(0); return !!linked; } @@ -316,8 +337,8 @@ static const FEffectShader effectshaders[]= { { "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "" }, { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n" }, - { "burn", "shaders/glsl/burn.vp", "shaders/glsl/burn.fp", NULL, "" }, - { "stencil", "shaders/glsl/stencil.vp", "shaders/glsl/stencil.fp", NULL, "" }, + { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", NULL, "#define SIMPLE\n" }, + { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\n" }, }; diff --git a/wadsrc/static/shaders/glsl/burn.vp b/wadsrc/static/shaders/glsl/burn.vp deleted file mode 100644 index 6a8d2b37b..000000000 --- a/wadsrc/static/shaders/glsl/burn.vp +++ /dev/null @@ -1,7 +0,0 @@ - -void main() -{ - gl_FrontColor = gl_Color; - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = ProjectionMatrix * gl_Vertex; -} diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 81b0601c5..f0bbdd413 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -1,7 +1,9 @@ +#ifndef SIMPLE // we do not need these for simple shaders in vec4 aVertex2; out vec4 pixelpos; out vec2 glowdist; +#endif #ifdef UNIFORM_VB uniform float fakeVB[100]; @@ -30,16 +32,23 @@ void main() #define tc gl_MultiTexCoord0 #endif - vec4 worldcoord = ModelMatrix * mix(vert, aVertex2, uInterpolationFactor); + #ifndef SIMPLE + vec4 worldcoord = ModelMatrix * mix(vert, aVertex2, uInterpolationFactor); + #else + vec4 worldcoord = ModelMatrix * vert; + #endif + vec4 eyeCoordPos = ViewMatrix * worldcoord; gl_FrontColor = gl_Color; - - pixelpos.xyz = worldcoord.xyz; - pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w; - glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y; - glowdist.y = worldcoord.y + ((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z); + #ifndef SIMPLE + pixelpos.xyz = worldcoord.xyz; + pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w; + + glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y; + glowdist.y = worldcoord.y + ((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z); + #endif #ifdef SPHEREMAP vec3 u = normalize(eyeCoordPos.xyz); diff --git a/wadsrc/static/shaders/glsl/stencil.vp b/wadsrc/static/shaders/glsl/stencil.vp deleted file mode 100644 index f5ac9fdd1..000000000 --- a/wadsrc/static/shaders/glsl/stencil.vp +++ /dev/null @@ -1,14 +0,0 @@ - -out vec4 pixelpos; - -void main() -{ - // perform exactly the same relevant steps as in the main shader to ensure matching results (that also means including the model matrix here!) - vec4 worldcoord = ModelMatrix * gl_Vertex; - vec4 eyeCoordPos = ViewMatrix * worldcoord; - - pixelpos.xyz = worldcoord.xyz; - pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w; - - gl_Position = ProjectionMatrix * eyeCoordPos; -} From 7cbffc7c14e0a3e7b68891bde39263db5e8905a8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 10 Jul 2014 10:35:02 +0200 Subject: [PATCH 064/138] - test code removal. --- src/gl/shaders/gl_shader.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 013e56709..a15d5a106 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -212,27 +212,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int texture_index = glGetUniformLocation(hShader, "texture2"); if (texture_index > 0) glUniform1i(texture_index, 1); - - GLint binaryLength; - void* binary; - FILE* outfile; - GLenum binaryFormat; - // - // Retrieve the binary from the program object - // - glGetProgramiv(hShader, GL_PROGRAM_BINARY_LENGTH, &binaryLength); - binary = (void*)malloc(binaryLength); - glGetProgramBinary(hShader, binaryLength, NULL, &binaryFormat, binary); - - // - // Cache the program binary for future runs - // - outfile = fopen(name, "wb"); - fwrite(binary, binaryLength, 1, outfile); - fclose(outfile); - free(binary); - - glUseProgram(0); return !!linked; } From d868f60f6c21c8df307b569e6dd947449870da09 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 12:14:12 +0200 Subject: [PATCH 065/138] - since the clip planes for plane mirrors did not work anymore I reimplemented them using shader based logic. It still needs to be seen if this affects performance on older hardware. --- src/CMakeLists.txt | 1 + src/gl/data/gl_matrix.cpp | 496 ++++++++++++++++++++++ src/gl/data/gl_matrix.h | 93 ++++ src/gl/renderer/gl_renderstate.cpp | 5 +- src/gl/renderer/gl_renderstate.h | 11 + src/gl/scene/gl_portal.cpp | 37 +- src/gl/scene/gl_portal.h | 2 +- src/gl/shaders/gl_shader.cpp | 1 + src/gl/shaders/gl_shader.h | 1 + wadsrc/static/shaders/glsl/fogboundary.fp | 6 + wadsrc/static/shaders/glsl/main.fp | 6 + wadsrc/static/shaders/glsl/shaderdefs.i | 1 + wadsrc/static/shaders/glsl/stencil.fp | 6 + 13 files changed, 650 insertions(+), 16 deletions(-) create mode 100644 src/gl/data/gl_matrix.cpp create mode 100644 src/gl/data/gl_matrix.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fad134fc3..efbeab3b5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1046,6 +1046,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 diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp new file mode 100644 index 000000000..589cfb8cc --- /dev/null +++ b/src/gl/data/gl_matrix.cpp @@ -0,0 +1,496 @@ +/* -------------------------------------------------- + +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 double +DegToRad(double degrees) +{ + return (double)(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( double *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; +} + + + +// glLoadIdentity 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; +} + + +// glMultMatrix implementation +void +VSMatrix::multMatrix(const double *aMatrix) +{ + + double 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(double)); +} + +// glMultMatrix implementation +void +VSMatrix::multMatrix(const float *aMatrix) +{ + + double 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(double)); +} + + + +// glLoadMatrix implementation +void +VSMatrix::loadMatrix(const double *aMatrix) +{ + memcpy(mMatrix, aMatrix, 16 * sizeof(double)); +} + +// glLoadMatrix implementation +void +VSMatrix::loadMatrix(const float *aMatrix) +{ + for (int i = 0; i < 16; ++i) + { + mMatrix[i] = aMatrix[i]; + } +} + + +// gl Translate implementation with matrix selection +void +VSMatrix::translate(double x, double y, double z) +{ + double mat[16]; + + setIdentityMatrix(mat); + mat[12] = x; + mat[13] = y; + mat[14] = z; + + multMatrix(mat); +} + + +// gl Scale implementation with matrix selection +void +VSMatrix::scale(double x, double y, double z) +{ + double 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(double angle, double x, double y, double z) +{ + double mat[16]; + double v[3]; + + v[0] = x; + v[1] = y; + v[2] = z; + + double radAngle = DegToRad(angle); + double co = cos(radAngle); + double si = sin(radAngle); + normalize(v); + double x2 = v[0]*v[0]; + double y2 = v[1]*v[1]; + double 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(double xPos, double yPos, double zPos, + double xLook, double yLook, double zLook, + double xUp, double yUp, double zUp) +{ + double 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); + + double 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(double fov, double ratio, double nearp, double farp) +{ + double projMatrix[16]; + + double f = 1.0f / tan (fov * (M_PI / 360.0f)); + + setIdentityMatrix(projMatrix,4); + + projMatrix[0] = f / ratio; + projMatrix[1 * 4 + 1] = f; + projMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp); + projMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp); + projMatrix[2 * 4 + 3] = -1.0f; + projMatrix[3 * 4 + 3] = 0.0f; + + multMatrix(projMatrix); +} + + +// glOrtho implementation +void +VSMatrix::ortho(double left, double right, + double bottom, double top, + double nearp, double farp) +{ + double m[16]; + + setIdentityMatrix(m,4); + + m[0 * 4 + 0] = 2 / (right - left); + m[1 * 4 + 1] = 2 / (top - bottom); + m[2 * 4 + 2] = -2 / (farp - nearp); + m[3 * 4 + 0] = -(right + left) / (right - left); + m[3 * 4 + 1] = -(top + bottom) / (top - bottom); + m[3 * 4 + 2] = -(farp + nearp) / (farp - nearp); + + multMatrix(m); +} + + +// glFrustum implementation +void +VSMatrix::frustum(double left, double right, + double bottom, double top, + double nearp, double farp) +{ + double 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 +double * +VSMatrix::get(MatrixTypes aType) +{ + return mMatrix[aType]; +} +*/ + + +/* ----------------------------------------------------- + SEND MATRICES TO OPENGL +------------------------------------------------------*/ + + + + +// universal +void +VSMatrix::matrixToGL(int loc) +{ + float copyto[16]; + copy(copyto); + glUniformMatrix4fv(loc, 1, false, copyto); +} + +// ----------------------------------------------------- +// AUX functions +// ----------------------------------------------------- + + +// Compute res = M * point +void +VSMatrix::multMatrixPoint(const double *point, double *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 double *a, const double *b, double *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 +double +VSMatrix::dotProduct(const double *a, const double *b) { + + double res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + + return res; +} + + +// Normalize a vec3 +void +VSMatrix::normalize(double *a) { + + double 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 double *a, const double *b, double *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 double *a, const double *b, double *res) { + + res[0] = b[0] + a[0]; + res[1] = b[1] + a[1]; + res[2] = b[2] + a[2]; +} + + +// returns |a| +double +VSMatrix::length(const double *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 double *aMatrix) +{ + + double 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]; + + double 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(double *resMat, const double *aMatrix) +{ + + double 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(double)); +} diff --git a/src/gl/data/gl_matrix.h b/src/gl/data/gl_matrix.h new file mode 100644 index 000000000..1ccbc5c37 --- /dev/null +++ b/src/gl/data/gl_matrix.h @@ -0,0 +1,93 @@ + +// 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 + +class VSMatrix { + + public: + + VSMatrix() + { + } + + VSMatrix(int) + { + loadIdentity(); + } + + void translate(double x, double y, double z); + void scale(double x, double y, double z); + void rotate(double angle, double x, double y, double z); + void loadIdentity(); + void multMatrix(const float *aMatrix); + void multMatrix(const double *aMatrix); + void multMatrix(const VSMatrix &aMatrix) + { + multMatrix(aMatrix.mMatrix); + } + void loadMatrix(const double *aMatrix); + void loadMatrix(const float *aMatrix); + void lookAt(double xPos, double yPos, double zPos, double xLook, double yLook, double zLook, double xUp, double yUp, double zUp); + void perspective(double fov, double ratio, double nearp, double farp); + void ortho(double left, double right, double bottom, double top, double nearp=-1.0f, double farp=1.0f); + void frustum(double left, double right, double bottom, double top, double nearp, double farp); + void copy(double * pDest) + { + memcpy(pDest, mMatrix, 16 * sizeof(double)); + } + + void copy(float * pDest) + { + for (int i = 0; i < 16; i++) + { + pDest[i] = (float)mMatrix[i]; + } + } + + void matrixToGL(int location); + void multMatrixPoint(const double *point, double *res); + + void computeNormalMatrix(const float *aMatrix); + void computeNormalMatrix(const double *aMatrix); + void computeNormalMatrix(const VSMatrix &aMatrix) + { + computeNormalMatrix(aMatrix.mMatrix); + } + + protected: + static void crossProduct(const double *a, const double *b, double *res); + static double dotProduct(const double *a, const double * b); + static void normalize(double *a); + static void subtract(const double *a, const double *b, double *res); + static void add(const double *a, const double *b, double *res); + static double length(const double *a); + static void multMatrix(double *resMatrix, const double *aMatrix); + + static void setIdentityMatrix(double *mat, int size = 4); + + /// The storage for matrices + double mMatrix[16]; + +}; + +#endif \ No newline at end of file diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 64647b670..83b630c91 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -83,6 +83,7 @@ void FRenderState::Reset() mColormapState = CM_DEFAULT; mLightParms[3] = -1.f; mSpecialEffect = EFF_NONE; + mClipHeight = 0.f; } @@ -114,12 +115,13 @@ bool FRenderState::ApplyShader() } else { + // todo: check how performance is affected by using 'discard' in a shader and if necessary create a separate set of discard-less shaders. activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); activeShader->Bind(); } int fogset = 0; - //glColor4fv(mColor.vec); + if (mFogEnabled) { if ((mFogColor & 0xffffff) == 0) @@ -143,6 +145,7 @@ bool FRenderState::ApplyShader() activeShader->muObjectColor.Set(mObjectColor); activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muInterpolationFactor.Set(mInterpolationFactor); + activeShader->muClipHeight.Set(mClipHeight); if (mGlowEnabled) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index f569c3eab..6653a7c0d 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -57,6 +57,7 @@ class FRenderState int mBlendEquation; bool m2D; float mInterpolationFactor; + float mClipHeight; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FStateVec4 mColor; @@ -100,6 +101,16 @@ public: mCurrentVertexBuffer = NULL; } + void SetClipHeight(float clip) + { + mClipHeight = clip; + } + + float GetClipHeight() + { + return mClipHeight; + } + void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mColor.Set(r, g, b, a); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index a7400ec22..276679b74 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -79,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; @@ -200,6 +201,7 @@ 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); gl_RenderState.ResetColor(); glDepthFunc(GL_LESS); @@ -235,7 +237,8 @@ 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; @@ -264,6 +267,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! } @@ -283,9 +287,8 @@ 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.GetClipHeight()); + gl_RenderState.SetClipHeight(0.f); // save viewpoint savedviewx=viewx; @@ -345,7 +348,11 @@ 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.SetClipHeight(f); + if (usestencil) { if (needdepth) FDrawInfo::EndDrawInfo(); @@ -360,6 +367,7 @@ void GLPortal::End(bool usestencil) GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); glColorMask(0,0,0,0); // no graphics + gl_RenderState.SetEffect(EFF_NONE); gl_RenderState.ResetColor(); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); @@ -386,7 +394,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. @@ -421,8 +430,10 @@ void GLPortal::End(bool usestencil) 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); @@ -778,18 +789,16 @@ void GLPlaneMirrorPortal::DrawContents() validcount++; + float f = FIXED2FLOAT(planez); + if (PlaneMirrorMode < 0) f -= 65536.f; // ceiling mirror: clip everytihng with a z lower than the portal's ceiling + else f += 65536.f; // floor mirror: clip everything with a z higher than the portal's floor + gl_RenderState.SetClipHeight(f); + PlaneMirrorFlag++; 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); - GLRenderer->DrawScene(); - glDisable(GL_CLIP_PLANE0+renderdepth); PlaneMirrorFlag--; PlaneMirrorMode=old_pm; } @@ -988,12 +997,12 @@ void GLHorizonPortal::DrawContents() gltexture->Bind(); + bool pushed = gl_SetPlaneTextureRotation(sp, gltexture); gl_RenderState.EnableAlphaTest(false); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); gl_RenderState.Apply(); - bool pushed = gl_SetPlaneTextureRotation(sp, gltexture); float vx=FIXED2FLOAT(viewx); float vy=FIXED2FLOAT(viewy); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 970fc3523..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,7 +102,6 @@ private: angle_t savedviewangle; AActor * savedviewactor; area_t savedviewarea; - unsigned char clipsave; GLPortal *NextPortal; TArray savedmapsection; TArray mPrimIndices; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index a15d5a106..f3b483461 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -200,6 +200,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muFixedColormap.Init(hShader, "uFixedColormap"); muInterpolationFactor.Init(hShader, "uInterpolationFactor"); + muClipHeight.Init(hShader, "uClipHeight"); timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 833f97fbb..eea46c8c8 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -193,6 +193,7 @@ class FShader FUniform4f muGlowBottomPlane; FUniform4f muGlowTopPlane; FBufferedUniform1f muInterpolationFactor; + FBufferedUniform1f muClipHeight; int timer_index; int lights_index; diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 0d4fb9a0d..264f8e8cd 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -9,6 +9,12 @@ in vec2 glowdist; void main() { +#ifndef NO_DISCARD + // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. + if (pixelpos.y > uClipHeight + 65536.0) discard; + if (pixelpos.y < uClipHeight - 65536.0) discard; +#endif + float fogdist; float fogfactor; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index afd075984..467723330 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -216,6 +216,12 @@ vec4 applyFog(vec4 frag, float fogfactor) void main() { +#ifndef NO_DISCARD + // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. + if (pixelpos.y > uClipHeight + 65536.0) discard; + if (pixelpos.y < uClipHeight - 65536.0) discard; +#endif + vec4 frag = ProcessTexel(); switch (uFixedColormap) diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 5a36473bf..198992fe6 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -1,6 +1,7 @@ // This file contains common data definitions for both vertex and fragment shader uniform vec4 uCameraPos; +uniform float uClipHeight; uniform int uTextureMode; diff --git a/wadsrc/static/shaders/glsl/stencil.fp b/wadsrc/static/shaders/glsl/stencil.fp index 9e4afec04..7cc579d9e 100644 --- a/wadsrc/static/shaders/glsl/stencil.fp +++ b/wadsrc/static/shaders/glsl/stencil.fp @@ -2,6 +2,12 @@ in vec4 pixelpos; void main() { +#ifndef NO_DISCARD + // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. + if (pixelpos.y > uClipHeight + 65536.0) discard; + if (pixelpos.y < uClipHeight - 65536.0) discard; +#endif + gl_FragColor = vec4(1.0); } From 60dc2e112214b623562744d0918a8dd43f635d59 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 13:01:35 +0200 Subject: [PATCH 066/138] - some shader fixes. --- wadsrc/static/shaders/glsl/stencil.fp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/wadsrc/static/shaders/glsl/stencil.fp b/wadsrc/static/shaders/glsl/stencil.fp index 7cc579d9e..9e4afec04 100644 --- a/wadsrc/static/shaders/glsl/stencil.fp +++ b/wadsrc/static/shaders/glsl/stencil.fp @@ -2,12 +2,6 @@ in vec4 pixelpos; void main() { -#ifndef NO_DISCARD - // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. - if (pixelpos.y > uClipHeight + 65536.0) discard; - if (pixelpos.y < uClipHeight - 65536.0) discard; -#endif - gl_FragColor = vec4(1.0); } From 00fcf4bc06d1af43990bb08ca51c5fa1f3986f05 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 13:25:42 +0200 Subject: [PATCH 067/138] - for some reason using world coordinates for clipping in the shader is somewhat imprecise so the clip plane heights have to be adjusted a bit for it. --- src/gl/renderer/gl_renderstate.cpp | 6 ++++-- src/gl/renderer/gl_renderstate.h | 20 +++++++++++++++----- src/gl/scene/gl_portal.cpp | 16 ++++++++++------ src/gl/shaders/gl_shader.cpp | 22 +++++++++++++++------- src/gl/shaders/gl_shader.h | 5 +++-- wadsrc/static/shaders/glsl/fogboundary.fp | 4 ++-- wadsrc/static/shaders/glsl/main.fp | 4 ++-- wadsrc/static/shaders/glsl/shaderdefs.i | 2 +- 8 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 83b630c91..6a510f85a 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -83,7 +83,8 @@ void FRenderState::Reset() mColormapState = CM_DEFAULT; mLightParms[3] = -1.f; mSpecialEffect = EFF_NONE; - mClipHeight = 0.f; + mClipHeightTop = 65536.f; + mClipHeightBottom = -65536.f; } @@ -145,7 +146,8 @@ bool FRenderState::ApplyShader() activeShader->muObjectColor.Set(mObjectColor); activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muInterpolationFactor.Set(mInterpolationFactor); - activeShader->muClipHeight.Set(mClipHeight); + activeShader->muClipHeightTop.Set(mClipHeightTop); + activeShader->muClipHeightBottom.Set(mClipHeightBottom); if (mGlowEnabled) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 6653a7c0d..815974d97 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -57,7 +57,7 @@ class FRenderState int mBlendEquation; bool m2D; float mInterpolationFactor; - float mClipHeight; + float mClipHeightTop, mClipHeightBottom; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FStateVec4 mColor; @@ -101,14 +101,24 @@ public: mCurrentVertexBuffer = NULL; } - void SetClipHeight(float clip) + void SetClipHeightTop(float clip) { - mClipHeight = clip; + mClipHeightTop = clip; } - float GetClipHeight() + float GetClipHeightTop() { - return mClipHeight; + 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) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 276679b74..28b9a1282 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -287,8 +287,10 @@ bool GLPortal::Start(bool usestencil, bool doquery) glDisable(GL_DEPTH_TEST); } } - planestack.Push(gl_RenderState.GetClipHeight()); - gl_RenderState.SetClipHeight(0.f); + planestack.Push(gl_RenderState.GetClipHeightTop()); + planestack.Push(gl_RenderState.GetClipHeightBottom()); + gl_RenderState.SetClipHeightTop(65536.f); + gl_RenderState.SetClipHeightBottom(-65536.f); // save viewpoint savedviewx=viewx; @@ -351,7 +353,9 @@ void GLPortal::End(bool usestencil) float f; planestack.Pop(f); - gl_RenderState.SetClipHeight(f); + gl_RenderState.SetClipHeightBottom(f); + planestack.Pop(f); + gl_RenderState.SetClipHeightTop(f); if (usestencil) { @@ -790,9 +794,9 @@ void GLPlaneMirrorPortal::DrawContents() validcount++; float f = FIXED2FLOAT(planez); - if (PlaneMirrorMode < 0) f -= 65536.f; // ceiling mirror: clip everytihng with a z lower than the portal's ceiling - else f += 65536.f; // floor mirror: clip everything with a z higher than the portal's floor - gl_RenderState.SetClipHeight(f); + // the coordinate fudging is needed because for some reason this is nowhere near precise and leaves gaps. Strange... + if (PlaneMirrorMode < 0) gl_RenderState.SetClipHeightTop(f+0.3f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling + else gl_RenderState.SetClipHeightBottom(f-0.3f); // floor mirror: clip everything with a z higher than the portal's floor PlaneMirrorFlag++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index f3b483461..50b67c4ca 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -200,7 +200,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muFixedColormap.Init(hShader, "uFixedColormap"); muInterpolationFactor.Init(hShader, "uInterpolationFactor"); - muClipHeight.Init(hShader, "uClipHeight"); + muClipHeightTop.Init(hShader, "uClipHeightTop"); + muClipHeightBottom.Init(hShader, "uClipHeightBottom"); timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); @@ -249,16 +250,18 @@ bool FShader::Bind() // //========================================================================== -FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath) +FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard) { + FString defines; // this can't be in the shader code due to ATI strangeness. - const char *str = (gl.MaxLights() == 128)? "#define MAXLIGHTS128\n" : ""; + if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n"; + if (!usediscard) defines += "#define NO_DISCARD\n"; FShader *shader = NULL; try { shader = new FShader(ShaderName); - if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str)) + if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, defines.GetChars())) { I_FatalError("Unable to load shader %s\n", ShaderName); } @@ -352,11 +355,16 @@ FShaderManager::~FShaderManager() void FShaderManager::CompileShaders() { - mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; + mActiveShader = NULL; + + for (int i = 0; i < MAX_EFFECTS; i++) + { + mEffectShaders[i] = NULL; + } for(int i=0;defaultshaders[i].ShaderName != NULL;i++) { - FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true); mTextureEffects.Push(shc); } @@ -365,7 +373,7 @@ void FShaderManager::CompileShaders() FString name = ExtractFileBase(usershaders[i]); FName sfn = name; - FShader *shc = Compile(sfn, usershaders[i]); + FShader *shc = Compile(sfn, usershaders[i], true); mTextureEffects.Push(shc); } diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index eea46c8c8..da3be18cb 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -193,7 +193,8 @@ class FShader FUniform4f muGlowBottomPlane; FUniform4f muGlowTopPlane; FBufferedUniform1f muInterpolationFactor; - FBufferedUniform1f muClipHeight; + FBufferedUniform1f muClipHeightTop; + FBufferedUniform1f muClipHeightBottom; int timer_index; int lights_index; @@ -244,7 +245,7 @@ class FShaderManager public: FShaderManager(); ~FShaderManager(); - FShader *Compile(const char *ShaderName, const char *ShaderPath); + FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard); int Find(const char *mame); FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 264f8e8cd..edf9384c6 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -11,8 +11,8 @@ void main() { #ifndef NO_DISCARD // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. - if (pixelpos.y > uClipHeight + 65536.0) discard; - if (pixelpos.y < uClipHeight - 65536.0) discard; + if (pixelpos.y > uClipHeightTop) discard; + if (pixelpos.y < uClipHeightBottom) discard; #endif float fogdist; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 467723330..5655493bd 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -218,8 +218,8 @@ void main() { #ifndef NO_DISCARD // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. - if (pixelpos.y > uClipHeight + 65536.0) discard; - if (pixelpos.y < uClipHeight - 65536.0) discard; + if (pixelpos.y > uClipHeightTop) discard; + if (pixelpos.y < uClipHeightBottom) discard; #endif vec4 frag = ProcessTexel(); diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 198992fe6..d281ee231 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -1,7 +1,7 @@ // This file contains common data definitions for both vertex and fragment shader uniform vec4 uCameraPos; -uniform float uClipHeight; +uniform float uClipHeightTop, uClipHeightBottom; uniform int uTextureMode; From 9230a20f18a22d7880813dd045854e02e57dcee2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 17:15:17 +0200 Subject: [PATCH 068/138] - added some checks to the wall rendering code that will allow to disable the clip planes in many cases, even when a plane mirror portal is active. This also solves the precision issue with using world coordinates for clip checks. --- src/gl/scene/gl_portal.cpp | 5 ++--- src/gl/scene/gl_walls_draw.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 28b9a1282..c0fee3385 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -794,9 +794,8 @@ void GLPlaneMirrorPortal::DrawContents() validcount++; float f = FIXED2FLOAT(planez); - // the coordinate fudging is needed because for some reason this is nowhere near precise and leaves gaps. Strange... - if (PlaneMirrorMode < 0) gl_RenderState.SetClipHeightTop(f+0.3f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling - else gl_RenderState.SetClipHeightBottom(f-0.3f); // floor mirror: clip everything with a z higher than the portal's floor + if (PlaneMirrorMode < 0) gl_RenderState.SetClipHeightTop(f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling + else gl_RenderState.SetClipHeightBottom(f); // floor mirror: clip everything with a z higher than the portal's floor PlaneMirrorFlag++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 8e3a4b955..aabec775e 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -225,7 +225,7 @@ void GLWall::SetupLights() void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store) { - texcoord tcs[4]; + 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)); if (!light) @@ -249,7 +249,14 @@ void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store if (!(textured & RWF_NORENDER)) { + // disable the clip plane if it isn't needed (which can be determined by a simple check.) + float ct = gl_RenderState.GetClipHeightTop(); + float cb = gl_RenderState.GetClipHeightBottom(); + if (ztop[0] <= ct && ztop[1] <= ct) gl_RenderState.SetClipHeightTop(65536.f); + if (zbottom[0] >= cb && zbottom[1] >= cb) gl_RenderState.SetClipHeightBottom(-65536.f); gl_RenderState.Apply(); + gl_RenderState.SetClipHeightTop(ct); + gl_RenderState.SetClipHeightBottom(cb); } // the rest of the code is identical for textured rendering and lights From dbb05c5f339d6e7ca40bfbfe19f96e4709c8b707 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 20:41:20 +0200 Subject: [PATCH 069/138] - remove use of builtin texture matrices. - make matrix class single precision. --- src/gl/data/gl_matrix.cpp | 124 +++++++++++++----------- src/gl/data/gl_matrix.h | 63 +++++++----- src/gl/models/gl_models.cpp | 56 +++-------- src/gl/renderer/gl_renderstate.cpp | 23 +++++ src/gl/renderer/gl_renderstate.h | 20 ++++ src/gl/scene/gl_drawinfo.cpp | 9 +- src/gl/scene/gl_drawinfo.h | 2 +- src/gl/scene/gl_flats.cpp | 32 +++--- src/gl/scene/gl_portal.cpp | 9 +- src/gl/scene/gl_scene.cpp | 8 -- src/gl/scene/gl_skydome.cpp | 13 +-- src/gl/shaders/gl_shader.cpp | 2 + src/gl/shaders/gl_shader.h | 6 ++ wadsrc/static/shaders/glsl/shaderdefs.i | 6 +- 14 files changed, 198 insertions(+), 175 deletions(-) diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index 589cfb8cc..c92f43c26 100644 --- a/src/gl/data/gl_matrix.cpp +++ b/src/gl/data/gl_matrix.cpp @@ -18,16 +18,16 @@ This is a simplified version of VSMatrix that has been adjusted for GZDoom's nee #include "doomtype.h" #include "gl/data/gl_matrix.h" -static inline double -DegToRad(double degrees) +static inline FLOATTYPE +DegToRad(FLOATTYPE degrees) { - return (double)(degrees * (M_PI / 180.0f)); + 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( double *mat, int size) { +VSMatrix::setIdentityMatrix( FLOATTYPE *mat, int size) { // fill matrix with 0s for (int i = 0; i < size * size; ++i) @@ -56,10 +56,10 @@ VSMatrix::loadIdentity() // glMultMatrix implementation void -VSMatrix::multMatrix(const double *aMatrix) +VSMatrix::multMatrix(const FLOATTYPE *aMatrix) { - double res[16]; + FLOATTYPE res[16]; for (int i = 0; i < 4; ++i) { @@ -72,15 +72,16 @@ VSMatrix::multMatrix(const double *aMatrix) } } } - memcpy(mMatrix, res, 16 * sizeof(double)); + memcpy(mMatrix, res, 16 * sizeof(FLOATTYPE)); } +#ifdef USE_DOUBLE // glMultMatrix implementation void VSMatrix::multMatrix(const float *aMatrix) { - double res[16]; + FLOATTYPE res[16]; for (int i = 0; i < 4; ++i) { @@ -93,18 +94,20 @@ VSMatrix::multMatrix(const float *aMatrix) } } } - memcpy(mMatrix, res, 16 * sizeof(double)); + memcpy(mMatrix, res, 16 * sizeof(FLOATTYPE)); } +#endif // glLoadMatrix implementation void -VSMatrix::loadMatrix(const double *aMatrix) +VSMatrix::loadMatrix(const FLOATTYPE *aMatrix) { - memcpy(mMatrix, aMatrix, 16 * sizeof(double)); + memcpy(mMatrix, aMatrix, 16 * sizeof(FLOATTYPE)); } +#ifdef USE_DOUBLE // glLoadMatrix implementation void VSMatrix::loadMatrix(const float *aMatrix) @@ -114,13 +117,14 @@ VSMatrix::loadMatrix(const float *aMatrix) mMatrix[i] = aMatrix[i]; } } +#endif // gl Translate implementation with matrix selection void -VSMatrix::translate(double x, double y, double z) +VSMatrix::translate(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z) { - double mat[16]; + FLOATTYPE mat[16]; setIdentityMatrix(mat); mat[12] = x; @@ -133,9 +137,9 @@ VSMatrix::translate(double x, double y, double z) // gl Scale implementation with matrix selection void -VSMatrix::scale(double x, double y, double z) +VSMatrix::scale(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z) { - double mat[16]; + FLOATTYPE mat[16]; setIdentityMatrix(mat,4); mat[0] = x; @@ -148,22 +152,22 @@ VSMatrix::scale(double x, double y, double z) // gl Rotate implementation with matrix selection void -VSMatrix::rotate(double angle, double x, double y, double z) +VSMatrix::rotate(FLOATTYPE angle, FLOATTYPE x, FLOATTYPE y, FLOATTYPE z) { - double mat[16]; - double v[3]; + FLOATTYPE mat[16]; + FLOATTYPE v[3]; v[0] = x; v[1] = y; v[2] = z; - double radAngle = DegToRad(angle); - double co = cos(radAngle); - double si = sin(radAngle); + FLOATTYPE radAngle = DegToRad(angle); + FLOATTYPE co = cos(radAngle); + FLOATTYPE si = sin(radAngle); normalize(v); - double x2 = v[0]*v[0]; - double y2 = v[1]*v[1]; - double z2 = v[2]*v[2]; + 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; @@ -194,11 +198,11 @@ VSMatrix::rotate(double angle, double x, double y, double z) // gluLookAt implementation void -VSMatrix::lookAt(double xPos, double yPos, double zPos, - double xLook, double yLook, double zLook, - double xUp, double yUp, double zUp) +VSMatrix::lookAt(FLOATTYPE xPos, FLOATTYPE yPos, FLOATTYPE zPos, + FLOATTYPE xLook, FLOATTYPE yLook, FLOATTYPE zLook, + FLOATTYPE xUp, FLOATTYPE yUp, FLOATTYPE zUp) { - double dir[3], right[3], up[3]; + FLOATTYPE dir[3], right[3], up[3]; up[0] = xUp; up[1] = yUp; up[2] = zUp; @@ -213,7 +217,7 @@ VSMatrix::lookAt(double xPos, double yPos, double zPos, crossProduct(right,dir,up); normalize(up); - double m1[16],m2[16]; + FLOATTYPE m1[16],m2[16]; m1[0] = right[0]; m1[4] = right[1]; @@ -247,11 +251,11 @@ VSMatrix::lookAt(double xPos, double yPos, double zPos, // gluPerspective implementation void -VSMatrix::perspective(double fov, double ratio, double nearp, double farp) +VSMatrix::perspective(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE farp) { - double projMatrix[16]; + FLOATTYPE projMatrix[16]; - double f = 1.0f / tan (fov * (M_PI / 360.0f)); + FLOATTYPE f = 1.0f / tan (fov * (M_PI / 360.0f)); setIdentityMatrix(projMatrix,4); @@ -268,11 +272,11 @@ VSMatrix::perspective(double fov, double ratio, double nearp, double farp) // glOrtho implementation void -VSMatrix::ortho(double left, double right, - double bottom, double top, - double nearp, double farp) +VSMatrix::ortho(FLOATTYPE left, FLOATTYPE right, + FLOATTYPE bottom, FLOATTYPE top, + FLOATTYPE nearp, FLOATTYPE farp) { - double m[16]; + FLOATTYPE m[16]; setIdentityMatrix(m,4); @@ -289,11 +293,11 @@ VSMatrix::ortho(double left, double right, // glFrustum implementation void -VSMatrix::frustum(double left, double right, - double bottom, double top, - double nearp, double farp) +VSMatrix::frustum(FLOATTYPE left, FLOATTYPE right, + FLOATTYPE bottom, FLOATTYPE top, + FLOATTYPE nearp, FLOATTYPE farp) { - double m[16]; + FLOATTYPE m[16]; setIdentityMatrix(m,4); @@ -312,7 +316,7 @@ VSMatrix::frustum(double left, double right, /* // returns a pointer to the requested matrix -double * +FLOATTYPE * VSMatrix::get(MatrixTypes aType) { return mMatrix[aType]; @@ -331,9 +335,13 @@ VSMatrix::get(MatrixTypes aType) 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 } // ----------------------------------------------------- @@ -343,7 +351,7 @@ VSMatrix::matrixToGL(int loc) // Compute res = M * point void -VSMatrix::multMatrixPoint(const double *point, double *res) +VSMatrix::multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *res) { for (int i = 0; i < 4; ++i) @@ -360,7 +368,7 @@ VSMatrix::multMatrixPoint(const double *point, double *res) // res = a cross b; void -VSMatrix::crossProduct(const double *a, const double *b, double *res) { +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]; @@ -369,10 +377,10 @@ VSMatrix::crossProduct(const double *a, const double *b, double *res) { // returns a . b -double -VSMatrix::dotProduct(const double *a, const double *b) { +FLOATTYPE +VSMatrix::dotProduct(const FLOATTYPE *a, const FLOATTYPE *b) { - double res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + FLOATTYPE res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; return res; } @@ -380,9 +388,9 @@ VSMatrix::dotProduct(const double *a, const double *b) { // Normalize a vec3 void -VSMatrix::normalize(double *a) { +VSMatrix::normalize(FLOATTYPE *a) { - double mag = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); + FLOATTYPE mag = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); a[0] /= mag; a[1] /= mag; @@ -392,7 +400,7 @@ VSMatrix::normalize(double *a) { // res = b - a void -VSMatrix::subtract(const double *a, const double *b, double *res) { +VSMatrix::subtract(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res) { res[0] = b[0] - a[0]; res[1] = b[1] - a[1]; @@ -402,7 +410,7 @@ VSMatrix::subtract(const double *a, const double *b, double *res) { // res = a + b void -VSMatrix::add(const double *a, const double *b, double *res) { +VSMatrix::add(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res) { res[0] = b[0] + a[0]; res[1] = b[1] + a[1]; @@ -411,8 +419,8 @@ VSMatrix::add(const double *a, const double *b, double *res) { // returns |a| -double -VSMatrix::length(const double *a) { +FLOATTYPE +VSMatrix::length(const FLOATTYPE *a) { return(sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])); @@ -429,10 +437,10 @@ M3(int i, int j) // computes the derived normal matrix for the view matrix void -VSMatrix::computeNormalMatrix(const double *aMatrix) +VSMatrix::computeNormalMatrix(const FLOATTYPE *aMatrix) { - double mMat3x3[9]; + FLOATTYPE mMat3x3[9]; mMat3x3[0] = aMatrix[0]; mMat3x3[1] = aMatrix[1]; @@ -446,7 +454,7 @@ VSMatrix::computeNormalMatrix(const double *aMatrix) mMat3x3[7] = aMatrix[9]; mMat3x3[8] = aMatrix[10]; - double det, invDet; + FLOATTYPE det, invDet; det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) + mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + @@ -476,10 +484,10 @@ VSMatrix::computeNormalMatrix(const double *aMatrix) // aux function resMat = resMat * aMatrix void -VSMatrix::multMatrix(double *resMat, const double *aMatrix) +VSMatrix::multMatrix(FLOATTYPE *resMat, const FLOATTYPE *aMatrix) { - double res[16]; + FLOATTYPE res[16]; for (int i = 0; i < 4; ++i) { @@ -492,5 +500,5 @@ VSMatrix::multMatrix(double *resMat, const double *aMatrix) } } } - memcpy(resMat, res, 16 * sizeof(double)); + memcpy(resMat, res, 16 * sizeof(FLOATTYPE)); } diff --git a/src/gl/data/gl_matrix.h b/src/gl/data/gl_matrix.h index 1ccbc5c37..de4b400da 100644 --- a/src/gl/data/gl_matrix.h +++ b/src/gl/data/gl_matrix.h @@ -22,6 +22,12 @@ #include +#ifdef USE_DOUBLE +typedef double FLOATTYPE; +#else +typedef float FLOATTYPE; +#endif + class VSMatrix { public: @@ -35,27 +41,32 @@ class VSMatrix { loadIdentity(); } - void translate(double x, double y, double z); - void scale(double x, double y, double z); - void rotate(double angle, double x, double y, double z); + 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); - void multMatrix(const double *aMatrix); +#endif + void multMatrix(const FLOATTYPE *aMatrix); void multMatrix(const VSMatrix &aMatrix) { multMatrix(aMatrix.mMatrix); } - void loadMatrix(const double *aMatrix); + void loadMatrix(const FLOATTYPE *aMatrix); +#ifdef USE_DOUBLE void loadMatrix(const float *aMatrix); - void lookAt(double xPos, double yPos, double zPos, double xLook, double yLook, double zLook, double xUp, double yUp, double zUp); - void perspective(double fov, double ratio, double nearp, double farp); - void ortho(double left, double right, double bottom, double top, double nearp=-1.0f, double farp=1.0f); - void frustum(double left, double right, double bottom, double top, double nearp, double farp); - void copy(double * pDest) +#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(double)); + memcpy(pDest, mMatrix, 16 * sizeof(FLOATTYPE)); } +#ifdef USE_DOUBLE void copy(float * pDest) { for (int i = 0; i < 16; i++) @@ -63,30 +74,38 @@ class VSMatrix { pDest[i] = (float)mMatrix[i]; } } +#endif + + const FLOATTYPE *get() const + { + return mMatrix; + } void matrixToGL(int location); - void multMatrixPoint(const double *point, double *res); + void multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *res); +#ifdef USE_DOUBLE void computeNormalMatrix(const float *aMatrix); - void computeNormalMatrix(const double *aMatrix); +#endif + void computeNormalMatrix(const FLOATTYPE *aMatrix); void computeNormalMatrix(const VSMatrix &aMatrix) { computeNormalMatrix(aMatrix.mMatrix); } protected: - static void crossProduct(const double *a, const double *b, double *res); - static double dotProduct(const double *a, const double * b); - static void normalize(double *a); - static void subtract(const double *a, const double *b, double *res); - static void add(const double *a, const double *b, double *res); - static double length(const double *a); - static void multMatrix(double *resMatrix, const double *aMatrix); + 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(double *mat, int size = 4); + static void setIdentityMatrix(FLOATTYPE *mat, int size = 4); /// The storage for matrices - double mMatrix[16]; + FLOATTYPE mMatrix[16]; }; diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 67ec241e3..adec46570 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -806,65 +806,41 @@ void gl_RenderModel(GLSprite * spr) // 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); - - 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); - - 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), &ModelToWorld, &NormalTransform, translation ); - } -#endif - + 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 ); - - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glActiveTexture(GL_TEXTURE0); - glMatrixMode(GL_MODELVIEW); + gl_RenderState.EnableModelMatrix(false); glDepthFunc(GL_LESS); if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] )) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 6a510f85a..6f7382c91 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -56,6 +56,8 @@ FRenderState gl_RenderState; CVAR(Bool, gl_direct_state_change, true, 0) +static VSMatrix identityMatrix(1); + //========================================================================== // // @@ -225,6 +227,27 @@ bool FRenderState::ApplyShader() activeShader->muColormapStart.Set(r, g, b, 1.f); } } + 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; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 815974d97..6c2965e22 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -4,6 +4,7 @@ #include #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" +#include "gl/data/gl_matrix.h" #include "c_cvars.h" #include "r_defs.h" @@ -58,6 +59,8 @@ class FRenderState bool m2D; float mInterpolationFactor; float mClipHeightTop, mClipHeightBottom; + bool mModelMatrixEnabled; + bool mTextureMatrixEnabled; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FStateVec4 mColor; @@ -80,6 +83,12 @@ class FRenderState bool ApplyShader(); public: + + VSMatrix mProjectionMatrix; + VSMatrix mViewMatrix; + VSMatrix mModelMatrix; + VSMatrix mTextureMatrix; + FRenderState() { Reset(); @@ -89,6 +98,7 @@ public: void SetupShader(int &shaderindex, float warptime); void Apply(); + void ApplyMatrices(); void SetVertexBuffer(FVertexBuffer *vb) { @@ -180,6 +190,16 @@ 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, z, y, 0); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 7dcf6319e..cac3bad6a 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -1083,10 +1083,9 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo float fviewy = FIXED2FLOAT(viewy); float fviewz = FIXED2FLOAT(viewz); + gl_SetPlaneTextureRotation(&plane, gltexture); gl_RenderState.Apply(); - bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); - float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz); float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz); @@ -1113,11 +1112,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); - 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..01a72701b 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -273,7 +273,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 9f0195307..6b449ded3 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -70,7 +70,7 @@ // //========================================================================== -bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture) +void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture) { // only manipulate the texture matrix if needed. if (secplane->xoffs != 0 || secplane->yoffs != 0 || @@ -93,15 +93,13 @@ bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte float xscale2=64.f/gltexture->TextureWidth(GLUSE_TEXTURE); float yscale2=64.f/gltexture->TextureHeight(GLUSE_TEXTURE); - 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; } @@ -377,13 +375,9 @@ void GLFlat::Draw(int pass) case GLPASS_TEXTURE: { gltexture->Bind(); - bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); + gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, false); - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } + gl_RenderState.EnableTextureMatrix(false); break; } @@ -440,13 +434,9 @@ void GLFlat::Draw(int pass) else { gltexture->Bind(); - bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture); + gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, true); - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } + gl_RenderState.EnableTextureMatrix(false); } if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index c0fee3385..557fbd106 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -1000,7 +1000,7 @@ void GLHorizonPortal::DrawContents() gltexture->Bind(); - bool pushed = gl_SetPlaneTextureRotation(sp, gltexture); + gl_SetPlaneTextureRotation(sp, gltexture); gl_RenderState.EnableAlphaTest(false); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); gl_RenderState.Apply(); @@ -1059,12 +1059,7 @@ void GLHorizonPortal::DrawContents() ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); - if (pushed) - { - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } - + gl_RenderState.EnableTextureMatrix(false); PortalAll.Unclock(); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index d013d7b30..e93df197c 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -286,14 +286,6 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) void FGLRenderer::SetViewMatrix(bool mirror, bool planemirror) { - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - glActiveTexture(GL_TEXTURE0); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); glLoadIdentity(); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 221f2203b..04f77a80f 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -293,20 +293,17 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in glScalef(1.f, 1.2f * 1.17f, 1.f); yscale = 240.f / texh; } - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - glScalef(mirror? -xscale : xscale, yscale, 1.f); - glTranslatef(1.f, y_offset / texh, 1.f); - glMatrixMode(GL_MODELVIEW); + 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); } GLRenderer->mSkyVBO->RenderDome(tex, mode); + gl_RenderState.EnableTextureMatrix(false); if (tex) { - glMatrixMode(GL_TEXTURE); - glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 50b67c4ca..79746e5c2 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -206,6 +206,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); fakevb_index = glGetUniformLocation(hShader, "fakeVB"); + modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix"); + texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix"); glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index da3be18cb..a87b1e576 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -198,11 +198,15 @@ class FShader int timer_index; int lights_index; + int modelmatrix_index; + int texturematrix_index; public: int fakevb_index; private: int currentglowstate; int currentfixedcolormap; + bool currentTextureMatrixState; + bool currentModelMatrixState; public: FShader(const char *name) @@ -211,6 +215,8 @@ public: hShader = hVertProg = hFragProg = 0; 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(); diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index d281ee231..ebe751c96 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -36,8 +36,8 @@ uniform ivec4 uLightRange; // redefine the matrix names to what they actually represent. -#define ModelMatrix gl_TextureMatrix[7] -#define ViewMatrix gl_ModelViewMatrix #define ProjectionMatrix gl_ProjectionMatrix -#define TextureMatrix gl_TextureMatrix[0] +#define ViewMatrix gl_ModelViewMatrix +uniform mat4 ModelMatrix; +uniform mat4 TextureMatrix; From 2214c0ac06081711244beb529703ff381d3b2223 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 22:37:34 +0200 Subject: [PATCH 070/138] - remove all uses of builtin matrix manipulation. Only glLoadMatrix for view and projection matrix are left. --- src/gl/data/gl_matrix.cpp | 37 ++++++++++--------------- src/gl/models/gl_models.cpp | 28 +++++++++---------- src/gl/renderer/gl_renderer.cpp | 7 +++-- src/gl/renderer/gl_renderstate.cpp | 10 +++++++ src/gl/renderer/gl_renderstate.h | 1 + src/gl/scene/gl_portal.cpp | 13 ++++----- src/gl/scene/gl_scene.cpp | 43 +++++++----------------------- src/gl/scene/gl_skydome.cpp | 38 +++++++++++++------------- src/gl/system/gl_framebuffer.cpp | 22 ++++----------- 9 files changed, 78 insertions(+), 121 deletions(-) diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index c92f43c26..aa98a3c66 100644 --- a/src/gl/data/gl_matrix.cpp +++ b/src/gl/data/gl_matrix.cpp @@ -253,20 +253,15 @@ VSMatrix::lookAt(FLOATTYPE xPos, FLOATTYPE yPos, FLOATTYPE zPos, void VSMatrix::perspective(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE farp) { - FLOATTYPE projMatrix[16]; - FLOATTYPE f = 1.0f / tan (fov * (M_PI / 360.0f)); - setIdentityMatrix(projMatrix,4); - - projMatrix[0] = f / ratio; - projMatrix[1 * 4 + 1] = f; - projMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp); - projMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp); - projMatrix[2 * 4 + 3] = -1.0f; - projMatrix[3 * 4 + 3] = 0.0f; - - multMatrix(projMatrix); + 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; } @@ -276,18 +271,14 @@ VSMatrix::ortho(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, FLOATTYPE nearp, FLOATTYPE farp) { - FLOATTYPE m[16]; + loadIdentity(); - setIdentityMatrix(m,4); - - m[0 * 4 + 0] = 2 / (right - left); - m[1 * 4 + 1] = 2 / (top - bottom); - m[2 * 4 + 2] = -2 / (farp - nearp); - m[3 * 4 + 0] = -(right + left) / (right - left); - m[3 * 4 + 1] = -(top + bottom) / (top - bottom); - m[3 * 4 + 2] = -(farp + nearp) / (farp - nearp); - - multMatrix(m); + 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); } diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index adec46570..3ea25aead 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -863,11 +863,6 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy) 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. @@ -879,28 +874,31 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy) 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(), NULL, 0 ); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); glDepthFunc(GL_LESS); if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] )) glDisable(GL_CULL_FACE); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index ece007c19..2f17ff99b 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -267,14 +267,13 @@ 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); + 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(); + gl_RenderState.ApplyMatrices(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(0, borderHeight, 0, 0, 0); ptr++; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 6f7382c91..95b0513b8 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -57,6 +57,7 @@ CVAR(Bool, gl_direct_state_change, true, 0) static VSMatrix identityMatrix(1); +TArray gl_MatrixStack; //========================================================================== // @@ -296,3 +297,12 @@ void FRenderState::Apply() ApplyShader(); } + + +void FRenderState::ApplyMatrices() +{ + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(mViewMatrix.get()); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(mProjectionMatrix.get()); +} diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 6c2965e22..d650e49b4 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -9,6 +9,7 @@ #include "r_defs.h" class FVertexBuffer; +extern TArray gl_MatrixStack; EXTERN_CVAR(Bool, gl_direct_state_change) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 557fbd106..922269636 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -117,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); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index e93df197c..bf11730aa 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -245,36 +245,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); } @@ -286,17 +261,15 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio) void FGLRenderer::SetViewMatrix(bool mirror, bool planemirror) { - 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); } @@ -310,6 +283,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(); } //----------------------------------------------------------------------------- @@ -887,6 +861,7 @@ 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(); clipper.Clear(); angle_t a1 = FrustumAngle(); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 04f77a80f..d2014c654 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -268,29 +268,30 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in if (tex) { - glPushMatrix(); tex->Bind(0, 0); texw = tex->TextureWidth(GLUSE_TEXTURE); texh = tex->TextureHeight(GLUSE_TEXTURE); + gl_RenderState.EnableModelMatrix(true); - glRotatef(-180.0f+x_offset, 0.f, 1.f, 0.f); + 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); + 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); @@ -301,13 +302,7 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in GLRenderer->mSkyVBO->RenderDome(tex, mode); gl_RenderState.EnableTextureMatrix(false); - - if (tex) - { - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - + gl_RenderState.EnableModelMatrix(false); } @@ -323,10 +318,12 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool int faces; FMaterial * tex; + gl_RenderState.EnableModelMatrix(true); + 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); + gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y); FFlatVertex *ptr; if (sb->faces[5]) @@ -456,6 +453,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool ptr->Set(-128.f, -128.f, 128.f, 1, 1); ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + gl_RenderState.EnableModelMatrix(false); } //----------------------------------------------------------------------------- @@ -477,8 +475,7 @@ void GLSkyPortal::DrawContents() gl_RenderState.EnableAlphaTest(false); 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) @@ -519,7 +516,8 @@ void GLSkyPortal::DrawContents() } gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } - glPopMatrix(); + gl_MatrixStack.Pop(gl_RenderState.mViewMatrix); + gl_RenderState.ApplyMatrices(); glset.lightmode = oldlightmode; } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 30f791d50..96abf833d 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" @@ -386,23 +387,10 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap) //========================================================================== bool OpenGLFrameBuffer::Begin2D(bool) { - glActiveTexture(GL_TEXTURE7); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glActiveTexture(GL_TEXTURE0); - glLoadIdentity(); - 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!!! From ce3653f6e1d2ccba096e2e9f0f59b3ba1c1be715 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 23:13:40 +0200 Subject: [PATCH 071/138] - remove all uses of builtin matrices. --- src/gl/data/gl_vertexbuffer.h | 4 +-- src/gl/renderer/gl_renderstate.cpp | 10 +++--- src/gl/scene/gl_flats.cpp | 4 +-- src/gl/shaders/gl_shader.cpp | 43 +++++++++++++++++++++++++ src/gl/shaders/gl_shader.h | 4 +++ wadsrc/static/shaders/glsl/shaderdefs.i | 4 +-- 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index d9e259db6..ff9d14278 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -80,7 +80,7 @@ public: #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(); + //drawcalls.Clock(); if (gl.flags & RFL_BUFFER_STORAGE) { glDrawArrays(primtype, offset, count); @@ -89,7 +89,7 @@ public: { ImmRenderBuffer(primtype, offset, count); } - drawcalls.Unclock(); + //drawcalls.Unclock(); } void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 95b0513b8..67a02440c 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -301,8 +301,10 @@ void FRenderState::Apply() void FRenderState::ApplyMatrices() { - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(mViewMatrix.get()); - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(mProjectionMatrix.get()); + drawcalls.Clock(); + if (GLRenderer->mShaderManager != NULL) + { + GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix); + } + drawcalls.Unclock(); } diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 6b449ded3..fb5da4fd2 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -298,9 +298,9 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); - drawcalls.Clock(); + //drawcalls.Clock(); glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); - drawcalls.Unclock(); + //drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 79746e5c2..1dbdada24 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -51,6 +51,7 @@ #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" @@ -206,6 +207,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * timer_index = glGetUniformLocation(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"); @@ -277,6 +280,19 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath return shader; } +//========================================================================== +// +// +// +//========================================================================== + +void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view) +{ + glProgramUniformMatrix4fv(hShader, projectionmatrix_index, 1, false, proj->get()); + glProgramUniformMatrix4fv(hShader, viewmatrix_index, 1, false, view->get()); +} + + //========================================================================== // // @@ -486,6 +502,33 @@ FShader *FShaderManager::BindEffect(int effect) } +//========================================================================== +// +// +// +//========================================================================== +EXTERN_CVAR(Int, gl_fuzztype) + +void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) +{ + for (int i = 0; i <= 4; i++) + { + mTextureEffects[i]->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); + } +} + //========================================================================== // // diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index a87b1e576..663d09122 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -198,6 +198,8 @@ class FShader int timer_index; int lights_index; + int projectionmatrix_index; + int viewmatrix_index; int modelmatrix_index; int texturematrix_index; public: @@ -230,6 +232,7 @@ public: bool Bind(); unsigned int GetHandle() const { return hShader; } + void ApplyMatrices(VSMatrix *proj, VSMatrix *view); }; @@ -256,6 +259,7 @@ public: FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); void SetWarpSpeed(unsigned int eff, float speed); + void ApplyMatrices(VSMatrix *proj, VSMatrix *view); FShader *GetActiveShader() const { return mActiveShader; diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index ebe751c96..867e9a709 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -36,8 +36,8 @@ uniform ivec4 uLightRange; // redefine the matrix names to what they actually represent. -#define ProjectionMatrix gl_ProjectionMatrix -#define ViewMatrix gl_ModelViewMatrix +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; uniform mat4 ModelMatrix; uniform mat4 TextureMatrix; From 150135a07d31a2fd5471a2d9907784ef705f0aee Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 13 Jul 2014 23:14:28 +0200 Subject: [PATCH 072/138] - reinstate drawcall timing. --- src/gl/data/gl_vertexbuffer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index ff9d14278..d9e259db6 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -80,7 +80,7 @@ public: #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(); + drawcalls.Clock(); if (gl.flags & RFL_BUFFER_STORAGE) { glDrawArrays(primtype, offset, count); @@ -89,7 +89,7 @@ public: { ImmRenderBuffer(primtype, offset, count); } - //drawcalls.Unclock(); + drawcalls.Unclock(); } void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL) From 1f2f7616e17e93b52f2bddf93433ffcb58038a88 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 14 Jul 2014 00:31:10 +0200 Subject: [PATCH 073/138] - remove timing of matrix application method --- src/gl/renderer/gl_renderstate.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 67a02440c..27e4465c1 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -301,10 +301,8 @@ void FRenderState::Apply() void FRenderState::ApplyMatrices() { - drawcalls.Clock(); if (GLRenderer->mShaderManager != NULL) { GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix); } - drawcalls.Unclock(); } From ed5ee4e8d196a27af348a769a55e11140786767b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 14 Jul 2014 18:48:46 +0200 Subject: [PATCH 074/138] - removed some obsolete init stuff and some deprecated constants. --- src/gl/system/gl_framebuffer.cpp | 12 +----------- src/gl/system/gl_interface.cpp | 1 - src/gl/textures/gl_hwtexture.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 96abf833d..e34eb5fce 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -138,7 +138,6 @@ 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); @@ -146,7 +145,7 @@ void OpenGLFrameBuffer::InitializeState() 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); @@ -154,15 +153,6 @@ void OpenGLFrameBuffer::InitializeState() 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); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 42224767b..5b99bd562 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -140,7 +140,6 @@ void gl_LoadExtensions() 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 (gl.version >= 4.f && CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; - if (gl.version >= 3.2f || CheckExtension("GL_ARB_draw_elements_base_vertex")) gl.flags |= RFL_BASEINDEX; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 9d81b54ce..516b5aaf5 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -253,9 +253,9 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i // 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; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapparam); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapparam); + clampmode = wrapparam==GL_CLAMP_TO_EDGE? GLT_CLAMPX|GLT_CLAMPY : 0; if (forcenofiltering) { @@ -469,7 +469,7 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int unsigned int * pTexID=GetTexID(translation); if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); - LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, alphatexture, texunit); + LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP_TO_EDGE, alphatexture, texunit); if (texunit != 0) glActiveTexture(GL_TEXTURE0); return *pTexID; } From 84a49e37eed36e939e05536bcd9859a751452b2b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 14 Jul 2014 19:54:07 +0200 Subject: [PATCH 075/138] - handle normals for spheremapped mirror surfaces using non-deprecated features. - move all WGL references out of global header files so that global wgl header include is no longer necessary --- src/gl/scene/gl_walls_draw.cpp | 9 ++++++++- src/win32/win32gliface.cpp | 23 +++++++++++++++++------ src/win32/win32gliface.h | 3 --- wadsrc/static/shaders/glsl/main.vp | 2 +- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index aabec775e..b932691de 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -321,7 +321,13 @@ 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); @@ -338,6 +344,7 @@ void GLWall::RenderMirrorSurface() flags &= ~GLWF_GLOW; RenderWall(RWF_BLANK); + gl_RenderState.EnableTextureMatrix(false); gl_RenderState.SetEffect(EFF_NONE); // Restore the defaults for the translucent pass diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 5623b7062..7b70e9172 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -1,5 +1,10 @@ #include "gl/system/gl_system.h" +#define DWORD WINDOWS_DWORD +#include +#undef DWORD + + #include "win32iface.h" #include "win32gliface.h" //#include "gl/gl_intern.h" @@ -22,6 +27,12 @@ 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 +592,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); @@ -612,7 +623,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; @@ -662,7 +673,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; @@ -736,7 +747,7 @@ bool Win32GLVideo::InitHardware (HWND Window, bool allowsoftware, int multisampl } m_hRC = 0; - if (wglCreateContextAttribsARB != NULL) + if (myWglCreateContextAttribsARB != NULL) { int ctxAttribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, @@ -746,7 +757,7 @@ bool Win32GLVideo::InitHardware (HWND Window, bool allowsoftware, int multisampl 0 }; - m_hRC = wglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); } if (m_hRC == 0) { diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index 4457c5372..f39a9f70b 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -46,8 +46,6 @@ public: 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: @@ -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/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index f0bbdd413..58ca931fb 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -52,7 +52,7 @@ void main() #ifdef SPHEREMAP vec3 u = normalize(eyeCoordPos.xyz); - vec3 n = normalize(gl_NormalMatrix * gl_Normal); + vec3 n = normalize(TextureMatrix * vec4(tc.x, 0.0, tc.y, 0.0); // use texture matrix and coordinates for our normal. Since this is only used on walls, the normal's y coordinate is always 0. vec3 r = reflect(u, n); float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) ); vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5); From ed8a21fd86d5f9636e6bb47f81c3e320166a4b61 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 14 Jul 2014 21:14:43 +0200 Subject: [PATCH 076/138] - replaced deprecated alpha testing with shader code. --- src/gl/renderer/gl_renderer.cpp | 4 +--- src/gl/renderer/gl_renderstate.cpp | 15 +------------- src/gl/renderer/gl_renderstate.h | 26 ++----------------------- src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_flats.cpp | 2 +- src/gl/scene/gl_portal.cpp | 2 +- src/gl/scene/gl_scene.cpp | 21 ++++++++------------ src/gl/scene/gl_skydome.cpp | 6 ++---- src/gl/scene/gl_sprite.cpp | 16 +++------------ src/gl/scene/gl_walls_draw.cpp | 10 ++++------ src/gl/scene/gl_weapon.cpp | 7 ++----- src/gl/shaders/gl_shader.cpp | 1 + src/gl/shaders/gl_shader.h | 1 + src/gl/system/gl_framebuffer.cpp | 1 - src/gl/system/gl_system.h | 4 +--- src/gl/system/gl_wipe.cpp | 6 +++--- wadsrc/static/shaders/glsl/main.fp | 6 ++++++ wadsrc/static/shaders/glsl/main.vp | 4 ++-- wadsrc/static/shaders/glsl/shaderdefs.i | 4 ++-- 19 files changed, 42 insertions(+), 96 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 2f17ff99b..ae2ba2125 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -383,7 +383,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip); gl_RenderState.SetColor(color); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.Apply(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); @@ -409,8 +409,6 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) 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); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 27e4465c1..917170872 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -75,8 +75,6 @@ void FRenderState::Reset() 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; mObjectColor = 0xffffffff; @@ -151,6 +149,7 @@ bool FRenderState::ApplyShader() activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muClipHeightTop.Set(mClipHeightTop); activeShader->muClipHeightBottom.Set(mClipHeightBottom); + activeShader->muAlphaThreshold.Set(mAlphaThreshold); if (mGlowEnabled) { @@ -269,18 +268,6 @@ void FRenderState::Apply() glDstBlend = mDstBlend; glBlendFunc(mSrcBlend, mDstBlend); } - if (mAlphaFunc != glAlphaFunc || mAlphaThreshold != glAlphaThreshold) - { - 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; diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index d650e49b4..d8168bca5 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -53,7 +53,6 @@ class FRenderState int mNumLights[4]; float *mLightData; int mSrcBlend, mDstBlend; - int mAlphaFunc; float mAlphaThreshold; bool mAlphaTest; int mBlendEquation; @@ -76,7 +75,6 @@ class FRenderState int mColormapState; int glSrcBlend, glDstBlend; - int glAlphaFunc; float glAlphaThreshold; bool glAlphaTest; int glBlendEquation; @@ -281,28 +279,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) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index e6d5c144f..98101c987 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -333,7 +333,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) // 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(); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index fb5da4fd2..91c7f1c7e 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -424,7 +424,7 @@ void GLFlat::Draw(int pass) if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE); 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); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 922269636..0cc602967 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -998,7 +998,7 @@ void GLHorizonPortal::DrawContents() gltexture->Bind(); gl_SetPlaneTextureRotation(sp, gltexture); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); gl_RenderState.Apply(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index bf11730aa..e6dc3098c 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -345,7 +345,7 @@ void FGLRenderer::RenderScene(int recursion) glDepthFunc(GL_LESS); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); glDisable(GL_POLYGON_OFFSET_FILL); // just in case @@ -374,8 +374,6 @@ void FGLRenderer::RenderScene(int recursion) gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(pass); - gl_RenderState.EnableAlphaTest(true); - // Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show if (!gl_texture) { @@ -383,7 +381,7 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.SetTextureMode(TM_MASK); } if (pass == GLPASS_BASE) pass = GLPASS_BASE_MASKED; - gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); gl_drawinfo->drawlists[GLDL_MASKED].Sort(); gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); gl_drawinfo->drawlists[GLDL_FOGMASKED].Sort(); @@ -440,10 +438,10 @@ void FGLRenderer::RenderScene(int recursion) glDepthFunc(GL_LEQUAL); if (gl_texture) { - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_drawinfo->drawlists[GLDL_LIGHT].Sort(); gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_TEXTURE); - gl_RenderState.EnableAlphaTest(true); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Sort(); gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_TEXTURE); gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Sort(); @@ -495,10 +493,9 @@ void FGLRenderer::RenderScene(int recursion) 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); @@ -523,8 +520,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); @@ -534,7 +530,7 @@ void FGLRenderer::RenderTranslucent() glDepthMask(true); - gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); RenderAll.Unclock(); } @@ -577,7 +573,7 @@ void FGLRenderer::DrawScene(bool toscreen) static void FillScreen() { - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); @@ -756,7 +752,6 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.ResetColor(); gl_RenderState.EnableTexture(true); - gl_RenderState.EnableAlphaTest(true); glDisable(GL_SCISSOR_TEST); } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index d2014c654..240bf6762 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -472,7 +472,7 @@ void GLSkyPortal::DrawContents() 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); gl_MatrixStack.Push(gl_RenderState.mViewMatrix); @@ -481,7 +481,6 @@ void GLSkyPortal::DrawContents() if (origin->texture[0] && origin->texture[0]->tex->gl_info.bSkybox) { RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2); - gl_RenderState.EnableAlphaTest(true); } else { @@ -495,8 +494,7 @@ void GLSkyPortal::DrawContents() 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]) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index ab0586f58..c70422b32 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -137,11 +137,11 @@ void GLSprite::Draw(int pass) 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) @@ -165,7 +165,7 @@ void GLSprite::Draw(int pass) minalpha*=factor; } - gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold); + gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, Colormap.desaturation); additivefog = true; } @@ -294,16 +294,6 @@ 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); - } } gl_RenderState.SetObjectColor(0xffffffff); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index b932691de..e28f6315c 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -301,9 +301,8 @@ void GLWall::RenderFogBoundary() int rel = rellight + getExtraLight(); gl_SetFog(lightlevel, rel, &Colormap, false); gl_RenderState.SetEffect(EFF_FOGBOUNDARY); - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); RenderWall(RWF_BLANK); - gl_RenderState.EnableAlphaTest(true); gl_RenderState.SetEffect(EFF_NONE); } } @@ -349,7 +348,7 @@ void GLWall::RenderMirrorSurface() // 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 @@ -383,8 +382,8 @@ 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; @@ -408,7 +407,6 @@ void GLWall::RenderTranslucentWall() // restore default settings if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (transparent) gl_RenderState.EnableAlphaTest(true); if (!gltexture) { diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 219eaf115..d0f2ab370 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -151,7 +151,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed if (tex->GetTransparent() || OverrideShader != 0) { - gl_RenderState.EnableAlphaTest(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); } gl_RenderState.Apply(); FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); @@ -164,10 +164,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed ptr->Set(x2, y2, 0, fU2, fV2); ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); - if (tex->GetTransparent() || OverrideShader != 0) - { - gl_RenderState.EnableAlphaTest(true); - } + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); } //========================================================================== diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 1dbdada24..4373955c2 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -203,6 +203,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muInterpolationFactor.Init(hShader, "uInterpolationFactor"); muClipHeightTop.Init(hShader, "uClipHeightTop"); muClipHeightBottom.Init(hShader, "uClipHeightBottom"); + muAlphaThreshold.Init(hShader, "uAlphaThreshold"); timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 663d09122..bed37cbb0 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -195,6 +195,7 @@ class FShader FBufferedUniform1f muInterpolationFactor; FBufferedUniform1f muClipHeightTop; FBufferedUniform1f muClipHeightBottom; + FBufferedUniform1f muAlphaThreshold; int timer_index; int lights_index; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index e34eb5fce..d3783fd42 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -150,7 +150,6 @@ void OpenGLFrameBuffer::InitializeState() 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); diff --git a/src/gl/system/gl_system.h b/src/gl/system/gl_system.h index 8140904a2..8273960f9 100644 --- a/src/gl/system/gl_system.h +++ b/src/gl/system/gl_system.h @@ -68,15 +68,13 @@ //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_wipe.cpp b/src/gl/system/gl_wipe.cpp index e4627fd35..12e7c9e02 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -280,7 +280,7 @@ 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); @@ -302,7 +302,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) 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.EnableAlphaTest(true); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); gl_RenderState.SetTextureMode(TM_MODULATE); return Clock >= 32; @@ -490,7 +490,7 @@ 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); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 5655493bd..30a815b3c 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -223,6 +223,12 @@ void main() #endif vec4 frag = ProcessTexel(); + +#ifndef NO_DISCARD + // alpha testing + if (frag.a <= uAlphaThreshold) discard; +#endif + switch (uFixedColormap) { diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 58ca931fb..7a434ccbe 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -52,8 +52,8 @@ void main() #ifdef SPHEREMAP vec3 u = normalize(eyeCoordPos.xyz); - vec3 n = normalize(TextureMatrix * vec4(tc.x, 0.0, tc.y, 0.0); // use texture matrix and coordinates for our normal. Since this is only used on walls, the normal's y coordinate is always 0. - vec3 r = reflect(u, n); + vec4 n = normalize(TextureMatrix * vec4(tc.x, 0.0, tc.y, 0.0)); // use texture matrix and coordinates for our normal. Since this is only used on walls, the normal's y coordinate is always 0. + vec3 r = reflect(u, n.xyz); float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) ); vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5); gl_TexCoord[0].xy = sst; diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 867e9a709..56e6965b2 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -4,6 +4,7 @@ uniform vec4 uCameraPos; uniform float uClipHeightTop, uClipHeightBottom; uniform int uTextureMode; +uniform float uAlphaThreshold; // colors uniform vec4 uObjectColor; @@ -34,8 +35,7 @@ uniform int uFogEnabled; // dynamic lights uniform ivec4 uLightRange; - -// redefine the matrix names to what they actually represent. +// matrices uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrix; uniform mat4 ModelMatrix; From 5193f6cfef8dde32d0b37005d94c726c09a6d01e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 00:19:41 +0200 Subject: [PATCH 077/138] - remove use of builtin deprecated varyings in shaders. --- wadsrc/static/shaders/glsl/burn.fp | 8 +++++--- wadsrc/static/shaders/glsl/func_brightmap.fp | 4 ++-- wadsrc/static/shaders/glsl/func_normal.fp | 2 +- wadsrc/static/shaders/glsl/func_warp1.fp | 2 +- wadsrc/static/shaders/glsl/func_warp2.fp | 2 +- wadsrc/static/shaders/glsl/func_wavex.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_jagged.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_noise.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_smooth.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_standard.fp | 2 +- wadsrc/static/shaders/glsl/fuzz_swirly.fp | 2 +- wadsrc/static/shaders/glsl/main.fp | 12 +++++++----- wadsrc/static/shaders/glsl/main.vp | 9 ++++++--- 15 files changed, 31 insertions(+), 24 deletions(-) diff --git a/wadsrc/static/shaders/glsl/burn.fp b/wadsrc/static/shaders/glsl/burn.fp index 8ccb553f8..d14748212 100644 --- a/wadsrc/static/shaders/glsl/burn.fp +++ b/wadsrc/static/shaders/glsl/burn.fp @@ -1,12 +1,14 @@ uniform sampler2D tex; uniform sampler2D texture2; +in vec4 vTexCoord; +in vec4 vColor; void main() { - vec4 frag = gl_Color; + vec4 frag = vColor; - vec4 t1 = texture2D(texture2, gl_TexCoord[0].xy); - vec4 t2 = texture2D(tex, vec2(gl_TexCoord[0].x, 1.0-gl_TexCoord[0].y)); + vec4 t1 = texture2D(texture2, vTexCoord.xy); + vec4 t2 = texture2D(tex, vec2(vTexCoord.x, 1.0-vTexCoord.y)); gl_FragColor = frag * vec4(t1.r, t1.g, t1.b, t2.a); } diff --git a/wadsrc/static/shaders/glsl/func_brightmap.fp b/wadsrc/static/shaders/glsl/func_brightmap.fp index b8b2a9f20..bea336eb6 100644 --- a/wadsrc/static/shaders/glsl/func_brightmap.fp +++ b/wadsrc/static/shaders/glsl/func_brightmap.fp @@ -2,11 +2,11 @@ uniform sampler2D texture2; vec4 ProcessTexel() { - return getTexel(gl_TexCoord[0].st); + return getTexel(vTexCoord.st); } vec4 ProcessLight(vec4 color) { - vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].st)); + 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_normal.fp b/wadsrc/static/shaders/glsl/func_normal.fp index d3b0d182c..184c14851 100644 --- a/wadsrc/static/shaders/glsl/func_normal.fp +++ b/wadsrc/static/shaders/glsl/func_normal.fp @@ -1,6 +1,6 @@ vec4 ProcessTexel() { - return getTexel(gl_TexCoord[0].st); + return getTexel(vTexCoord.st); } diff --git a/wadsrc/static/shaders/glsl/func_warp1.fp b/wadsrc/static/shaders/glsl/func_warp1.fp index 2dbf8a420..891eaa936 100644 --- a/wadsrc/static/shaders/glsl/func_warp1.fp +++ b/wadsrc/static/shaders/glsl/func_warp1.fp @@ -2,7 +2,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; const float pi = 3.14159265358979323846; vec2 offset = vec2(0,0); diff --git a/wadsrc/static/shaders/glsl/func_warp2.fp b/wadsrc/static/shaders/glsl/func_warp2.fp index 78044f970..7cc5e7ebb 100644 --- a/wadsrc/static/shaders/glsl/func_warp2.fp +++ b/wadsrc/static/shaders/glsl/func_warp2.fp @@ -2,7 +2,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; const float pi = 3.14159265358979323846; vec2 offset = vec2(0.0,0.0); diff --git a/wadsrc/static/shaders/glsl/func_wavex.fp b/wadsrc/static/shaders/glsl/func_wavex.fp index 5172239c7..e4230ae87 100644 --- a/wadsrc/static/shaders/glsl/func_wavex.fp +++ b/wadsrc/static/shaders/glsl/func_wavex.fp @@ -2,7 +2,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; const float pi = 3.14159265358979323846; diff --git a/wadsrc/static/shaders/glsl/fuzz_jagged.fp b/wadsrc/static/shaders/glsl/fuzz_jagged.fp index 103f34689..c088c7b30 100644 --- a/wadsrc/static/shaders/glsl/fuzz_jagged.fp +++ b/wadsrc/static/shaders/glsl/fuzz_jagged.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec2 texSplat; const float pi = 3.14159265358979323846; diff --git a/wadsrc/static/shaders/glsl/fuzz_noise.fp b/wadsrc/static/shaders/glsl/fuzz_noise.fp index 02985a122..9f5da5f25 100644 --- a/wadsrc/static/shaders/glsl/fuzz_noise.fp +++ b/wadsrc/static/shaders/glsl/fuzz_noise.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_smooth.fp b/wadsrc/static/shaders/glsl/fuzz_smooth.fp index 597debb53..4261d5415 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smooth.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smooth.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); float texX = texCoord.x / 3.0 + 0.66; diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp b/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp index 196cca33a..bfe04ec16 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smoothnoise.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + 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; diff --git a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp index bfd60de57..75bee0330 100644 --- a/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp +++ b/wadsrc/static/shaders/glsl/fuzz_smoothtranslucent.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); float texX = sin(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 a1bd0ebaf..fd87eaa46 100644 --- a/wadsrc/static/shaders/glsl/fuzz_standard.fp +++ b/wadsrc/static/shaders/glsl/fuzz_standard.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0; diff --git a/wadsrc/static/shaders/glsl/fuzz_swirly.fp b/wadsrc/static/shaders/glsl/fuzz_swirly.fp index de91e47d6..86a66ac8e 100644 --- a/wadsrc/static/shaders/glsl/fuzz_swirly.fp +++ b/wadsrc/static/shaders/glsl/fuzz_swirly.fp @@ -3,7 +3,7 @@ uniform float timer; vec4 ProcessTexel() { - vec2 texCoord = gl_TexCoord[0].st; + vec2 texCoord = vTexCoord.st; vec4 basicColor = getTexel(texCoord); float texX = sin(texCoord.x * 100.0 + timer*5.0); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 30a815b3c..6bb96aa9a 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -1,6 +1,8 @@ in vec4 pixelpos; in vec2 glowdist; +in vec4 vTexCoord; +in vec4 vColor; #ifdef SHADER_STORAGE_LIGHTS layout(std430, binding = 3) buffer ParameterBuffer @@ -120,7 +122,7 @@ float R_DoomLightingEquation(float light, float dist) vec4 getLightColor(float fogdist, float fogfactor) { - vec4 color = gl_Color; + vec4 color = vColor; if (uLightLevel >= 0.0) { @@ -193,7 +195,7 @@ vec4 getLightColor(float fogdist, float fogfactor) color.rgb = clamp(color.rgb + desaturate(dynlight).rgb, 0.0, 1.4); // prevent any unintentional messing around with the alpha. - return vec4(color.rgb, gl_Color.a); + return vec4(color.rgb, vColor.a); } //=========================================================================== @@ -291,14 +293,14 @@ void main() { float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14); vec4 cm = uFixedColormapStart + gray * uFixedColormapRange; - frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a*gl_Color.a); + frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a*vColor.a); break; } case 2: { frag = frag * uFixedColormapStart; - frag.a *= gl_Color.a; + frag.a *= vColor.a; break; } @@ -320,7 +322,7 @@ void main() } fogfactor = exp2 (uFogDensity * fogdist); - frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * gl_Color.a); + frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a); break; } } diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 7a434ccbe..e1349857e 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -5,6 +5,9 @@ out vec4 pixelpos; out vec2 glowdist; #endif +out vec4 vTexCoord; +out vec4 vColor; + #ifdef UNIFORM_VB uniform float fakeVB[100]; #endif @@ -40,7 +43,7 @@ void main() vec4 eyeCoordPos = ViewMatrix * worldcoord; - gl_FrontColor = gl_Color; + vColor = gl_Color; #ifndef SIMPLE pixelpos.xyz = worldcoord.xyz; @@ -56,9 +59,9 @@ void main() vec3 r = reflect(u, n.xyz); float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) ); vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5); - gl_TexCoord[0].xy = sst; + vTexCoord.xy = sst; #else - gl_TexCoord[0] = TextureMatrix * tc; + vTexCoord = TextureMatrix * tc; #endif gl_Position = ProjectionMatrix * eyeCoordPos; From 5a322742c350007b5f2b715de7e565673e78a635 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 00:37:13 +0200 Subject: [PATCH 078/138] - remove use of builtin and deprecated color vertex attribute. --- src/gl/renderer/gl_renderstate.cpp | 2 +- src/gl/scene/gl_skydome.cpp | 4 ++-- src/gl/shaders/gl_shader.cpp | 5 +++-- src/gl/shaders/gl_shader.h | 1 + wadsrc/static/shaders/glsl/main.vp | 3 ++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 917170872..6f5b9be14 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -136,7 +136,7 @@ bool FRenderState::ApplyShader() } } - glColor4fv(mColor.vec); + glVertexAttrib4fv(VATTR_COLOR, mColor.vec); activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 240bf6762..c54fb8c16 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -82,10 +82,10 @@ FSkyVertexBuffer::FSkyVertexBuffer() glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x); glTexCoordPointer(2, GL_FLOAT, sizeof(FSkyVertex), &VSO->u); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSkyVertex), &VSO->color); + glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + glEnableVertexAttribArray(VATTR_COLOR); glBindVertexArray(0); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 4373955c2..ba3db27ea 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -120,6 +120,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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) { @@ -156,6 +157,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * glAttachShader(hShader, hVertProg); glAttachShader(hShader, hFragProg); + glBindAttribLocation(hShader, VATTR_COLOR, "aColor"); + glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); glLinkProgram(hShader); @@ -213,8 +216,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix"); texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix"); - glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); - glUseProgram(hShader); int texture_index = glGetUniformLocation(hShader, "texture2"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index bed37cbb0..2e0731346 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -9,6 +9,7 @@ extern bool gl_shaderactive; enum { + VATTR_COLOR = 14, VATTR_VERTEX2 = 15 }; diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index e1349857e..8a1709ecf 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -1,4 +1,5 @@ +in vec4 aColor; #ifndef SIMPLE // we do not need these for simple shaders in vec4 aVertex2; out vec4 pixelpos; @@ -43,7 +44,7 @@ void main() vec4 eyeCoordPos = ViewMatrix * worldcoord; - vColor = gl_Color; + vColor = aColor; #ifndef SIMPLE pixelpos.xyz = worldcoord.xyz; From 1b7f5a2e6aca704711e581259c335ba05f1be662 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 00:59:01 +0200 Subject: [PATCH 079/138] - replaced builtin texture coordinate vertex attribute. --- src/gl/data/gl_vertexbuffer.cpp | 6 ++++-- src/gl/models/gl_models.cpp | 4 ++-- src/gl/scene/gl_skydome.cpp | 4 ++-- src/gl/shaders/gl_shader.cpp | 2 ++ src/gl/shaders/gl_shader.h | 6 ++++-- wadsrc/static/shaders/glsl/main.vp | 14 ++++++-------- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index d9d96c855..a1d553e15 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -115,9 +115,9 @@ FFlatVertexBuffer::FFlatVertexBuffer() glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x); - glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u); + glVertexAttribPointer(VATTR_TEXCOORD, 2,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(VATTR_TEXCOORD); glBindVertexArray(0); } @@ -140,6 +140,7 @@ CVAR(Bool, gl_testbuffer, false, 0) void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count) { +#if 0 if (!gl_testbuffer) // todo: remove the immediate mode calls once the uniform array method has been tested. { glBegin(primtype); @@ -151,6 +152,7 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs glEnd(); } else +#endif { if (count > 20) { diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 3ea25aead..e779cb0c9 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -117,7 +117,7 @@ FModelVertexBuffer::FModelVertexBuffer() glBufferData(GL_ELEMENT_ARRAY_BUFFER,ibo_shadowdata.Size() * sizeof(unsigned int), &ibo_shadowdata[0], GL_STATIC_DRAW); glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_VERTEX2); glBindVertexArray(0); } @@ -141,7 +141,7 @@ FModelVertexBuffer::~FModelVertexBuffer() unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int frame2, float factor) { glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].x); - glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].u); + 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; } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index c54fb8c16..0b902bba0 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -81,10 +81,10 @@ FSkyVertexBuffer::FSkyVertexBuffer() glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x); - glTexCoordPointer(2, GL_FLOAT, sizeof(FSkyVertex), &VSO->u); + glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u); glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color); glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_COLOR); glBindVertexArray(0); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index ba3db27ea..86f4ec928 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -157,6 +157,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * glAttachShader(hShader, hVertProg); glAttachShader(hShader, hFragProg); + + glBindAttribLocation(hShader, VATTR_TEXCOORD, "aTexCoord"); glBindAttribLocation(hShader, VATTR_COLOR, "aColor"); glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 2e0731346..6675e235e 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -9,8 +9,10 @@ extern bool gl_shaderactive; enum { - VATTR_COLOR = 14, - VATTR_VERTEX2 = 15 + VATTR_VERTEX = 0, + VATTR_TEXCOORD = 1, + VATTR_COLOR = 2, + VATTR_VERTEX2 = 3 }; diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 8a1709ecf..7c62f77f8 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -1,4 +1,5 @@ +in vec2 aTexCoord; in vec4 aColor; #ifndef SIMPLE // we do not need these for simple shaders in vec4 aVertex2; @@ -15,26 +16,23 @@ uniform float fakeVB[100]; void main() { - -#ifdef UNIFORM_VB vec4 vert; vec4 tc; + +#ifdef UNIFORM_VB if (gl_MultiTexCoord0.x >= 100000.0) { - int fakeVI = int(gl_MultiTexCoord0.y)*5; + int fakeVI = int(aTexCoord.y)*5; vert = gl_Vertex + vec4(fakeVB[fakeVI], fakeVB[fakeVI+1], fakeVB[fakeVI+2], 0.0); tc = vec4(fakeVB[fakeVI+3], fakeVB[fakeVI+4], 0.0, 0.0); } else +#endif { vert = gl_Vertex; - tc = gl_MultiTexCoord0; + tc = vec4(aTexCoord, 0.0, 0.0); } -#else - #define vert gl_Vertex - #define tc gl_MultiTexCoord0 -#endif #ifndef SIMPLE vec4 worldcoord = ModelMatrix * mix(vert, aVertex2, uInterpolationFactor); From eedc5a69be772ab045d79539c8bbeb0f253cdc20 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 01:02:48 +0200 Subject: [PATCH 080/138] - replaced builtin position vertex attribute. --- src/gl/data/gl_vertexbuffer.cpp | 4 ++-- src/gl/models/gl_models.cpp | 4 ++-- src/gl/scene/gl_skydome.cpp | 4 ++-- src/gl/shaders/gl_shader.cpp | 1 + wadsrc/static/shaders/glsl/main.vp | 5 +++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index a1d553e15..01c7ee3b9 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -114,9 +114,9 @@ FFlatVertexBuffer::FFlatVertexBuffer() glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x); + glVertexAttribPointer(VATTR_VERTEX, 3,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); glVertexAttribPointer(VATTR_TEXCOORD, 2,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); - glEnableClientState(GL_VERTEX_ARRAY); + glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glBindVertexArray(0); } diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index e779cb0c9..3d2d0db05 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -116,7 +116,7 @@ FModelVertexBuffer::FModelVertexBuffer() glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBufferData(GL_ELEMENT_ARRAY_BUFFER,ibo_shadowdata.Size() * sizeof(unsigned int), &ibo_shadowdata[0], GL_STATIC_DRAW); - glEnableClientState(GL_VERTEX_ARRAY); + glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_VERTEX2); glBindVertexArray(0); @@ -140,7 +140,7 @@ FModelVertexBuffer::~FModelVertexBuffer() unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int frame2, float factor) { - glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO[frame1].x); + 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; diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 0b902bba0..a2c0cf981 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -80,10 +80,10 @@ FSkyVertexBuffer::FSkyVertexBuffer() glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x); + 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); - glEnableClientState(GL_VERTEX_ARRAY); + glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_COLOR); glBindVertexArray(0); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 86f4ec928..2ce815500 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -158,6 +158,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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"); diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 7c62f77f8..eab0e1ab2 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -1,4 +1,5 @@ +in vec4 aPosition; in vec2 aTexCoord; in vec4 aColor; #ifndef SIMPLE // we do not need these for simple shaders @@ -24,13 +25,13 @@ void main() if (gl_MultiTexCoord0.x >= 100000.0) { int fakeVI = int(aTexCoord.y)*5; - vert = gl_Vertex + vec4(fakeVB[fakeVI], fakeVB[fakeVI+1], fakeVB[fakeVI+2], 0.0); + vert = aPosition + vec4(fakeVB[fakeVI], fakeVB[fakeVI+1], fakeVB[fakeVI+2], 0.0); tc = vec4(fakeVB[fakeVI+3], fakeVB[fakeVI+4], 0.0, 0.0); } else #endif { - vert = gl_Vertex; + vert = aPosition; tc = vec4(aTexCoord, 0.0, 0.0); } From 6046b11b4f38b8657a41666b8a8985955c09e1e5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 01:05:53 +0200 Subject: [PATCH 081/138] - all shaders now compile in core profile. --- src/gl/shaders/gl_shader.cpp | 2 +- wadsrc/static/shaders/glsl/burn.fp | 3 ++- wadsrc/static/shaders/glsl/fogboundary.fp | 3 ++- wadsrc/static/shaders/glsl/main.fp | 4 +++- wadsrc/static/shaders/glsl/stencil.fp | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 2ce815500..b056def8e 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -88,7 +88,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * // FString vp_comb = "#version 130\n"; - if (gl.glslversion >= 3.3f) vp_comb = "#version 330 compatibility\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. + if (gl.glslversion >= 3.3f) vp_comb = "#version 330 core\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. // todo when using shader storage buffers, add // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. diff --git a/wadsrc/static/shaders/glsl/burn.fp b/wadsrc/static/shaders/glsl/burn.fp index d14748212..0cc3f7950 100644 --- a/wadsrc/static/shaders/glsl/burn.fp +++ b/wadsrc/static/shaders/glsl/burn.fp @@ -2,6 +2,7 @@ uniform sampler2D tex; uniform sampler2D texture2; in vec4 vTexCoord; in vec4 vColor; +out vec4 FragColor; void main() { @@ -10,5 +11,5 @@ void main() vec4 t1 = texture2D(texture2, vTexCoord.xy); vec4 t2 = texture2D(tex, vec2(vTexCoord.x, 1.0-vTexCoord.y)); - gl_FragColor = frag * vec4(t1.r, t1.g, t1.b, t2.a); + 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 edf9384c6..1a2b0b0f9 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -1,5 +1,6 @@ in vec4 pixelpos; in vec2 glowdist; +out vec4 FragColor; //=========================================================================== // @@ -30,6 +31,6 @@ void main() fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); } fogfactor = exp2 (uFogDensity * fogdist); - gl_FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor); + FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor); } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 6bb96aa9a..c56057401 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -4,6 +4,8 @@ in vec2 glowdist; in vec4 vTexCoord; in vec4 vColor; +out vec4 FragColor; + #ifdef SHADER_STORAGE_LIGHTS layout(std430, binding = 3) buffer ParameterBuffer { @@ -326,6 +328,6 @@ void main() break; } } - gl_FragColor = frag; + FragColor = frag; } diff --git a/wadsrc/static/shaders/glsl/stencil.fp b/wadsrc/static/shaders/glsl/stencil.fp index 9e4afec04..d1b8745f6 100644 --- a/wadsrc/static/shaders/glsl/stencil.fp +++ b/wadsrc/static/shaders/glsl/stencil.fp @@ -1,7 +1,8 @@ in vec4 pixelpos; +out vec4 FragColor; void main() { - gl_FragColor = vec4(1.0); + FragColor = vec4(1.0); } From fc0cf4f998ec4721a7c44dd9f16bdcef45ca80f8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 02:26:23 +0200 Subject: [PATCH 082/138] - GZDoom now runs on an OpenGL core profile. :) It's probably still necessary to replace GLEW with another loader library. GLEW is pretty much broken on core OpenGL without some hacky workarounds... --- src/gl/system/gl_framebuffer.cpp | 2 +- src/gl/system/gl_interface.cpp | 37 ++++++++++------------ src/gl/system/gl_system.h | 1 - src/win32/win32gliface.cpp | 50 ++++++++++++++---------------- src/win32/win32gliface.h | 4 +-- wadsrc/static/shaders/glsl/main.vp | 2 +- 6 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index d3783fd42..fa5370b2d 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -121,6 +121,7 @@ void OpenGLFrameBuffer::InitializeState() if (first) { + glewExperimental=TRUE; glewInit(); } @@ -140,7 +141,6 @@ void OpenGLFrameBuffer::InitializeState() glDepthFunc(GL_LESS); glEnable(GL_DITHER); - glEnable(GL_ALPHA_TEST); glDisable(GL_CULL_FACE); glDisable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_LINE); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 5b99bd562..e1c70b14a 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -61,24 +61,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)); } } @@ -132,14 +123,16 @@ void gl_LoadExtensions() { I_FatalError("Unsupported OpenGL version.\nAt least GL 3.0 is required to run " GAMENAME ".\n"); } - gl.version = strtod(version, NULL); - gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL); + + // 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.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 (gl.version >= 4.f && CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; + if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -157,11 +150,15 @@ void gl_PrintStartupLog() Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); Printf ("GL_VERSION: %s\n", glGetString(GL_VERSION)); Printf ("GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - Printf ("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); + Printf ("GL_EXTENSIONS:"); + for (unsigned i = 0; i < m_Extensions.Size(); i++) + { + Printf(" %s", m_Extensions[i].GetChars()); + } int v; 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); diff --git a/src/gl/system/gl_system.h b/src/gl/system/gl_system.h index 8273960f9..2130c9cbb 100644 --- a/src/gl/system/gl_system.h +++ b/src/gl/system/gl_system.h @@ -68,7 +68,6 @@ //GL headers #include -//#include "gl_load.h" #if defined(__APPLE__) #include diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 7b70e9172..db414bae6 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -610,7 +610,7 @@ bool Win32GLVideo::SetPixelFormat() // //========================================================================== -bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) +bool Win32GLVideo::SetupPixelFormat(int multisample) { int colorDepth; HDC deskDC; @@ -646,14 +646,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) { @@ -713,11 +706,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; } } @@ -735,32 +725,40 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample) // //========================================================================== -bool Win32GLVideo::InitHardware (HWND Window, bool allowsoftware, int multisample) +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; + m_hRC = NULL; if (myWglCreateContextAttribsARB != NULL) { - 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 - }; + // let's try to get the best version possible. + static int versions[] = { 44, 43, 42, 41, 40, 33, 32, -1 }; - m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + 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, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0 + }; + + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + if (m_hRC != NULL) break; + } } if (m_hRC == 0) { + // If we are unable to get a core context, let's try whatever the system gives us. m_hRC = wglCreateContext(m_hDC); } @@ -903,7 +901,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 f39a9f70b..f61c31857 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -42,7 +42,7 @@ 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); @@ -81,7 +81,7 @@ protected: HWND InitDummy(); void ShutdownDummy(HWND dummy); bool SetPixelFormat(); - bool SetupPixelFormat(bool allowsoftware, int multisample); + bool SetupPixelFormat(int multisample); void GetDisplayDeviceName(); void MakeModesList(); diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index eab0e1ab2..c40426829 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -22,7 +22,7 @@ void main() #ifdef UNIFORM_VB - if (gl_MultiTexCoord0.x >= 100000.0) + if (aTexCoord.x >= 100000.0) { int fakeVI = int(aTexCoord.y)*5; vert = aPosition + vec4(fakeVB[fakeVI], fakeVB[fakeVI+1], fakeVB[fakeVI+2], 0.0); From fb6b4238ed32e82ff1dfb1f08cc49a9bb972e8d8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 02:48:59 +0200 Subject: [PATCH 083/138] - fixed: glProgramUniform is only present from GL 4.1 or a specific extension so it may not be used on systems not supporting it. --- src/gl/scene/gl_flats.cpp | 4 ++-- src/gl/shaders/gl_shader.cpp | 25 ++++++++++++++++++++++--- src/gl/system/gl_interface.cpp | 2 ++ src/gl/system/gl_interface.h | 7 ++++--- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 91c7f1c7e..19eb3b9e1 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -298,9 +298,9 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); - //drawcalls.Clock(); + drawcalls.Clock(); glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); - //drawcalls.Unclock(); + drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index b056def8e..db3e68298 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -293,8 +293,18 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - glProgramUniformMatrix4fv(hShader, projectionmatrix_index, 1, false, proj->get()); - glProgramUniformMatrix4fv(hShader, viewmatrix_index, 1, false, view->get()); + + if (gl.flags & RFL_SEPARATE_SHADER_OBJECTS) + { + glProgramUniformMatrix4fv(hShader, projectionmatrix_index, 1, false, proj->get()); + glProgramUniformMatrix4fv(hShader, viewmatrix_index, 1, false, view->get()); + } + else + { + Bind(); + glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get()); + glUniformMatrix4fv(viewmatrix_index, 1, false, view->get()); + } } @@ -486,7 +496,16 @@ void FShaderManager::SetWarpSpeed(unsigned int eff, float speed) FShader *sh = mTextureEffects[eff]; float warpphase = gl_frameMS * speed / 1000.f; - glProgramUniform1f(sh->GetHandle(), sh->timer_index, warpphase); + if (gl.flags & RFL_SEPARATE_SHADER_OBJECTS) + { + glProgramUniform1f(sh->GetHandle(), sh->timer_index, warpphase); + } + else + { + // not so pretty... + sh->Bind(); + glUniform1f(sh->timer_index, warpphase); + } } } diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index e1c70b14a..f00202fd8 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -133,6 +133,8 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; + if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS; + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 74beb72a4..0f569d2c4 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -9,9 +9,10 @@ enum RenderFlags RFL_TEXTURE_COMPRESSION=1, RFL_TEXTURE_COMPRESSION_S3TC=2, - RFL_BUFFER_STORAGE = 8, - RFL_SHADER_STORAGE_BUFFER = 16, - RFL_BASEINDEX = 32, + RFL_SEPARATE_SHADER_OBJECTS = 4, // we need this extension for glProgramUniform. On hardware not supporting it we need some rather clumsy workarounds + RFL_BUFFER_STORAGE = 8, // allows persistently mapped buffers, which are the only efficient way to actually use a dynamic vertex buffer. If this isn't present, a workaround with uniform arrays is used. + RFL_SHADER_STORAGE_BUFFER = 16, // to be used later for a parameter buffer + RFL_BASEINDEX = 32, // currently unused }; enum TexMode From b8bcbe819be221b9fed81615158fdcc0dda2e861 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 20:49:21 +0200 Subject: [PATCH 084/138] - removed texture based dynamic lighting. For GL 3.x the shader approach is always better. - fixed: sky fog was not unset. --- src/gl/dynlights/a_dynlight.cpp | 19 +-- src/gl/dynlights/gl_dynlight.h | 2 - src/gl/dynlights/gl_dynlight1.cpp | 108 ------------- src/gl/renderer/gl_renderer.cpp | 4 +- src/gl/renderer/gl_renderer.h | 3 +- src/gl/scene/gl_drawinfo.h | 22 +-- src/gl/scene/gl_flats.cpp | 163 ++------------------ src/gl/scene/gl_portal.cpp | 2 +- src/gl/scene/gl_scene.cpp | 97 +----------- src/gl/scene/gl_skydome.cpp | 1 + src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_spritelight.cpp | 55 ++++--- src/gl/scene/gl_wall.h | 2 +- src/gl/scene/gl_walls.cpp | 52 +------ src/gl/scene/gl_walls_draw.cpp | 248 ++++++++---------------------- src/r_defs.h | 6 +- wadsrc/static/glstuff/gllight.png | Bin 13073 -> 0 bytes 17 files changed, 129 insertions(+), 657 deletions(-) delete mode 100644 wadsrc/static/glstuff/gllight.png diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index b462b62ac..bcc126ecf 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -521,14 +521,12 @@ 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[additive], subSec->sector, this, touching_sector); + touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector); subSec->sector->validcount = ::validcount; } @@ -542,7 +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); } } @@ -755,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 37cbc4f93..568630898 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -184,8 +184,6 @@ struct FDynLightData bool gl_GetLight(Plane & p, ADynamicLight * light, 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(); void gl_UploadLights(FDynLightData &data); diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 42053e8a5..cee31ee42 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -68,17 +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) - { - if (gl.maxuniforms < 1024 && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) - { - 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); @@ -155,75 +144,6 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadd } -//========================================================================== -// -// 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); - } - gl_RenderState.SetColor(r, g, b, 1.f, desaturation); - return true; -} - - //========================================================================== // // @@ -257,31 +177,3 @@ void gl_UploadLights(FDynLightData &data) } } #endif - -//========================================================================== -// -// -// -//========================================================================== - -bool gl_SetupLightTexture() -{ - - if (GLRenderer->gllight == NULL) return false; - FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight); - pat->BindPatch(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/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index ae2ba2125..42773496e 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -96,7 +96,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mSkyVBO = NULL; gl_spriteindex = 0; mShaderManager = NULL; - glpart2 = glpart = gllight = mirrortexture = NULL; + glpart2 = glpart = mirrortexture = NULL; } void FGLRenderer::Initialize() @@ -104,7 +104,6 @@ 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; @@ -128,7 +127,6 @@ FGLRenderer::~FGLRenderer() if (glpart2) delete glpart2; if (glpart) delete glpart; if (mirrortexture) delete mirrortexture; - if (gllight) delete gllight; if (mFBID != 0) glDeleteFramebuffers(1, &mFBID); } diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 733123599..a2679f665 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -62,8 +62,7 @@ public: FTexture *glpart2; FTexture *glpart; FTexture *mirrortexture; - FTexture *gllight; - + float mSky1Pos, mSky2Pos; FRotator mAngles; diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 01a72701b..f4b104392 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -13,14 +13,6 @@ 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, @@ -30,25 +22,15 @@ enum DrawListType 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_PLAIN, // Main pass without dynamic lights + GLPASS_ALL, // Main pass with 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 }; //========================================================================== diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 19eb3b9e1..2767a5e80 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -103,26 +103,24 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte } + //========================================================================== // // Flats // //========================================================================== +extern FDynLightData lightdata; -void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) +bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) { 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(); + lightdata.Clear(); + FLightNode * node = sub->lighthead; while (node) { ADynamicLight * light = node->lightsource; - + if (light->flags2&MF2_DORMANT) { node=node->nextLight; @@ -140,72 +138,9 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) } p.Set(plane.plane); - if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.desaturation, false, foggy)) - { - node=node->nextLight; - continue; - } - draw_dlightf++; - gl_RenderState.Apply(); - - // Render the light - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - 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; - ptr->Set(vt->fx, zc, vt->fy, (nearToVert.Dot(right) * scale) + 0.5f, (nearToVert.Dot(up) * scale) + 0.5f); - ptr++; - } - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); + 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++) - { - 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, false, false, lightdata); - node = node->nextLight; - } - } int numlights[3]; @@ -347,7 +282,6 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) //========================================================================== void GLFlat::Draw(int pass) { - int i; int rel = getExtraLight(); #ifdef _DEBUG @@ -360,65 +294,15 @@ 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: - { + gl_SetFog(lightlevel, rel, &Colormap, false); gltexture->Bind(); gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, 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) - { - 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; - } - } - } - break; case GLPASS_TRANSLUCENT: if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -462,38 +346,15 @@ inline void GLFlat::PutFlat(bool fog) } if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog) { - 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) { - 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 = false; 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) list = GLDL_LIGHTBRIGHT; - - gl_drawinfo->drawlists[list].AddFlat (this); + list = masked ? GLDL_MASKED : GLDL_PLAIN; } + gl_drawinfo->drawlists[list].AddFlat (this); } //========================================================================== diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 0cc602967..afc5cf1f2 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -144,7 +144,7 @@ void GLPortal::DrawPortalStencil() for (unsigned int i = 0; i 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && gl_dynlight_shader) + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights) { 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_RenderState.EnableBrightmap(true); gl_drawinfo->drawlists[GLDL_PLAIN].Sort(); gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass); - 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); - // 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_drawinfo->drawlists[GLDL_MASKED].Sort(); gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); - 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); - // And now the multipass stuff - if (!gl_dynlight_shader && gl_lights) - { - // 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); - gl_RenderState.SetSoftLightLevel(255); - 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 - gl_RenderState.ResetColor(); - gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - gl_RenderState.EnableFog(false); - glDepthFunc(GL_LEQUAL); - if (gl_texture) - { - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); - gl_drawinfo->drawlists[GLDL_LIGHT].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_TEXTURE); - gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - 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; - } - } gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index a2c0cf981..d0932a89f 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -511,6 +511,7 @@ void GLSkyPortal::DrawContents() gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLES, 0, 12); gl_RenderState.EnableTexture(true); + gl_RenderState.SetObjectColor(0xffffffff); } gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index c70422b32..554b8ff1f 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -112,7 +112,7 @@ 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) return; diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index e4e2e855a..e66941283 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -71,47 +71,44 @@ void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsect float out[3] = { 0.0f, 0.0f, 0.0f }; // Go through both light lists - for (int i = 0; i < 2; i++) + FLightNode * node = subsec->lighthead; + while (node) { - FLightNode * node = subsec->lighthead[i]; - 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()) { - 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; + 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; } gl_RenderState.SetDynLight(out[0], out[1], out[2]); } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 28fa51868..fe2ec6e8e 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -169,7 +169,7 @@ private: void SetupLights(); bool PrepareLight(texcoord * tcs, ADynamicLight * light); - void RenderWall(int textured, ADynamicLight * light=NULL, unsigned int *store = NULL); + void RenderWall(int textured, unsigned int *store = NULL); void FloodPlane(int pass); diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index f720f1678..60e9287bf 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -114,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 @@ -145,47 +144,11 @@ 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 = false; - if (!gl_fixedcolormap) - { - 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; - } - } - } - 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) list = GLDL_LIGHTBRIGHT; - if (flags & GLWF_GLOW) list = GLDL_LIGHTBRIGHT; - } + masked = passflag[type]==1? false : (gltexture && gltexture->isMasked()); + list = masked ? GLDL_MASKED : GLDL_PLAIN; gl_drawinfo->drawlists[list].AddWall(this); } @@ -1514,11 +1477,12 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) 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; + flags = 0; 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; @@ -1764,7 +1728,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); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index e28f6315c..8cdae097a 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -62,57 +62,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.desaturation, 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 @@ -132,77 +81,74 @@ 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, 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]; @@ -223,29 +169,20 @@ void GLWall::SetupLights() // //========================================================================== -void GLWall::RenderWall(int textured, ADynamicLight * light, unsigned int *store) +void GLWall::RenderWall(int textured, unsigned int *store) { 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)); - 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 & RWF_GLOW)) - { - gl_RenderState.SetGlowPlanes(topplane, bottomplane); - gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); - } - + gl_RenderState.SetGlowPlanes(topplane, bottomplane); + gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); } - else - { - if (!PrepareLight(tcs, light)) return; - } - if (!(textured & RWF_NORENDER)) { @@ -422,7 +359,6 @@ void GLWall::RenderTranslucentWall() //========================================================================== void GLWall::Draw(int pass) { - FLightNode * node; int rel; #ifdef _DEBUG @@ -461,64 +397,6 @@ void GLWall::Draw(int pass) 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(flags, 0); - } - RenderWall(RWF_TEXTURED|RWF_GLOW); - gl_RenderState.EnableGlow(false); - gl_RenderState.EnableLight(false); - break; - - case GLPASS_TEXTURE: // modulated texture - gltexture->Bind(flags, 0); - RenderWall(RWF_TEXTURED); - 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(RWF_TEXTURED, node->lightsource); - } - node = node->nextLight; - } - break; - case GLPASS_DECALS: case GLPASS_DECALS_NOFOG: if (seg->sidedef && seg->sidedef->AttachedDecals) diff --git a/src/r_defs.h b/src/r_defs.h index 6b76803b4..dea227cc5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -772,7 +772,7 @@ struct sector_t int subsectorcount; // list of subsectors subsector_t ** subsectors; FPortal * portals[2]; // floor and ceiling portals - FLightNode * lighthead[2]; + FLightNode * lighthead; enum { @@ -949,7 +949,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 +1082,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/wadsrc/static/glstuff/gllight.png b/wadsrc/static/glstuff/gllight.png deleted file mode 100644 index a3a296b9f856f4654aae244e3400a4f33fd95902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13073 zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4h9AWhDyoryBHXZZg{#lhE&{o8v8P7uH~wf zpZETEMnC!|AkuoS@R3THe(~kWN6KvO3OebyGV1+5U;o4YqkL#+sOi*Su5W65ztl%F zloo^rpFJPqb3}yc!hcW3IiF|Fidk+hbn54#2haa^F`WD8bLCv-=WtQs)t|LZ8tMeE z{@=rJZtLn*ow9}zdl@b3m9nbrwoGCbae0$}f#v@*@%*3ObMKvdI$K6CWA5(`$55XT z*Q4h)PyF@PUcJF)YNYJ85XPXu)4|hg4SdrtoOk>n^DmjnW3HK1*4=%Zw66GD=QDQ& zMJcHEyf5ber~7`N|GKoltyWt$TKfp!WK+0*?B^rFwwn3LAM!2tPYH^i=@`T)Y~0-Q ziT`Eh6x9_69@w;03I5Mxlu0$;`|qUjG>#xW)z-=%iKfvitE9fkPMlQ#^5xbmw*I*l zf5Y-7$kj!%H_Cj-7bxOi`A1f@b|udr@3(d(H(z}Fyz28cZ^chp$^97ve z-JJTxvGA{e*H0(q=LtJX-fj@!3pCw#LhhHi?EIMhQ`@fRulvJV%5kjCQfFi64}&Cj z+f3s)=NsZH56$ffs9s#MplbHfGeyhFqE5~B~%z4`O^^a2Coh!9I>iSm4ZORQT1rhOwf-V1onO0o) zTy7p*Ty2@36}dK5K*C=_h3l_Bh$vF z6DPPj=9UZ8Z)SL~^x^Z@?f2!k`sxI~sH%Vcfsun-(%|w;o$K%CD$7p(Q_k72rf}!( zkXm{7^5Ax}9jn4?9_SiA{t?mZ*gUOa#;O@9f1fDiv`)Md{3Evi#s2iaukKVye%+I% zoE#s&z~W_%XS%`*9yNg)6;8RV`@dVI=D9DZpUn2+=k9s?_sv-OY^68nmZ`U|p1M;h zeX_VLzuoW;vn{g=^KtPhY%|2NPRy9NB>YbvV@hZ9r+Gc;w*QysK7M_)x^92@nu34l z@3|F5HMaTh&Z`i)|Kiii8PjH*%=b7@|M%x?&PA0m3A0U3b6;2PO=k7-G+8?3m{Y%< zW%|V_463v8SSP4t&2wco^y3Y2a;?8B|6_f1{Z;G7g~fAjM@tBt+W5zA?Y?5a92xof zIUW}J(*jLhp7Q83R$ly`8AZd^{p6H}ZaXFeB`UlUXx^2$$8rX0?uv zCI9{h<$d60+93GflBr?xqaS~TF7Z7x-=*EGa)S5c%5Wc^BN7u0vzD@5)t|FtmHVZc zjVJU|-RFxlEVZ3^cnZfJ|G5(je%gQKX}KC*i;aaa@>_hjA~P zVCSkuN5i=pw(2aY+`y36C;mW`H~q(BWow5A3sQww_?7%qw|cegmgy!=&MizAgf(P4 z;yF0}eExR-)%v-1y*e|Z=kNcM5ZP$-*>9(C%>GxcZ2@K(2M&b>*d1GXm^r{;#S|2%9LMtufAjzN5F@L3Tk<5M`Pu*TM8nWe{Owp z!Cvy;%2l1$@9$c$zSybde?iNMR)(Jz50}K62(8vQ-t*T!!gSHGQ}GAooey8SBv8dT z-;{a2kVBI3v;*z0d2&v2p3%ReTv$}Mg59i-f&Ii+CpQK^s~js4hKu%d_hqwwEHz_T zuzZ^8`}B8NaqLUk6T%uBC$2o8tnS*_{l>u~^1HuK#4LpeA%?313V+_Z^&!*x!TeAE zWi}qzS}O74_&sY|j{T1uPG@i$6@BFnPBV)Ei~sn~ikB>?n{_>J(WjRY2kevo z?M`y^G5YHXgNg@nJO=1827rM+B za4@d6`t$V0^E-QI-)t`468q-B!Mk!tc$K3T?b=y7bB9pU59fyx5ldD&Gq?%z&3)f( zf1M#jYxjoR7SpZWt^P_qVA`aYlJ@P1`SLAu-ZU(eY`mId;}OK(;ieTLAv0}#yzK$Q zzg&zr9-25Z|LLoln={Y+Q~bt$?YZAKhOiiyJMqt5<;5PZT`Q2Q5Ypke`quIEggv3k z{sQ$%4V~57#RKFS^;{+#W6+qn?AGk+)&CApX$+K_B{tcsS%$OV#rjo=rT;EyHYRh{ z&yxDZzg}LTf$3V))$e|+qW+EVM9t%$e>W0+X?rrRY+-@g*^>)>EJ8R0mjy&{2~1wd zvXt%PZz%(bxX>4i*dJ{8Z_yWQb|ZdC$x4?*8P9WFyR<|*&RD$+f3?b>t1WrKLMf?P z@!cVl?+Y`$nSal{-m~E${}$bvNSpPat2`4E+zV!@Ygql4eEG$(J5;ZXZ*d6Eq;1Sr z&E<|&GWKCi|2dhK9eGn}TfJ)U`I-+M3-#`u_5IsuuuP%D{lF)ivVM;vbN!0Ue@q!C56=T>q!=JNxzb zIVLl#AM{L8v|jU|ztga#;c2|tBn!!++fKEHeDj4EF8$|YsGU{2uBE)tqW^tC-@h5N z?LRa=VU^VPnGpE?&4U?JKeGh!1qKStUuhC+{42Od=;Pyr1NO%nIuCrTD%vmW#C3AM zNp|qtx%Zro_uOM`I=FD5QDtMZy6%~90p5-m-Y2A+9cF4y{5Ok%Yl61jeC;jwazpB0 z9y)d5_T&DWk5j*C%lVi#Y&2=%^$~8o7r9LF)XxBOp~6kvJ{loz{;m#!c6@Aq*yS3M z?A?R-A6SRZRFeJ^@Lm10{rBZ}?p1PC{$t}!>saZjvT&O6g%%-kQSaw@G0d6u^0j4x z7dzyQy#5}RkTBq=tdc*u^F@$oE;ubB4N? zt*s@wEc+EayZGNW)X!lSn7wp;6g!98f%3RrvzG~1oD#QMqoC>{@>QgoqwT#0%ey!! zUa!82)`L(AFcw|t%4(>(j&&56P_9)DNXOu5h= zypm%sYp>YpvjVGgEUeV8Rh(>oWq3e5BVf*tOkM>x6~X;AYz~|c1*}iq{cE|&BHfkk6<;tuAYc+^cV@8J4mI(6Ti z|C4up*dV#!LVP=K;NnvjFC5D|d!$|pFtfh-&-rK3G*O6NSNC*%Onb>~GT+JW!M|5`&U-R*7`a}FxhI;twc@*(PQ0m-p@L3`Xf@~i z#ZF1zS^||i&r3R9z4$$XEg=2lZE2=OH~v@p-TFLdvHet$O?N+kD|d@sZ2T=WH*ZIQ zer~6N5f8_w{E5#+`&gZvoK?@gRE~Sd_%Z89&#j%aSM<*JAHn<$SJZep z6%Tyr=_>JfX16$gv4)4{mrV5!g5pZ|r2d+pyKq0PF_gb`qY__--7A+Kykpfb+$S}O58~nux&A3fe#zQsytRM!`D6IM?0-Dz3#U4(zH{De>UW1x zkSDGqi$CP0*NF|8lI+^8`*(cxl?%n3Z7S;OczU}@;zuZ<_$ z=dI(_Bq3>uFWOhWTUs?3EjW9iQ<|x}s_K?Q7jw|_{NRAF{XgYyt&+c`Ht+EQg-V%> z1eZqntOGCoH#oL`U(%$>T5^oo{3IycNHzbA#)b|FQoi4koADGh}8bZ#w3))lfxc z3;S`8Z=EfC$`@Yd-rOJCQL(yqHB()`*`)PM0aE`McU=1|xg`8Wv2Ezbnw%$fKewt) z4ijhKKXh^RIdvudvkStKxAY`A|XnN3Z`Ag|nNQ>ZJ6UJdBL|9SV{@?FwJ-v+#lF zx3G7=C6pT8sVK+U--+IKP~&{_igN+a4hd<#k`g%>#&FZ$WsXOLAp0S%Lvjj6@9Jms ztDJCmzoT#{PSIc~BY&2XsLH|oo_%dMKY5ndI89)(ZE8C{)tVzz=|Iu4`{CX#3yw6r zs#m%yhx9@iy}*1t~?XTdFyeqyN2nYW~1FXkOX@ zEyjO2EUzxUpCJ49+2T|I5s@j0HMLB4j~)nFz+~?xoFTQlo!jv#JhW$4 zPwLUHZtQvy_)w{QV;}g1VD`S=^F5moSrc!6KVG4Zr73dUkXs!_~j? zla6N0bUHk_B&j@uZ|0qzXW_G28NTrsCq9`fcx~Rg;C*WY8YXbu{QF5#sd6!+%`?Fz z5wn;sgw9=Zz*h8`-CWLsO%0hDO&2SU_0&HVAmox79ck}Rf)}PHC z0yhn14qEdXNU<)z@@lEW|Bn`{o~8c_VZ5P{ZlkcPugY(coXe~0|JEyMKRZ^jthsb{ zK<55aXFmO|TF-y}ZGI=mS{=_VNy$PC1sug8Zqgj#`yxWTd{xF>Mpug6-DH7SF@t&qoy+&bRvQ z88M~XA?wcl*4N9Y_a8iXFqL2A-!lUi-z(o)_Dd}}p7SQ^{l}*hYAsuWTD+N6c1L8| z2+aC-_cou2`LT=4g^I3aYR5YHnl>A3PY>Ap(!b+bZS?*}uH|=&D;&8Pmaetu+rRWP z)7t!WMu}tf&F_5nHn@oD$!<90*b`BBcIM(A{8!J)HC$3Zek0>uch;f$0{aNnU6RL_ zTHjZSc1lv_bx10>S2v-2$`1{`1(s$n@??3^dKgzm#jD!$3qSSdNn(DG1ATY&F` zjwM-NC%sP;4|!5oS|9S;?VETkQ^30S0eUmoTg?}QE9S7K$lup>eO<6x{$}yh~KgQ_o3z-B3H{SfRyy=Zu z|85TvXNGCDr_ToOxsa&TJj1q2{6ImV&8Z{5BNzTt}BZ6@W;X^?SGYqRDDw$fJt zfol3@TOPdF%cFc@VnL6(!R?TDYRk(0KfA*C<;ITsCcYOd?>D@cV45JK1>5%>t$CUj0X`(l@{Mc8?WP z8-xyNGMwJ&>l5LweL3N~h2#8Ct}`#(SHI?NJ{aG2H}G-$wzrSvI3iBZi1BdgJjke^ zS6snp)A%#g^JIt1n=8vQls%mPT=;V8@i`6^hR)SoG8hF+T*{9SEMcQXFj)3BOb2!iW%a?dI%=2x^T5=@E@At%uAI~Z#rZN@9F#F{jU8~)vlcuDA8U*oC&xf(q8+NX$T zWSyJS@_vd~qS`af`g0Nq7ydp`efG4&fkP-EfJen)62snKGx<3;e7Ldly}+Sm`nrTf)x3raIQd$K!H&N@{>a9zts=^2p=)0_(qS~_K{ zzoL9&)AxJTr~7L4YP?-NqffX8?0dl)Zg4R`qXUuI`z5u4Th(AmHU@J$xcpvugf6b z*v~m<_aU}J&5OT7L~CB<+l@1W!N3rFM>{LxyNTs*az-&)K@Ez8r6D1jX7Czva)OC+Jz=}7^CWi5)t26_P^H-*C zKJAU2M?9wZTRpj|c5U`P8RzCKAqBzbhHhJY7bG{{V{z8JuI^=0>+An|wU$)RcxQ)n0?Z&jB#3md6kS(W6p&sY_`9=@2^O* zI8(uJFZkf!(x08@TDD)ZzO~${BzETS)y#YL|DI>@rBV0 zGtz0ct_8~)MWd>-6SU+Kt_!e#^dFzdDT1+l3UM#QT76i}Tuv6bZ~1&chom6ILCqtZ%#*2c{|zW37?X?qbJ);;a_uQRXMc_A^; z=%jq;ud5gDiRXMx5Oz{y>&m{beT>^dNkYcx+vF1#3dP2YFLv(a%QaHT2zjvAp<(&l z0@pJw>Hp8TCUR6e3$V7Hk)A$JU_rx?sizXBGQO`hV$^VGZBqBL5ZC`vwY1|n+lz<- z_s6>KsZ*rxTRXDFP57_AbIyXE%oX1yUgR-^Evvg2_HfrxTRiV^Np`~9K1asN^UBBL{UBvUvK)Z?IKj&|1{4-&hYFh`- zpL}J37+Ddo>l{rE&Wg_s_ArFSoc-$GwY0*{ZB-TT-lAKRF6{|>8K>^o)RT4i>Mu@v z`N=#I2kKUcglsg7ZrsvTeKcK1_35H4xz`jq~AQOwEE_J?bMEIz3p~k=TJluz{+KjDez{$AXyP|<#5`4e-g1N!H_+w!VAAAbDr zf}-t(4INX%_j?JS5(=xC5Ws17P+7w#pfxG+X|MPd=R?k-*}1ngmR{hqke#yPp6dD4 z3`L)Ur`CSiI@fu*E@jbQ-+z(QI%==dE=!iF3w>(2Sx;VGf7kB8 zio*;Y-}do3W;*n*Tj2Ts#RAWkBh{P2dMAWW-{>eB`tDn$Fvl`=hm&iC>a7_%1BFV| z8d;)JoF@D^-p#S-p2O`%t~o~4DK0s?4jP`g_$5_5N!)YmcI_3b(o6!EoqMvVYQMtc zsXUARI`2Gdt={}h-6}Wf=s|b3*K_Jv=hi*FJ%Nwio12SUpOafVMYU+OW0Azjo+L! z6W#}#SO*q%Guw(hQgVw6sNA5O&-Tv6ac9_rt-ltlDV)w`R*7Ord$WA`c!*DGHcyeJ>a!i@BY{~^XK1| zZ?7f(pK3Ln@^hE0L54=m8Mhk;mPmZ@N@<(jZr}OgR`q(5Hg3zLc1}^&x18)UE+;me z3)(up{-y0p@ASJf4n8sbrrC0O?_Son?}-|7tk1-parF3nIbnXlDLHk{EbR?VSx27o zGIq~5Vw&C1bR?^9$2nVlo8$b&qEmKvOkI|^GH$V5+z-Dhk=e%+ddzM-h}&Svrfd;= z&x7&z^DJ+PYENdC+4m1TlM2jc5aV3QS1{%H-TR#fSy?5|){F7(RM0=Wi~r_z(VrbCqVK`S|`tjzPncC;A)E~S_ z)wDYM`&!_~hYlU>`x*b7UAKWD!0-97CtE&$T0FIWt16FCvxu;;-UJ8D(*BU+9{vSu zqQ$#DHe2!$@UL06+ocW%QA#3>A5}U?lo?Z8J z85EjR1Y~sEvsF@Fo}Sa+dbwZb#gYBbf243;_FKa@^^$>(WW$M!xo172wC-3RaShI$ z=IY5*Rg;N2Rml*1isAN;Zn)+YH_mBh0`zm zrGy>Sb<{T`tzFE+J%MA6!*m~psp+*Do7p&~v$MLNYIP6!F3r7B+Uep=F|EzN)E#XD zT3F=*A{L)^GE$3a>3McPSfER^;$ipV`CGroWl!zy*{dCG;kG$j^Q2@~bsLAEn)ZX0 z-P2wlFjY|3O**$g&~zs6`D6#Ki1Y4jhGvN`Bsy)`T3DYt6#CSE+4%W+eD&ME;cwRT zs}-*36xN-hG&Sb#l8Sm2!TVwcOS-7dpxvz8BE;p{5x!^ccmbKH`lODzNnIk&~n19|&ibd@px@HGo$an{qHP%FH?!l5`mm}gnpe)h@tT20wlPn=eW zIdkmzl z;*~hIW`6x5$LzN!jt5N3+o<+tfz!)-v(w(5jZCsSR`+Smf4TOc_j?z)&71b&*6Xsf zj&|Ag&!iS~a)(*%$c*DNTEO?R;7{ny4?jbmeP2+U5IQkOegC7oHU}@iD42UILTg7# zj_rbdzXiX2h$`6mYkueVzE}Fp&5Uza-S)u67uBQh?K2;b8ZGJQ(`RC4`8=D)N=XmJWZ7h60O;YvypX4u(S=;um zb39YIpz?XIu-fjgAL`shMP`18YdFRp`XR-q*=TdC^qKg(3R3_4HYqzRKPz@vpzwXp zit0~u`<|{a^ga~x>!Rf=zJ!Q*^3Uo686q4Lx*WwGHE4Ct31Ns~G`X~Qw$|;%vDGK} zOC6*(D)?6X+a7l&eOB$NJMR|<8g+bQf6hKpi%Y7!O} z8BCGs<~4cs`2}m^Er|tg_0|4|*1ullHldZ}$NEVQQAdsz7Wt_3#2yek*K(hOq4tf$ zr^M?y+w)qVDs{x2wbv5={y+6!`3X@j_k~O*vdWzPyYDbC%`ahO7ER%OVYaDsqtYgm zUl+T2CHYU@C~XiA+Isi&+mE|mUvIO2c+JAB^DOTYM$Obe?lJe<-8C};Q#?K;v(y z|E!RR2>9P~)0d~|gM!!T<7NwL56-D_J)(cn@Xz94h6II=L9cz*+b@?Aw_ou5@YLC- zPK6gJhuqqKmE#3t)AcCs_UFGoyzA3?#v1!Xdb+rFM)}q$v+JvvQV!P~t)Kjmqq*|j zZ1;Obf`5GWs46+^{I_+tfW^IfHm22q9~pdW7UvXMd|uqVjGg;m##OQ7Oqs89zZ~v& zW#7ZZ{obzPiy_;77G2vWxp#p~6Wesc>~4pu9B^eg(8TQFo53ege*V+f_mTX+FK)9G zYl`J9FnzZs=kSRVuCM1p7nppXdd$v1WxMSa;w2ki@+Uqa-G=IDEce}eWgRJF!N6*9yjn`MS9qnL!vX^O3+QMh`;KpOE52N0S#b5|`$mSaNat5#J&$?= zFFPDzW&Lx71!kLf2D1wc|Y#`8y##UjacMh*a?mgdcGkqUCzN7V`PQq9(22Jg>Yx|DBe zKBtG@=ET+R6CE1P&iGJoTo?8@UY(&SRAtZd7fFKNry3@Ozlr!gnMq=?Lav_W&N6%V z@Be!e(=$Fi%C*o>_Mf$R!h`!y|0FB^PY%inJiIbh;Ks{avsWHkTpVSm%dqH&^s|4a zx796Vd%~wF>s$8<%=#{2lv5Y5xcwhit8*>F+TA!pX z+{7{^kn>fd{GNt>mIB=d%}L5UEbLuP(;%ED3J>2;+aZiio_f(@>k-Vqo>OZO9Y}l}V zzrLOCsYPp6eEIKw{C@<4?Vo);^LoFpzb^N9#@#wa+ed$*nj9i>+ikyF$9)VJVB5D- z>)Ni(RSg#wed(`KHFSF7%vrOBaq^qUEBbnGpZ=b|blQa5%3qeemwCNy@`s)756y4f zS-RQ!C7)_zEQ8h3^`&ym4vinToU@qwEC2s4hIN7)rpwwGHpG2?zi39jEYIZ!kGoD@ ze^cF~^?^;y!VuwpLYmWOuKx4&ci%*@ z72L0Gm~pJzHH(_@BOolHj2AE zf3VaenW;d%?&^=bZ}TTc9#p#TuDU4EKG}7%I|FZzV)CcoOb2dXll$=J+pp(h8moTx z>|FNd-*LuID>jQO?f5hGtX{Rj{hbo~(z>6#v-GyN{NF#H;Y0mg=?|xF2_6j16t7~B zJ6p`~FmlH|*QouoE^pS5NSbxJ%X7vnjTt3bfpxNq_LU6tH!zwXUpuj(L88yQ=i(!V zqtiFCG~M2wDU?@`uqR9F&?~Ko zICOfQ5T~Hg)5izSHZ1$HjQLo{?guB6r({g=GI5fLuB-cZo}*!stX>~$u}vj^iMhiC zuN^u~vit7IUF2y!e3!4?C6iTnzvhL-Z5u@Y{4n(U{haMVILm>@{`Nm4?>tdETe`Gy z-`(5w1_xcI+pe%H5SziX-*Kj`*hbSNK@pGFVc*iv{nupl2ydw5b=k|H*LjIeV&T^~ zC+md;O*f3UtkyR^sXsxV{VHRg(*wC+*Oh$VIycvPF-+&@NHaew%dwqTV)lh{{liZ( zD^m7meQGzE<9{td@Xp?s-*&o-1iZd^Kv^hWjp5AS)j!j3+16dTb@1l>n4eKK9Fp}G z2GM&ScowGY3ct)I{d@XR+p7{ACuLXcd%?NF&%#Ijyymep)17}gI{$fgRISoF*7CrU z&%GP_E&o;i_$qX6QtfU5w`mfo|IU1^k7D-QznrzaapCVq?}JgZ>b2~JuKYI^U-0cn z@V!aLPWcBLTVJn#_g5 zZ+bm06&SUxWN%S85W9Bk$7GfV=D7|hwlaCGw=;KY;NYGzqas24_5@CFkqU(Abn?5Z?QzKDVJmSl(yY)b$M44v%)0DNy3jfj;{DEB5*HfLm#*1o=LBG z{`~n_@5sQc8zxod|1w_n{$J^7wQqNr+G}1+w)YD7{ohJ4ZVTg_zw%eaVt)9CK6qNq zvfxt^=X!QQOO=V@`@$j)%)P*Q<*l~Ff!p`4Y6u3tF?{xKZ{*6L)646>{@K5V@nZ5t zrFEe@1e3KM&1lq1zVZF%?RVW8QpH>m=3FL%bC~KDK6<}_aev9b`xQ)vxeooi*4)?; zsNr=YLfouO;oU(Ig+uuQ*A;h!YIs;FOkv~i{Jr(_|2DQen;lB{tQ7M?RG(}%(=&ba zZ^ePY-!o;8aJ&;YF;%sf2_PykMyT( zOYmoRNs_33<-K|SH&d~P(ySM1PH2R7boLZqpIuTqN%OUd)I9a4#r^O19lGmSwQ#y} z2=mY0&;Q#PDqc@#TbOh!Cc>iCuc}GxXxoKt(|I>=yp#XXaNt{fhJg63vYHc3f7BRz zp2n{VkKLpAFhTOdz4N!K6;9mlx@;PCcUSzJiSJ~^|MK77T=)FPe$57LmKT35toGRM z2&($Y};s{;CS&x($+ImJACHe zHkZ1z!Ql5^xvBq{`5tWNdf=}aZmKRY%t}sS=+wEmzn>{EV3GV3ojbA%Zp{3~&-vh~?THsc3)lo_#?@b9 zJ=L4~{c%Rw67|4_|NEw$J3e3Le?P0hck3M|l8Vh9ypVa3^ipo(g~UBxXYTZex!igA zW&Yd)`=7nrDEc=`q~oN-Ja2pU@@aKtcg(e3Dc@hY=fD5?|EB&5pFUKbb(cNF;97Tl z&zT#^#&;atKE5fAk71s_JF&e!is2x$;?i@6wf=Q&C&t&i=`s=xbke+2Wf;sv#7;$BXBOCr@D+FrCU z5o_{TJNf;o*ZU(FOxU;ocCU6TI@uVo=&rVbroo}CfQNm-oj+c^{>8?t;Kjnr_Nqux zqxdl|$6MyQ*eQOmum59aTHyNV>qW83*nj(4qpYmWvzm%OJm~$=cDa5s!xKK1CBn)= z2i|qfG}tx!^wG>`N2lBWc`we8di=bjALol7Xz+hpt@~$xG{gT% b^8eXyONlr0HB~$X?RD{V^>bP0l+XkK3f!mG From 6b9d6787d9e674f579b214af94ac3328534e9be1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Jul 2014 21:16:59 +0200 Subject: [PATCH 085/138] - move models into their own draw list to avoid frequent buffer changes. - same for SKYHACK walls. Although rare, they would get in the way of optimizing the draw calls if not being separated out. --- src/gl/scene/gl_drawinfo.h | 9 +++++++-- src/gl/scene/gl_scene.cpp | 12 ++++++++++++ src/gl/scene/gl_sprite.cpp | 6 +----- src/gl/scene/gl_wall.h | 8 +++----- src/gl/scene/gl_walls.cpp | 12 ++++++++++-- src/gl/scene/gl_walls_draw.cpp | 19 ++++++------------- 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index f4b104392..780be6f36 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -15,8 +15,8 @@ enum DrawListType { GLDL_PLAIN, GLDL_MASKED, - GLDL_FOG, - GLDL_FOGMASKED, + GLDL_MASKEDOFS, + GLDL_MODELS, GLDL_TRANSLUCENT, GLDL_TRANSLUCENTBORDER, @@ -96,6 +96,11 @@ public: Reset(); } + unsigned int Size() + { + return drawitems.Size(); + } + void AddWall(GLWall * wall); void AddFlat(GLFlat * flat); void AddSprite(GLSprite * sprite); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 110a36420..1d1cfd29c 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -376,6 +376,18 @@ void FGLRenderer::RenderScene(int recursion) gl_drawinfo->drawlists[GLDL_MASKED].Sort(); gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); + // this list is empty most of the time so only waste time on it when in use. + if (gl_drawinfo->drawlists[GLDL_MASKEDOFS].Size() > 0) + { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -128.0f); + gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort(); + gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(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); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 554b8ff1f..9ce6856b0 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -315,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); } diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index fe2ec6e8e..fafd5ccb8 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -97,11 +97,9 @@ 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, }; enum diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 60e9287bf..e665eeb89 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -148,14 +148,22 @@ void GLWall::PutWall(bool translucent) bool masked; masked = passflag[type]==1? false : (gltexture && gltexture->isMasked()); - list = masked ? GLDL_MASKED : GLDL_PLAIN; + + if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S)) + { + list = GLDL_MASKEDOFS; + } + else + { + list = masked ? GLDL_MASKED : GLDL_PLAIN; + } gl_drawinfo->drawlists[list].AddWall(this); } 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. diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 8cdae097a..932451298 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -369,14 +369,10 @@ 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) { - 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) @@ -426,12 +422,9 @@ void GLWall::Draw(int pass) } } - if ((flags&GLWF_SKYHACK && type==RENDERWALL_M2S) || type == RENDERWALL_COLORLAYER) + if (type == RENDERWALL_COLORLAYER) { - if (pass!=GLPASS_DECALS) - { - glDisable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(0, 0); - } + glDisable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0, 0); } } From eb9d2d99171e0fac2fb99770f4330b57708ab5e1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 17 Jul 2014 02:37:18 +0200 Subject: [PATCH 086/138] - reactivate compatibility profile so that immediate mode drawing can be used on older hardware not supporting persistently mapped buffers. - reactivate alpha testing per fixed function pipeline - use the 'modern' way to define clip planes (GL_CLIP_DISTANCE). This is far more portable than the old glClipPlane method and a lot more robust than checking this in the fragment shader. --- src/gl/data/gl_vertexbuffer.cpp | 35 +++++++++++++++------- src/gl/renderer/gl_renderstate.cpp | 24 ++++++++++++++- src/gl/renderer/gl_renderstate.h | 4 ++- src/gl/scene/gl_portal.cpp | 26 ++++++++++++---- src/gl/scene/gl_walls_draw.cpp | 7 ----- src/gl/system/gl_interface.cpp | 1 + src/gl/system/gl_interface.h | 1 + src/gl/textures/gl_material.h | 1 - src/win32/win32gliface.cpp | 36 ++++++++++++++++++----- wadsrc/static/shaders/glsl/fogboundary.fp | 6 ---- wadsrc/static/shaders/glsl/main.fp | 10 ++----- wadsrc/static/shaders/glsl/main.vp | 2 ++ wadsrc/static/shaders/glsl/shaderdefs.i | 5 +++- 13 files changed, 110 insertions(+), 48 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 01c7ee3b9..6fd7f3f98 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -136,24 +136,29 @@ FFlatVertexBuffer::~FFlatVertexBuffer() // //========================================================================== -CVAR(Bool, gl_testbuffer, false, 0) +CUSTOM_CVAR(Int, gl_rendermethod, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ +} void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count) { -#if 0 - if (!gl_testbuffer) // todo: remove the immediate mode calls once the uniform array method has been tested. + switch (gl_rendermethod) { - glBegin(primtype); - for (unsigned int i = 0; i < count; i++) + case 0: +#ifndef CORE_PROFILE + if (!(gl.flags & RFL_COREPROFILE)) { - glTexCoord2fv(&map[offset + i].u); - glVertex3fv(&map[offset + i].x); + 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(); + break; } - glEnd(); - } - else #endif - { + case 1: if (count > 20) { int start = offset; @@ -186,6 +191,14 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, count * 5, &map[offset].x); glDrawArrays(primtype, 0, count); } + break; + + case 2: + // glBufferSubData + + case 3: + // glMapBufferRange + break; } } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 6f5b9be14..73d7d5ef3 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -149,7 +149,29 @@ bool FRenderState::ApplyShader() activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muClipHeightTop.Set(mClipHeightTop); activeShader->muClipHeightBottom.Set(mClipHeightBottom); - activeShader->muAlphaThreshold.Set(mAlphaThreshold); + +#ifndef CORE_PROFILE + if (!(gl.flags & RFL_COREPROFILE)) + { + if (mAlphaThreshold != glAlphaThreshold) + { + glAlphaThreshold = mAlphaThreshold; + if (mAlphaThreshold < 0.f) + { + glDisable(GL_ALPHA_TEST); + } + else + { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, mAlphaThreshold); + } + } + } + else +#endif + { + activeShader->muAlphaThreshold.Set(mAlphaThreshold); + } if (mGlowEnabled) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index d8168bca5..a07cd3401 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -74,8 +74,10 @@ class FRenderState int mEffectState; int mColormapState; - int glSrcBlend, glDstBlend; float glAlphaThreshold; + bool glClipOn; + + int glSrcBlend, glDstBlend; bool glAlphaTest; int glBlendEquation; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index afc5cf1f2..7c7efc91d 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -286,8 +286,10 @@ bool GLPortal::Start(bool usestencil, bool doquery) } planestack.Push(gl_RenderState.GetClipHeightTop()); planestack.Push(gl_RenderState.GetClipHeightBottom()); - gl_RenderState.SetClipHeightTop(65536.f); + glDisable(GL_CLIP_DISTANCE0); + glDisable(GL_CLIP_DISTANCE1); gl_RenderState.SetClipHeightBottom(-65536.f); + gl_RenderState.SetClipHeightTop(65536.f); // save viewpoint savedviewx=viewx; @@ -351,8 +353,10 @@ void GLPortal::End(bool usestencil) 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) { @@ -790,15 +794,27 @@ void GLPlaneMirrorPortal::DrawContents() validcount++; - float f = FIXED2FLOAT(planez); - if (PlaneMirrorMode < 0) gl_RenderState.SetClipHeightTop(f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling - else gl_RenderState.SetClipHeightBottom(f); // floor mirror: clip everything with a z higher than the portal's floor - PlaneMirrorFlag++; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); ClearClipper(); + 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_DISTANCE0); + glDisable(GL_CLIP_DISTANCE1); + gl_RenderState.SetClipHeightBottom(-65536.f); + gl_RenderState.SetClipHeightTop(65536.f); PlaneMirrorFlag--; PlaneMirrorMode=old_pm; } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 932451298..b9965972c 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -186,14 +186,7 @@ void GLWall::RenderWall(int textured, unsigned int *store) if (!(textured & RWF_NORENDER)) { - // disable the clip plane if it isn't needed (which can be determined by a simple check.) - float ct = gl_RenderState.GetClipHeightTop(); - float cb = gl_RenderState.GetClipHeightBottom(); - if (ztop[0] <= ct && ztop[1] <= ct) gl_RenderState.SetClipHeightTop(65536.f); - if (zbottom[0] >= cb && zbottom[1] >= cb) gl_RenderState.SetClipHeightBottom(-65536.f); gl_RenderState.Apply(); - gl_RenderState.SetClipHeightTop(ct); - gl_RenderState.SetClipHeightBottom(cb); } // the rest of the code is identical for textured rendering and lights diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index f00202fd8..0b1e88548 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -134,6 +134,7 @@ void gl_LoadExtensions() if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC; if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS; + if (!CheckExtension("GL_ARB_compatibility")) gl.flags |= RFL_COREPROFILE; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 0f569d2c4..2209f0bed 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -13,6 +13,7 @@ enum RenderFlags RFL_BUFFER_STORAGE = 8, // allows persistently mapped buffers, which are the only efficient way to actually use a dynamic vertex buffer. If this isn't present, a workaround with uniform arrays is used. RFL_SHADER_STORAGE_BUFFER = 16, // to be used later for a parameter buffer RFL_BASEINDEX = 32, // currently unused + RFL_COREPROFILE = 64, }; enum TexMode diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 81f4dd10f..259f881b4 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -63,7 +63,6 @@ private: bool bHasColorkey; // only for hires bool bExpand; - float AlphaThreshold; unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index db414bae6..3b630177a 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -17,6 +17,7 @@ #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" @@ -739,21 +740,42 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) m_hRC = NULL; if (myWglCreateContextAttribsARB != NULL) { - // let's try to get the best version possible. - static int versions[] = { 44, 43, 42, 41, 40, 33, 32, -1 }; +#ifndef CORE_PROFILE + bool core = !!Args->CheckParm("-core"); +#else + bool core = true; +#endif + if (core) + { + // let's try to get the best version possible. + static int versions[] = { 44, 43, 42, 41, 40, 33, 32, -1 }; - for (int i = 0; versions[i] > 0; i++) + 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, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0 + }; + + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + if (m_hRC != NULL) break; + } + } + else { int ctxAttribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10, - WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10, + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - if (m_hRC != NULL) break; + } } if (m_hRC == 0) diff --git a/wadsrc/static/shaders/glsl/fogboundary.fp b/wadsrc/static/shaders/glsl/fogboundary.fp index 1a2b0b0f9..d8259c845 100644 --- a/wadsrc/static/shaders/glsl/fogboundary.fp +++ b/wadsrc/static/shaders/glsl/fogboundary.fp @@ -10,12 +10,6 @@ out vec4 FragColor; void main() { -#ifndef NO_DISCARD - // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. - if (pixelpos.y > uClipHeightTop) discard; - if (pixelpos.y < uClipHeightBottom) discard; -#endif - float fogdist; float fogfactor; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index c56057401..a4e4d782b 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -220,16 +220,10 @@ vec4 applyFog(vec4 frag, float fogfactor) void main() { -#ifndef NO_DISCARD - // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. - if (pixelpos.y > uClipHeightTop) discard; - if (pixelpos.y < uClipHeightBottom) discard; -#endif - vec4 frag = ProcessTexel(); -#ifndef NO_DISCARD - // alpha testing +#ifdef CORE_PROFILE + // alpha testing - only for the core profile, in compatibility mode we use the alpha test. if (frag.a <= uAlphaThreshold) discard; #endif diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index c40426829..e355141f0 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -65,4 +65,6 @@ void main() #endif gl_Position = ProjectionMatrix * eyeCoordPos; + gl_ClipDistance[0] = worldcoord.y - uClipHeightBottom; + gl_ClipDistance[1] = uClipHeightTop - worldcoord.y; } diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 56e6965b2..2870cf975 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -1,10 +1,13 @@ // This file contains common data definitions for both vertex and fragment shader uniform vec4 uCameraPos; +uniform int uTextureMode; uniform float uClipHeightTop, uClipHeightBottom; -uniform int uTextureMode; +#ifdef CORE_PROFILE uniform float uAlphaThreshold; +#endif + // colors uniform vec4 uObjectColor; From e0b756e511974a9bd603deccd5bcd0f8deee8ad2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 17 Jul 2014 10:04:20 +0200 Subject: [PATCH 087/138] - fixed: The cubemapped skybox renderer did not set up the model matrix properly. --- src/gl/scene/gl_skydome.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index d0932a89f..583c6fc62 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -319,6 +319,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool FMaterial * tex; gl_RenderState.EnableModelMatrix(true); + gl_RenderState.mModelMatrix.loadIdentity(); if (!sky2) gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y); From 6c9a818220d7a7c69b3b8848340e8153a07e6f54 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 26 Jul 2014 10:23:07 +0200 Subject: [PATCH 088/138] - allow different render modes if persistent buffers are not available (untested!) --- src/gl/data/gl_vertexbuffer.cpp | 31 ++++++++++++++++++++++++++----- src/gl/data/gl_vertexbuffer.h | 3 ++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 6fd7f3f98..c09996bf0 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -96,21 +96,21 @@ FFlatVertexBuffer::FFlatVertexBuffer() 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); + mIndex = mCurIndex = 0; } else { vbo_shadowdata.Reserve(BUFFER_SIZE); map = &vbo_shadowdata[0]; - FFlatVertex fill[20]; for (int i = 0; i < 20; i++) { - fill[i].Set(0, 0, 0, 100001.f, i); + map[i].Set(0, 0, 0, 100001.f, i); } glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, 20 * sizeof(FFlatVertex), fill, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE * sizeof(FFlatVertex), map, GL_STREAM_DRAW); + mIndex = mCurIndex = 20; } - mIndex = mCurIndex = 0; glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); @@ -136,15 +136,23 @@ FFlatVertexBuffer::~FFlatVertexBuffer() // //========================================================================== -CUSTOM_CVAR(Int, gl_rendermethod, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Int, gl_rendermethod, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { + int newself = self; + if (newself < 0) newself = 0; + if (newself == 0 && (gl.flags & RFL_COREPROFILE)) newself = 1; + if (newself > 3) newself = 3; } 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. + // Any of the provided methods are rather shitty, with immediate mode being the most reliable across different hardware. + // Still, allow this to be set per CVAR, just in case. Fortunately for newer hardware all this nonsense is not needed anymore. switch (gl_rendermethod) { case 0: + // trusty old immediate mode #ifndef CORE_PROFILE if (!(gl.flags & RFL_COREPROFILE)) { @@ -159,6 +167,7 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs } #endif case 1: + // uniform array if (count > 20) { int start = offset; @@ -195,9 +204,21 @@ void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offs case 2: // glBufferSubData + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferSubData(GL_ARRAY_BUFFER, offset * sizeof(FFlatVertex), count * sizeof(FFlatVertex), &vbo_shadowdata[offset]); + glDrawArrays(primtype, offset, count); + break; case 3: // glMapBufferRange + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + void *p = glMapBufferRange(GL_ARRAY_BUFFER, offset * sizeof(FFlatVertex), count * sizeof(FFlatVertex), GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); + if (p != NULL) + { + memcpy(p, &vbo_shadowdata[offset], count * sizeof(FFlatVertex)); + glUnmapBuffer(GL_ARRAY_BUFFER); + glDrawArrays(primtype, offset, count); + } break; } } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index d9e259db6..cb287f6c8 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -51,6 +51,7 @@ class FFlatVertexBuffer : public FVertexBuffer void CheckPlanes(sector_t *sector); 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); @@ -74,7 +75,7 @@ public: unsigned int diff = newofs - mCurIndex; *poffset = mCurIndex; mCurIndex = newofs; - if (mCurIndex >= BUFFER_SIZE) mCurIndex = mIndex; + 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. From 637aa9d77e8b0abce6b49b0ca4d085fe370fb8df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 26 Jul 2014 18:43:54 +0200 Subject: [PATCH 089/138] - some adjustments to allow testing the different rendering methods. --- src/gl/system/gl_cvars.h | 1 - src/gl/system/gl_interface.cpp | 7 ++++++- wadsrc/static/menudef.z | 17 +++++++++-------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index d0e18bca4..567d9f85f 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -38,7 +38,6 @@ 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) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 0b1e88548..72d5a457b 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -52,6 +52,7 @@ RenderContext gl; int occlusion_type=0; +CVAR(Bool, gl_persistent_avail, false, CVAR_NOSET); //========================================================================== // @@ -132,7 +133,11 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE; + if (CheckExtension("GL_ARB_buffer_storage") && !Args->CheckParm("-nopersistentbuffers")) + { + gl.flags |= RFL_BUFFER_STORAGE; // the cmdline option is for testing the fallback implementation on newer hardware. + gl_persistent_avail = true; + } if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS; if (!CheckExtension("GL_ARB_compatibility")) gl.flags |= RFL_COREPROFILE; diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index 0db780620..e448e42d9 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -105,12 +105,6 @@ OptionValue "HqResizeModes" 6, "hq4x" } -OptionValue "HqResizeTargets" -{ - 0, "Everything" - 1, "Sprites/fonts" -} - OptionValue "FogMode" { 0, "Off" @@ -130,6 +124,14 @@ OptionValue "FuzzStyle" //5, "Jagged fuzz" I can't see any difference between this and 4 so it's disabled for now. } +OptionValue "RenderMethods" +{ + 0, "Immediate mode" + 1, "Uniform array" + 2, "Buffer upload" + 3, "Mapped buffer" +} + OptionMenu "GLTextureGLOptions" { Title "TEXTURE OPTIONS" @@ -158,7 +160,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" @@ -179,7 +180,7 @@ 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, "OnOff" + Option "Render method", gl_rendermethod, "RenderMethods", "gl_persistent_avail" } OptionMenu "OpenGLOptions" From bdf5bbd34e0148a4f8a5085b6761e9b72ccb3213 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 26 Jul 2014 20:56:10 +0200 Subject: [PATCH 090/138] - make the shader timer part of the render state. --- src/gl/renderer/gl_renderstate.cpp | 15 +-------------- src/gl/renderer/gl_renderstate.h | 8 +++++++- src/gl/shaders/gl_shader.cpp | 30 +----------------------------- src/gl/shaders/gl_shader.h | 3 +-- src/gl/textures/gl_material.cpp | 4 ++-- 5 files changed, 12 insertions(+), 48 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 73d7d5ef3..807912bca 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -88,20 +88,6 @@ void FRenderState::Reset() mClipHeightBottom = -65536.f; } - -//========================================================================== -// -// Set texture shader info -// -//========================================================================== - -void FRenderState::SetupShader(int &shaderindex, float warptime) -{ - mEffectState = shaderindex; - if (shaderindex > 0) GLRenderer->mShaderManager->SetWarpSpeed(shaderindex, warptime); -} - - //========================================================================== // // Apply shader settings @@ -149,6 +135,7 @@ bool FRenderState::ApplyShader() activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muClipHeightTop.Set(mClipHeightTop); activeShader->muClipHeightBottom.Set(mClipHeightBottom); + activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f); #ifndef CORE_PROFILE if (!(gl.flags & RFL_COREPROFILE)) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index a07cd3401..63fdab4ea 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -61,6 +61,7 @@ class FRenderState float mClipHeightTop, mClipHeightBottom; bool mModelMatrixEnabled; bool mTextureMatrixEnabled; + float mShaderTimer; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FStateVec4 mColor; @@ -97,7 +98,12 @@ public: void Reset(); - void SetupShader(int &shaderindex, float warptime); + void SetShader(int shaderindex, float warptime) + { + mEffectState = shaderindex; + mShaderTimer = warptime; + } + void Apply(); void ApplyMatrices(); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index db3e68298..870b6184a 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -210,8 +210,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muClipHeightTop.Init(hShader, "uClipHeightTop"); muClipHeightBottom.Init(hShader, "uClipHeightBottom"); muAlphaThreshold.Init(hShader, "uAlphaThreshold"); + muTimer.Init(hShader, "timer"); - timer_index = glGetUniformLocation(hShader, "timer"); lights_index = glGetUniformLocation(hShader, "lights"); fakevb_index = glGetUniformLocation(hShader, "fakeVB"); projectionmatrix_index = glGetUniformLocation(hShader, "ProjectionMatrix"); @@ -481,34 +481,6 @@ void FShaderManager::SetActiveShader(FShader *sh) } -//========================================================================== -// -// To avoid maintenance this will be set when a warped texture is bound -// because at that point the draw buffer needs to be flushed anyway. -// -//========================================================================== - -void FShaderManager::SetWarpSpeed(unsigned int eff, float speed) -{ - // indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom - if (eff < mTextureEffects.Size()) - { - FShader *sh = mTextureEffects[eff]; - - float warpphase = gl_frameMS * speed / 1000.f; - if (gl.flags & RFL_SEPARATE_SHADER_OBJECTS) - { - glProgramUniform1f(sh->GetHandle(), sh->timer_index, warpphase); - } - else - { - // not so pretty... - sh->Bind(); - glUniform1f(sh->timer_index, warpphase); - } - } -} - //========================================================================== // // diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 6675e235e..c825996ee 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -199,8 +199,8 @@ class FShader FBufferedUniform1f muClipHeightTop; FBufferedUniform1f muClipHeightBottom; FBufferedUniform1f muAlphaThreshold; + FBufferedUniform1f muTimer; - int timer_index; int lights_index; int projectionmatrix_index; int viewmatrix_index; @@ -262,7 +262,6 @@ public: int Find(const char *mame); FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); - void SetWarpSpeed(unsigned int eff, float speed); void ApplyMatrices(VSMatrix *proj, VSMatrix *view); FShader *GetActiveShader() const { diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index b6d83eb52..9ec948b37 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -737,7 +737,7 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader) int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT; - gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); + gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); if (tex->bHasCanvas || tex->bWarped) clampmode = 0; else if (clampmode != -1) clampmode &= 3; @@ -784,7 +784,7 @@ void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; int maxbound = 0; - gl_RenderState.SetupShader(shaderindex, tex->gl_info.shaderspeed); + gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, alphatexture); // The only multitexture effect usable on sprites is the brightmap. From 77d9d9b2a588c5902dfb26ebb8affe3fdab2bdd7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 11:53:18 +0200 Subject: [PATCH 091/138] - fixed: For updating the model VAO's attribute pointers it is necessary to first bind the vertex buffer we need to refer to, because this is not part of the VAO's state. --- src/gl/models/gl_models.cpp | 1 + src/gl/shaders/gl_shader.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 3d2d0db05..39663ab53 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -140,6 +140,7 @@ FModelVertexBuffer::~FModelVertexBuffer() 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); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 870b6184a..20abe17e5 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -88,7 +88,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * // FString vp_comb = "#version 130\n"; - if (gl.glslversion >= 3.3f) vp_comb = "#version 330 core\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile. // todo when using shader storage buffers, add // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. From c1d8f235c25e9caaa720dbb47f86eb7defd26fab Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 12:33:54 +0200 Subject: [PATCH 092/138] - renamed some stuff that clashed with gl function names. --- src/gl/data/gl_matrix.cpp | 14 +++++++------- src/gl/renderer/gl_renderstate.cpp | 24 +++++++++++++----------- src/gl/renderer/gl_renderstate.h | 12 +++++------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index aa98a3c66..35683dbb8 100644 --- a/src/gl/data/gl_matrix.cpp +++ b/src/gl/data/gl_matrix.cpp @@ -40,7 +40,7 @@ VSMatrix::setIdentityMatrix( FLOATTYPE *mat, int size) { -// glLoadIdentity implementation +// gl LoadIdentity implementation void VSMatrix::loadIdentity() { @@ -54,7 +54,7 @@ VSMatrix::loadIdentity() } -// glMultMatrix implementation +// gl MultMatrix implementation void VSMatrix::multMatrix(const FLOATTYPE *aMatrix) { @@ -76,7 +76,7 @@ VSMatrix::multMatrix(const FLOATTYPE *aMatrix) } #ifdef USE_DOUBLE -// glMultMatrix implementation +// gl MultMatrix implementation void VSMatrix::multMatrix(const float *aMatrix) { @@ -100,7 +100,7 @@ VSMatrix::multMatrix(const float *aMatrix) -// glLoadMatrix implementation +// gl LoadMatrix implementation void VSMatrix::loadMatrix(const FLOATTYPE *aMatrix) { @@ -108,7 +108,7 @@ VSMatrix::loadMatrix(const FLOATTYPE *aMatrix) } #ifdef USE_DOUBLE -// glLoadMatrix implementation +// gl LoadMatrix implementation void VSMatrix::loadMatrix(const float *aMatrix) { @@ -265,7 +265,7 @@ VSMatrix::perspective(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE } -// glOrtho implementation +// gl Ortho implementation void VSMatrix::ortho(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, @@ -282,7 +282,7 @@ VSMatrix::ortho(FLOATTYPE left, FLOATTYPE right, } -// glFrustum implementation +// gl Frustum implementation void VSMatrix::frustum(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 807912bca..bee49cd96 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -74,11 +74,9 @@ void FRenderState::Reset() mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA; - glSrcBlend = glDstBlend = -1; mAlphaThreshold = 0.5f; mBlendEquation = GL_FUNC_ADD; mObjectColor = 0xffffffff; - glBlendEquation = -1; m2D = true; mVertexBuffer = mCurrentVertexBuffer = NULL; mColormapState = CM_DEFAULT; @@ -86,6 +84,10 @@ void FRenderState::Reset() mSpecialEffect = EFF_NONE; mClipHeightTop = 65536.f; mClipHeightBottom = -65536.f; + + stSrcBlend = stDstBlend = -1; + stBlendEquation = -1; + stAlphaThreshold = -1.f; } //========================================================================== @@ -140,9 +142,9 @@ bool FRenderState::ApplyShader() #ifndef CORE_PROFILE if (!(gl.flags & RFL_COREPROFILE)) { - if (mAlphaThreshold != glAlphaThreshold) + if (mAlphaThreshold != stAlphaThreshold) { - glAlphaThreshold = mAlphaThreshold; + stAlphaThreshold = mAlphaThreshold; if (mAlphaThreshold < 0.f) { glDisable(GL_ALPHA_TEST); @@ -150,7 +152,7 @@ bool FRenderState::ApplyShader() else { glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, mAlphaThreshold); + glAlphaFunc(GL_GREATER, mAlphaThreshold * mColor.vec[3]); } } } @@ -271,16 +273,16 @@ 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 (mBlendEquation != glBlendEquation) + if (mBlendEquation != stBlendEquation) { - glBlendEquation = mBlendEquation; - ::glBlendEquation(mBlendEquation); + stBlendEquation = mBlendEquation; + glBlendEquation(mBlendEquation); } } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 63fdab4ea..562cfb0ef 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -75,12 +75,10 @@ class FRenderState int mEffectState; int mColormapState; - float glAlphaThreshold; - bool glClipOn; - - int glSrcBlend, glDstBlend; - bool glAlphaTest; - int glBlendEquation; + float stAlphaThreshold; + int stSrcBlend, stDstBlend; + bool stAlphaTest; + int stBlendEquation; bool ApplyShader(); @@ -299,7 +297,7 @@ public: } else { - ::glBlendEquation(eq); + glBlendEquation(eq); } } From 97341fcb31b0e0c11f592882f4c4e98fd099e31b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 13:46:35 +0200 Subject: [PATCH 093/138] - reenabled the flat vertex buffer for GL 3.x NVidia hardware. On AMD and Intel it'll stay off because past tests have shown that it won't improve performance at all. --- src/gl/data/gl_vertexbuffer.cpp | 55 +++++++++++++++++---------------- src/gl/data/gl_vertexbuffer.h | 1 + src/gl/system/gl_interface.cpp | 5 +-- src/gl/system/gl_interface.h | 1 + 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index c09996bf0..f68883edf 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -96,7 +96,7 @@ FFlatVertexBuffer::FFlatVertexBuffer() 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); - mIndex = mCurIndex = 0; + mNumReserved = mIndex = mCurIndex = 0; } else { @@ -109,7 +109,7 @@ FFlatVertexBuffer::FFlatVertexBuffer() } glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE * sizeof(FFlatVertex), map, GL_STREAM_DRAW); - mIndex = mCurIndex = 20; + mNumReserved = mIndex = mCurIndex = 20; } glBindVertexArray(vao_id); @@ -390,6 +390,11 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; mapvt->z = vt->z; } + if (!(gl.flags & RFL_BUFFER_STORAGE)) + { + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferSubData(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex), &vbo_shadowdata[startvt]); + } } //========================================================================== @@ -400,12 +405,20 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { - vbo_shadowdata.Clear(); - if (gl.flags & RFL_BUFFER_STORAGE) + if (!(gl.flags & RFL_NOBUFFER)) { + vbo_shadowdata.Resize(mNumReserved); CreateFlatVBO(); - memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); mCurIndex = mIndex = vbo_shadowdata.Size(); + if (gl.flags & RFL_BUFFER_STORAGE) + { + memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); + } + else + { + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferSubData(GL_ARRAY_BUFFER, mNumReserved * sizeof(FFlatVertex), (mIndex - mNumReserved) * sizeof(FFlatVertex), &vbo_shadowdata[mNumReserved]); + } } else if (sectors) { @@ -417,6 +430,7 @@ void FFlatVertexBuffer::CreateVBO() sectors[i].vboheight[1] = sectors[i].vboheight[0] = FIXED_MIN; } } + } //========================================================================== @@ -427,39 +441,28 @@ void FFlatVertexBuffer::CreateVBO() void FFlatVertexBuffer::CheckPlanes(sector_t *sector) { - if (gl.flags & RFL_BUFFER_STORAGE) + if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) { - 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); - } - } - 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::ceiling); + sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling); + } + if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[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 (gl.flags & RFL_BUFFER_STORAGE) + if (!(gl.flags & RFL_NOBUFFER)) { CheckPlanes(sector); sector_t *hs = sector->GetHeightSec(); diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index cb287f6c8..b6d61f2da 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -47,6 +47,7 @@ class FFlatVertexBuffer : public FVertexBuffer FFlatVertex *map; unsigned int mIndex; unsigned int mCurIndex; + unsigned int mNumReserved; void CheckPlanes(sector_t *sector); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 72d5a457b..2d5f13125 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -120,7 +120,7 @@ void gl_LoadExtensions() // Don't even start if it's lower than 3.0 - if (strcmp(version, "3.0") < 0) + if (strcmp(version, "3.0") < 0) { I_FatalError("Unsupported OpenGL version.\nAt least GL 3.0 is required to run " GAMENAME ".\n"); } @@ -129,8 +129,9 @@ void gl_LoadExtensions() gl.version = strtod(version, NULL) + 0.01f; gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f; - gl.vendorstring=(char*)glGetString(GL_VENDOR); + gl.vendorstring = (char*)glGetString(GL_VENDOR); + if (!strstr(gl.vendorstring, "NVIDIA Corporation")); gl.flags |= RFL_NOBUFFER; 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 (CheckExtension("GL_ARB_buffer_storage") && !Args->CheckParm("-nopersistentbuffers")) diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 2209f0bed..d33ce77fc 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -14,6 +14,7 @@ enum RenderFlags RFL_SHADER_STORAGE_BUFFER = 16, // to be used later for a parameter buffer RFL_BASEINDEX = 32, // currently unused RFL_COREPROFILE = 64, + RFL_NOBUFFER = 128, // the static buffer makes no sense on GL 3.x AMD and Intel hardware, as long as compatibility mode is on }; enum TexMode From 4904abfc1cfc54c54b82207958dd20862c410674 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 13:47:37 +0200 Subject: [PATCH 094/138] - forgot test stuff. --- src/gl/system/gl_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 2d5f13125..f4d13f8f2 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -131,7 +131,7 @@ void gl_LoadExtensions() gl.vendorstring = (char*)glGetString(GL_VENDOR); - if (!strstr(gl.vendorstring, "NVIDIA Corporation")); gl.flags |= RFL_NOBUFFER; + if (!strstr(gl.vendorstring, "NVIDIA Corporation")) gl.flags |= RFL_NOBUFFER; 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 (CheckExtension("GL_ARB_buffer_storage") && !Args->CheckParm("-nopersistentbuffers")) From 754c96a540c1f84706a169aac22f5c6793730dd7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 16:09:47 +0200 Subject: [PATCH 095/138] - added default precision settings to shader include because some old ATI drivers complain if they aren't there - even though the spec doesn't require them... --- wadsrc/static/shaders/glsl/shaderdefs.i | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 2870cf975..242b7244b 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -1,5 +1,9 @@ // This file contains common data definitions for both vertex and fragment shader +// these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here. +precision highp int; +precision highp float; + uniform vec4 uCameraPos; uniform int uTextureMode; uniform float uClipHeightTop, uClipHeightBottom; From 3d24f58bf05ed4eeaa6e84d2bf9033712f45d51f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 20:18:32 +0200 Subject: [PATCH 096/138] - fixed conditions for disabling the flat vertex buffer. --- src/gl/system/gl_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index f4d13f8f2..ca40bc60e 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -131,7 +131,6 @@ void gl_LoadExtensions() gl.vendorstring = (char*)glGetString(GL_VENDOR); - if (!strstr(gl.vendorstring, "NVIDIA Corporation")) gl.flags |= RFL_NOBUFFER; 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 (CheckExtension("GL_ARB_buffer_storage") && !Args->CheckParm("-nopersistentbuffers")) @@ -142,6 +141,7 @@ void gl_LoadExtensions() if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS; if (!CheckExtension("GL_ARB_compatibility")) gl.flags |= RFL_COREPROFILE; + if (!(gl.flags & (RFL_COREPROFILE|RFL_BUFFER_STORAGE)) && !strstr(gl.vendorstring, "NVIDIA Corporation")) gl.flags |= RFL_NOBUFFER; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); From c9c93a58a2129f79a3c53f7bc4102d03f9ea9e69 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Jul 2014 21:55:25 +0200 Subject: [PATCH 097/138] - fixed bad constant and potential use of uninitialized variable. --- src/gl/scene/gl_flats.cpp | 4 ++-- src/gl/system/gl_framebuffer.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 2767a5e80..60b1237d5 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -344,12 +344,12 @@ inline void GLFlat::PutFlat(bool fog) { Colormap.Clear(); } - if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog) + if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog || gltexture == NULL) { // 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 { bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack); list = masked ? GLDL_MASKED : GLDL_PLAIN; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index fa5370b2d..b2f147dc1 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -121,7 +121,7 @@ void OpenGLFrameBuffer::InitializeState() if (first) { - glewExperimental=TRUE; + glewExperimental=true; glewInit(); } From ef8f66c9a1acd6df65e5d6700305e4e391b8cb26 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 30 Jul 2014 23:13:16 +0200 Subject: [PATCH 098/138] - removed the code for hardware alpha testing again because it didn't work anymore with how things are set up now. - we need to check all GL versions when trying to get a context because some drivers only give us the version we request, leaving out newer features that are not exposed via extension. - added some status info about uniform blocks. --- src/gl/renderer/gl_renderstate.cpp | 24 +------------------ src/gl/system/gl_interface.cpp | 4 ++++ src/gl/system/gl_interface.h | 1 + src/gl/textures/gl_hwtexture.cpp | 2 ++ src/win32/win32gliface.cpp | 31 +++++++------------------ wadsrc/static/shaders/glsl/main.fp | 4 +--- wadsrc/static/shaders/glsl/shaderdefs.i | 2 -- 7 files changed, 17 insertions(+), 51 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index bee49cd96..24492c495 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -138,29 +138,7 @@ bool FRenderState::ApplyShader() activeShader->muClipHeightTop.Set(mClipHeightTop); activeShader->muClipHeightBottom.Set(mClipHeightBottom); activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f); - -#ifndef CORE_PROFILE - if (!(gl.flags & RFL_COREPROFILE)) - { - if (mAlphaThreshold != stAlphaThreshold) - { - stAlphaThreshold = mAlphaThreshold; - if (mAlphaThreshold < 0.f) - { - glDisable(GL_ALPHA_TEST); - } - else - { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, mAlphaThreshold * mColor.vec[3]); - } - } - } - else -#endif - { - activeShader->muAlphaThreshold.Set(mAlphaThreshold); - } + activeShader->muAlphaThreshold.Set(mAlphaThreshold); if (mGlowEnabled) { diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index ca40bc60e..404c068d7 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -175,6 +175,9 @@ void gl_PrintStartupLog() 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); + gl.maxuniformblock = v; glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &v); @@ -182,5 +185,6 @@ void gl_PrintStartupLog() glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); Printf("Max. vertex shader storage blocks: %d\n", v); + } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index d33ce77fc..a88133929 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -29,6 +29,7 @@ struct RenderContext { unsigned int flags; unsigned int maxuniforms; + unsigned int maxuniformblock; float version; float glslversion; int max_texturesize; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 516b5aaf5..98229a1ca 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -192,6 +192,8 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i if (alphatexture) { // thanks to deprecation and delayed introduction of a suitable replacement feature this has become a bit messy... + // Of all the targeted hardware, the Intel GMA 2000 and 3000 are the only ones not supporting texture swizzle, and they + // are also the only ones not supoorting GL 3.3. On those we are forced to use a full RGBA texture here. if (gl.version >= 3.3f) { texformat = GL_R8; diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 3b630177a..a0e55d673 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -745,37 +745,22 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) #else bool core = true; #endif - if (core) - { - // let's try to get the best version possible. - static int versions[] = { 44, 43, 42, 41, 40, 33, 32, -1 }; + // 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[] = { 44, 43, 42, 41, 40, 33, 32, 30, -1 }; - 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, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 0 - }; - - m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - if (m_hRC != NULL) break; - } - } - else + for (int i = 0; versions[i] > 0; i++) { int ctxAttribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 3, - WGL_CONTEXT_MINOR_VERSION_ARB, 0, + 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, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + WGL_CONTEXT_PROFILE_MASK_ARB, core? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - + if (m_hRC != NULL) break; } } if (m_hRC == 0) diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index a4e4d782b..482afc0ca 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -222,12 +222,10 @@ void main() { vec4 frag = ProcessTexel(); -#ifdef CORE_PROFILE - // alpha testing - only for the core profile, in compatibility mode we use the alpha test. +#ifndef NO_ALPHATEST if (frag.a <= uAlphaThreshold) discard; #endif - switch (uFixedColormap) { case 0: diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 242b7244b..d310126ab 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -8,9 +8,7 @@ uniform vec4 uCameraPos; uniform int uTextureMode; uniform float uClipHeightTop, uClipHeightBottom; -#ifdef CORE_PROFILE uniform float uAlphaThreshold; -#endif // colors From 1ec58011d2dc761043d19e9b098b3969cf26ed55 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 31 Jul 2014 00:44:22 +0200 Subject: [PATCH 099/138] - start of light buffer implementation so that we don't have to use uniform arrays which appear to be broken on AMD. --- src/CMakeLists.txt | 1 + src/gl/dynlights/gl_lightbuffer.cpp | 153 ++++++++++++++++++++++++++++ src/gl/dynlights/gl_lightbuffer.h | 30 ++++++ src/gl/scene/gl_wall.h | 2 +- src/gl/scene/gl_walls.cpp | 2 + src/gl/shaders/gl_shader.cpp | 10 +- 6 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 src/gl/dynlights/gl_lightbuffer.cpp create mode 100644 src/gl/dynlights/gl_lightbuffer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 22fd833b4..fdc4bb6e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1088,6 +1088,7 @@ add_executable( zdoom WIN32 gl/dynlights/gl_dynlight.cpp gl/dynlights/gl_glow.cpp gl/dynlights/gl_dynlight1.cpp + gl/dynlights/gl_lightbuffer.cpp gl/shaders/gl_shader.cpp gl/shaders/gl_texshader.cpp gl/system/gl_interface.cpp diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp new file mode 100644 index 000000000..663631240 --- /dev/null +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -0,0 +1,153 @@ +/* +** gl_lightbuffer.cpp +** Buffer data maintenance for dynamic lights +** +**--------------------------------------------------------------------------- +** 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. +** 5. Full disclosure of the entire project's source code, except for third +** party libraries is mandatory. (NOTE: This clause is non-negotiable!) +** +** 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 "gl/dynlights/gl_lightbuffer.h" +#include "gl/dynlights/gl_dynlight.h" +#include "gl/system/gl_interface.h" + +static const int LIGHTBUF_BINDINGPOINT = 1; + +FLightBuffer::FLightBuffer() +{ + if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + { + mBufferType = GL_SHADER_STORAGE_BUFFER; + mBufferSize = 80000; // 40000 lights per scene should be plenty. The largest I've ever seen was around 5000. + } + else + { + mBufferType = GL_UNIFORM_BUFFER; + mBufferSize = gl.maxuniformblock / 4 - 100; // we need to be a bit careful here so don't use the full buffer size + } + AddBuffer(); + Clear(); +} + +FLightBuffer::~FLightBuffer() +{ + glBindBuffer(mBufferType, 0); + for (unsigned int i = 0; i < mBufferIds.Size(); i++) + { + glDeleteBuffers(1, &mBufferIds[i]); + } +} + +void FLightBuffer::AddBuffer() +{ + unsigned int id; + glGenBuffers(1, &id); + mBufferIds.Push(id); + glBindBuffer(mBufferType, id); + unsigned int bytesize = mBufferSize * 8 * sizeof(float); + if (gl.flags & RFL_BUFFER_STORAGE) + { + glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + mBufferPointers.Push((float*)map); + } + else + { + glBufferData(mBufferType, bytesize, NULL, GL_STREAM_DRAW); + } +} + +void FLightBuffer::Clear() +{ + mBufferNum = 0; + mIndex = 0; + mBufferArray.Clear(); + mBufferStart.Clear(); +} + +void FLightBuffer::UploadLights(FDynLightData &data, unsigned int &buffernum, unsigned int &bufferindex) +{ + 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 (totalsize == 0) return; + + if (mIndex + totalsize > mBufferSize) + { + if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + { + return; // we do not want multiple shader storage blocks. 40000 lights is too much already + } + else + { + mBufferNum++; + mBufferStart.Push(mIndex); + mIndex = 0; + if (mBufferIds.Size() <= mBufferNum) AddBuffer(); + } + } + + float *copyptr; + + if (gl.flags & RFL_BUFFER_STORAGE) + { + copyptr = mBufferPointers[mBufferNum] + mIndex * 4; + } + else + { + unsigned int pos = mBufferArray.Reserve(totalsize * 4); + copyptr = &mBufferArray[pos]; + } + + float parmcnt[] = { mIndex + 1, mIndex + 1 + size0, mIndex + 1 + size0 + size1, mIndex + totalsize }; + + memcpy(©ptr[0], parmcnt, 4 * sizeof(float)); + memcpy(©ptr[1], &data.arrays[0][0], 4 * size0*sizeof(float)); + memcpy(©ptr[1 + size0], &data.arrays[1][0], 4 * size1*sizeof(float)); + memcpy(©ptr[1 + size0 + size1], &data.arrays[2][0], 4 * size2*sizeof(float)); + buffernum = mBufferNum; + bufferindex = mIndex; + mIndex += totalsize; +} + +void FLightBuffer::Finish() +{ + //glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferIds[0]); +} + + + diff --git a/src/gl/dynlights/gl_lightbuffer.h b/src/gl/dynlights/gl_lightbuffer.h new file mode 100644 index 000000000..57e6bf0c8 --- /dev/null +++ b/src/gl/dynlights/gl_lightbuffer.h @@ -0,0 +1,30 @@ +#ifndef __GL_LIGHTBUFFER_H +#define __GL_LIGHTBUFFER_H + +#include "tarray.h" +struct FDynLightData; + +class FLightBuffer +{ + TArray mBufferArray; + TArray mBufferIds; + TArray mBufferStart; + TArray mBufferPointers; + unsigned int mBufferType; + unsigned int mBufferSize; + unsigned int mIndex; + unsigned int mBufferNum; + + void AddBuffer(); + +public: + + FLightBuffer(); + ~FLightBuffer(); + void Clear(); + void UploadLights(FDynLightData &data, unsigned int &buffernum, unsigned int &bufferindex); + void Finish(); +}; + +#endif + diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index fafd5ccb8..e17f61c3e 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -135,7 +135,7 @@ public: float topglowcolor[4]; float bottomglowcolor[4]; - int firstdynlight, lastdynlight; + unsigned int dynlightindex, dynlightbuffer; int firstwall, numwalls; // splitting info. union diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index e665eeb89..cd179a265 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -1486,6 +1486,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) glseg.y2= FIXED2FLOAT(v2->y); Colormap=frontsector->ColorMap; flags = 0; + dynlightindex = UINT_MAX; int rel = 0; int orglightlevel = gl_ClampLight(frontsector->lightlevel); @@ -1750,6 +1751,7 @@ 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); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 20abe17e5..1ddb58076 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -264,7 +264,7 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath 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_DISCARD\n"; + if (!usediscard) defines += "#define NO_ALPHATEST\n"; FShader *shader = NULL; try @@ -350,10 +350,10 @@ struct FEffectShader static const FEffectShader effectshaders[]= { - { "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "" }, - { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n" }, - { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", NULL, "#define SIMPLE\n" }, - { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\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" }, }; From 7967082e603cb13fe45f14d40bd2f4485bcf4e1c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 1 Aug 2014 20:59:39 +0200 Subject: [PATCH 100/138] - use the light buffer to handle dynamic lighting. --- src/gl/dynlights/gl_dynlight1.cpp | 33 ------- src/gl/dynlights/gl_lightbuffer.cpp | 118 +++++++++++++----------- src/gl/dynlights/gl_lightbuffer.h | 20 ++-- src/gl/renderer/gl_renderer.cpp | 4 + src/gl/renderer/gl_renderer.h | 2 + src/gl/renderer/gl_renderstate.cpp | 26 +++--- src/gl/renderer/gl_renderstate.h | 27 ++---- src/gl/scene/gl_flats.cpp | 21 +---- src/gl/scene/gl_scene.cpp | 2 + src/gl/scene/gl_wall.h | 2 +- src/gl/scene/gl_walls_draw.cpp | 12 +-- src/gl/shaders/gl_shader.cpp | 25 +++-- src/gl/shaders/gl_shader.h | 6 +- src/gl/system/gl_interface.cpp | 5 + src/gl/system/gl_interface.h | 1 + wadsrc/static/shaders/glsl/main.fp | 85 +++++++++-------- wadsrc/static/shaders/glsl/shaderdefs.i | 2 +- 17 files changed, 194 insertions(+), 197 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index cee31ee42..c504a33c4 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -144,36 +144,3 @@ bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadd } -//========================================================================== -// -// -// -//========================================================================== - -#if 0 -void gl_UploadLights(FDynLightData &data) -{ - ParameterBufferElement *pptr; - int size0 = data.arrays[0].Size()/4; - int size1 = data.arrays[1].Size()/4; - int size2 = data.arrays[2].Size()/4; - - if (size0 + size1 + size2 > 0) - { - int sizetotal = size0 + size1 + size2 + 1; - int index = GLRenderer->mParmBuffer->Reserve(sizetotal, &pptr); - - float parmcnt[] = { index + 1, index + 1 + size0, index + 1 + size0 + size1, index + 1 + size0 + size1 + size2 }; - - memcpy(&pptr[0], parmcnt, 4 * sizeof(float)); - memcpy(&pptr[1], &data.arrays[0][0], 4 * size0*sizeof(float)); - memcpy(&pptr[1 + size0], &data.arrays[1][0], 4 * size1*sizeof(float)); - memcpy(&pptr[1 + size0 + size1], &data.arrays[2][0], 4 * size2*sizeof(float)); - gl_RenderState.SetDynLightIndex(index); - } - else - { - gl_RenderState.SetDynLightIndex(-1); - } -} -#endif diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index 663631240..b91b0fe55 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -39,93 +39,79 @@ */ #include "gl/system/gl_system.h" +#include "gl/shaders/gl_shader.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 LIGHTBUF_BINDINGPOINT = 1; +static const int BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB. FLightBuffer::FLightBuffer() { if (gl.flags & RFL_SHADER_STORAGE_BUFFER) { mBufferType = GL_SHADER_STORAGE_BUFFER; - mBufferSize = 80000; // 40000 lights per scene should be plenty. The largest I've ever seen was around 5000. + mBlockAlign = 0; } else { mBufferType = GL_UNIFORM_BUFFER; - mBufferSize = gl.maxuniformblock / 4 - 100; // we need to be a bit careful here so don't use the full buffer size + mBlockSize = 2048;// gl.maxuniformblock / 4 - 100; + mBlockAlign = 1024;// ((mBlockSize * 2) & ~(gl.uniformblockalignment - 1)) / 4; // count in vec4's } - AddBuffer(); + + glGenBuffers(1, &mBufferId); + glBindBuffer(mBufferType, mBufferId); + unsigned int bytesize = BUFFER_SIZE * 4 * sizeof(float); + if (gl.flags & RFL_BUFFER_STORAGE) + { + glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + mBufferPointer = (float*)map; + glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId); + } + else + { + glBufferData(mBufferType, bytesize, NULL, GL_STREAM_DRAW); + mBufferPointer = NULL; + } + Clear(); + mLastMappedIndex = UINT_MAX; } FLightBuffer::~FLightBuffer() { glBindBuffer(mBufferType, 0); - for (unsigned int i = 0; i < mBufferIds.Size(); i++) - { - glDeleteBuffers(1, &mBufferIds[i]); - } -} - -void FLightBuffer::AddBuffer() -{ - unsigned int id; - glGenBuffers(1, &id); - mBufferIds.Push(id); - glBindBuffer(mBufferType, id); - unsigned int bytesize = mBufferSize * 8 * sizeof(float); - if (gl.flags & RFL_BUFFER_STORAGE) - { - glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - mBufferPointers.Push((float*)map); - } - else - { - glBufferData(mBufferType, bytesize, NULL, GL_STREAM_DRAW); - } + glDeleteBuffers(1, &mBufferId); } void FLightBuffer::Clear() { - mBufferNum = 0; mIndex = 0; mBufferArray.Clear(); - mBufferStart.Clear(); } -void FLightBuffer::UploadLights(FDynLightData &data, unsigned int &buffernum, unsigned int &bufferindex) +int FLightBuffer::UploadLights(FDynLightData &data) { 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 (totalsize == 0) return; + if (totalsize <= 1) return -1; - if (mIndex + totalsize > mBufferSize) + if (mIndex + totalsize > BUFFER_SIZE) { - if (gl.flags & RFL_SHADER_STORAGE_BUFFER) - { - return; // we do not want multiple shader storage blocks. 40000 lights is too much already - } - else - { - mBufferNum++; - mBufferStart.Push(mIndex); - mIndex = 0; - if (mBufferIds.Size() <= mBufferNum) AddBuffer(); - } + return -1; // we ran out of space. All following lights will be ignored } float *copyptr; - if (gl.flags & RFL_BUFFER_STORAGE) + if (mBufferPointer != NULL) { - copyptr = mBufferPointers[mBufferNum] + mIndex * 4; + copyptr = mBufferPointer + mIndex * 4; } else { @@ -133,20 +119,48 @@ void FLightBuffer::UploadLights(FDynLightData &data, unsigned int &buffernum, un copyptr = &mBufferArray[pos]; } - float parmcnt[] = { mIndex + 1, mIndex + 1 + size0, mIndex + 1 + size0 + size1, mIndex + totalsize }; + float parmcnt[] = { 0, size0, size0 + size1, size0 + size1 + size2 }; memcpy(©ptr[0], parmcnt, 4 * sizeof(float)); - memcpy(©ptr[1], &data.arrays[0][0], 4 * size0*sizeof(float)); - memcpy(©ptr[1 + size0], &data.arrays[1][0], 4 * size1*sizeof(float)); - memcpy(©ptr[1 + size0 + size1], &data.arrays[2][0], 4 * size2*sizeof(float)); - buffernum = mBufferNum; - bufferindex = mIndex; + 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)); + + if (mBufferPointer == NULL) // if we can't persistently map the buffer we need to upload it after all lights have been added. + { + glBindBuffer(mBufferType, mBufferId); + glBufferSubData(mBufferType, mIndex, totalsize * 4 * sizeof(float), copyptr); + } + + unsigned int bufferindex = mIndex; mIndex += totalsize; + draw_dlight += (totalsize-1) / 2; + return bufferindex; } void FLightBuffer::Finish() { - //glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferIds[0]); + /* + if (!(gl.flags & RFL_BUFFER_STORAGE)) // if we can't persistently map the buffer we need to upload it after all lights have been added. + { + glBindBuffer(mBufferType, mBufferId); + glBufferSubData(mBufferType, 0, mBufferArray.Size() * sizeof(float), &mBufferArray[0]); + } + */ + Clear(); +} + +int FLightBuffer::BindUBO(unsigned int index) +{ + 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); } diff --git a/src/gl/dynlights/gl_lightbuffer.h b/src/gl/dynlights/gl_lightbuffer.h index 57e6bf0c8..8e50555c3 100644 --- a/src/gl/dynlights/gl_lightbuffer.h +++ b/src/gl/dynlights/gl_lightbuffer.h @@ -7,23 +7,25 @@ struct FDynLightData; class FLightBuffer { TArray mBufferArray; - TArray mBufferIds; - TArray mBufferStart; - TArray mBufferPointers; - unsigned int mBufferType; - unsigned int mBufferSize; - unsigned int mIndex; - unsigned int mBufferNum; + unsigned int mBufferId; + float * mBufferPointer; - void AddBuffer(); + unsigned int mBufferType; + unsigned int mIndex; + unsigned int mLastMappedIndex; + unsigned int mBlockAlign; + unsigned int mBlockSize; public: FLightBuffer(); ~FLightBuffer(); void Clear(); - void UploadLights(FDynLightData &data, unsigned int &buffernum, unsigned int &bufferindex); + int UploadLights(FDynLightData &data); void Finish(); + int BindUBO(unsigned int index); + unsigned int GetBlockSize() const { return mBlockSize; } + unsigned int GetBufferType() const { return mBufferType; } }; #endif diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 42773496e..ceb553f86 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -67,6 +67,7 @@ #include "gl/utility/gl_clock.h" #include "gl/utility/gl_templates.h" #include "gl/models/gl_models.h" +#include "gl/dynlights/gl_lightbuffer.h" //=========================================================================== // @@ -97,6 +98,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) gl_spriteindex = 0; mShaderManager = NULL; glpart2 = glpart = mirrortexture = NULL; + mLights = NULL; } void FGLRenderer::Initialize() @@ -108,6 +110,7 @@ void FGLRenderer::Initialize() mVBO = new FFlatVertexBuffer; mSkyVBO = new FSkyVertexBuffer; mModelVBO = new FModelVertexBuffer; + mLights = new FLightBuffer; gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; SetupLevel(); @@ -124,6 +127,7 @@ FGLRenderer::~FGLRenderer() 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; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index a2679f665..15c8a2e16 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -17,6 +17,7 @@ struct pspdef_t; class FShaderManager; class GLPortal; class FGLThreadManager; +class FLightBuffer; enum SectorRenderFlags { @@ -72,6 +73,7 @@ public: FFlatVertexBuffer *mVBO; FSkyVertexBuffer *mSkyVBO; FModelVertexBuffer *mModelVBO; + FLightBuffer *mLights; FGLRenderer(OpenGLFrameBuffer *fb); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 24492c495..464880895 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -48,6 +48,7 @@ #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); @@ -68,9 +69,10 @@ TArray gl_MatrixStack; void FRenderState::Reset() { mTextureEnabled = true; - mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false; + mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; mFogColor.d = -1; mTextureMode = -1; + mLightIndex = -1; mDesaturation = 0; mSrcBlend = GL_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA; @@ -98,7 +100,6 @@ void FRenderState::Reset() bool FRenderState::ApplyShader() { - FShader *activeShader; if (mSpecialEffect > EFF_NONE) { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); @@ -139,6 +140,7 @@ bool FRenderState::ApplyShader() 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) { @@ -159,17 +161,6 @@ bool FRenderState::ApplyShader() activeShader->currentglowstate = 0; } - if (mLightEnabled) - { - activeShader->muLightRange.Set(mNumLights); - glUniform4fv(activeShader->lights_index, mNumLights[3], mLightData); - } - else - { - static const int nulint[] = { 0, 0, 0, 0 }; - activeShader->muLightRange.Set(nulint); - } - if (mColormapState != activeShader->currentfixedcolormap) { float r, g, b; @@ -282,3 +273,12 @@ void FRenderState::ApplyMatrices() 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 562cfb0ef..0e290adb3 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -9,6 +9,7 @@ #include "r_defs.h" class FVertexBuffer; +class FShader; extern TArray gl_MatrixStack; EXTERN_CVAR(Bool, gl_direct_state_change) @@ -43,24 +44,22 @@ class FRenderState bool mTextureEnabled; bool mFogEnabled; bool mGlowEnabled; - bool mLightEnabled; bool mBrightmapEnabled; + int mLightIndex; int mSpecialEffect; int mTextureMode; int mDesaturation; int mSoftLight; float mLightParms[4]; - int mNumLights[4]; - float *mLightData; int mSrcBlend, mDstBlend; float mAlphaThreshold; - bool mAlphaTest; int mBlendEquation; + bool mAlphaTest; bool m2D; - float mInterpolationFactor; - float mClipHeightTop, mClipHeightBottom; bool mModelMatrixEnabled; bool mTextureMatrixEnabled; + float mInterpolationFactor; + float mClipHeightTop, mClipHeightBottom; float mShaderTimer; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; @@ -80,6 +79,8 @@ class FRenderState bool stAlphaTest; int stBlendEquation; + FShader *activeShader; + bool ApplyShader(); public: @@ -104,6 +105,7 @@ public: void Apply(); void ApplyMatrices(); + void ApplyLightIndex(int index); void SetVertexBuffer(FVertexBuffer *vb) { @@ -185,9 +187,9 @@ public: mGlowEnabled = on; } - void EnableLight(bool on) + void SetLightIndex(int n) { - mLightEnabled = on; + mLightIndex = n; } void EnableBrightmap(bool on) @@ -251,15 +253,6 @@ public: mLightParms[0] = d; } - void SetLights(int *numlights, float *lightdata) - { - mNumLights[0] = 0; - mNumLights[1] = numlights[0]; - mNumLights[2] = numlights[1]; - mNumLights[3] = numlights[2]; - mLightData = lightdata; // caution: the data must be preserved by the caller until the 'apply' call! - } - void SetFixedColormap(int cm) { mColormapState = cm; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 60b1237d5..9e4a8ec6d 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -56,6 +56,7 @@ #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/shaders/gl_shader.h" #include "gl/textures/gl_material.h" @@ -142,22 +143,8 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) node = node->nextLight; } - int numlights[3]; - - lightdata.Combine(numlights, gl.MaxLights()); - if (numlights[2] > 0) - { - draw_dlightf+=numlights[2]/2; - gl_RenderState.EnableLight(true); - gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]); - gl_RenderState.Apply(); - return true; - } - if (lightsapplied) - { - gl_RenderState.EnableLight(false); - gl_RenderState.Apply(); - } + dynlightindex = GLRenderer->mLights->UploadLights(lightdata); + gl_RenderState.ApplyLightIndex(dynlightindex); return false; } @@ -271,7 +258,6 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) } } } - gl_RenderState.EnableLight(false); } @@ -450,6 +436,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_scene.cpp b/src/gl/scene/gl_scene.cpp index 0a73a06f6..e301b3da6 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" @@ -348,6 +349,7 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); glDisable(GL_POLYGON_OFFSET_FILL); // just in case + GLRenderer->mLights->Finish(); int pass; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index e17f61c3e..36d4d2fc3 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -135,7 +135,7 @@ public: float topglowcolor[4]; float bottomglowcolor[4]; - unsigned int dynlightindex, dynlightbuffer; + int dynlightindex; int firstwall, numwalls; // splitting info. union diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index b9965972c..98bc9f661 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -53,6 +53,7 @@ #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" @@ -150,15 +151,8 @@ void GLWall::SetupLights() } 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); } @@ -187,6 +181,7 @@ void GLWall::RenderWall(int textured, unsigned int *store) if (!(textured & RWF_NORENDER)) { gl_RenderState.Apply(); + gl_RenderState.ApplyLightIndex(dynlightindex); } // the rest of the code is identical for textured rendering and lights @@ -383,7 +378,6 @@ void GLWall::Draw(int pass) gltexture->Bind(flags, 0); RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); - gl_RenderState.EnableLight(false); break; case GLPASS_DECALS: diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 1ddb58076..00683dd20 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -57,6 +57,7 @@ #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_shader.h" #include "gl/textures/gl_material.h" +#include "gl/dynlights/gl_lightbuffer.h" //========================================================================== // @@ -86,10 +87,19 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * // // 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 = "#version 130\n"; - // todo when using shader storage buffers, add - // "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead. + FString vp_comb; + + if (lightbuffertype == GL_UNIFORM_BUFFER) + { + vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); + } + else + { + vp_comb = "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; + } if (!(gl.flags & RFL_BUFFER_STORAGE)) { @@ -196,7 +206,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muLightParms.Init(hShader, "uLightAttr"); muColormapStart.Init(hShader, "uFixedColormapStart"); muColormapRange.Init(hShader, "uFixedColormapRange"); - muLightRange.Init(hShader, "uLightRange"); + muLightIndex.Init(hShader, "uLightIndex"); muFogColor.Init(hShader, "uFogColor"); muDynLightColor.Init(hShader, "uDynLightColor"); muObjectColor.Init(hShader, "uObjectColor"); @@ -218,10 +228,13 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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); - int texture_index = glGetUniformLocation(hShader, "texture2"); - if (texture_index > 0) glUniform1i(texture_index, 1); + tempindex = glGetUniformLocation(hShader, "texture2"); + if (tempindex > 0) glUniform1i(tempindex, 1); glUseProgram(0); return !!linked; diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index c825996ee..e100e9bf1 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -187,7 +187,7 @@ class FShader FUniform1i muFixedColormap; FUniform4f muColormapStart; FUniform4f muColormapRange; - FBufferedUniform4i muLightRange; + FBufferedUniform1i muLightIndex; FBufferedUniformPE muFogColor; FBufferedUniform4f muDynLightColor; FBufferedUniformPE muObjectColor; @@ -281,6 +281,10 @@ public: #define FIRST_USER_SHADER 12 +enum +{ + LIGHTBUF_BINDINGPOINT = 1 +}; #endif diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 404c068d7..ee30084f0 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -133,6 +133,7 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_shader_storage_buffer_object")) gl.flags |= RFL_SHADER_STORAGE_BUFFER; if (CheckExtension("GL_ARB_buffer_storage") && !Args->CheckParm("-nopersistentbuffers")) { gl.flags |= RFL_BUFFER_STORAGE; // the cmdline option is for testing the fallback implementation on newer hardware. @@ -178,6 +179,10 @@ void gl_PrintStartupLog() glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); Printf ("Max. uniform block size: %d\n", v); gl.maxuniformblock = v; + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); + Printf ("Uniform block alignment: %d\n", v); + gl.uniformblockalignment = v; + glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &v); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index a88133929..9a5c18ac4 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -30,6 +30,7 @@ struct RenderContext unsigned int flags; unsigned int maxuniforms; unsigned int maxuniformblock; + unsigned int uniformblockalignment; float version; float glslversion; int max_texturesize; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 482afc0ca..532529f0b 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -7,14 +7,15 @@ in vec4 vColor; out vec4 FragColor; #ifdef SHADER_STORAGE_LIGHTS - layout(std430, binding = 3) buffer ParameterBuffer + layout(std430, binding = 1) buffer LightBufferSSO { vec4 lights[]; }; -#elif defined MAXLIGHTS128 - uniform vec4 lights[256]; #else - uniform vec4 lights[128]; + layout(std140) uniform LightBufferUBO + { + vec4 lights[NUM_UBO_LIGHTS]; + }; #endif @@ -169,29 +170,33 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 dynlight = uDynLightColor; - if (uLightRange.z > uLightRange.x) + if (uLightIndex >= 0) { - // - // modulated lights - // - for(int i=uLightRange.x; i lightRange.x) { - vec4 lightpos = lights[i]; - vec4 lightcolor = lights[i+1]; - - lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; - dynlight.rgb += lightcolor.rgb; - } - // - // subtractive lights - // - for(int i=uLightRange.y; i uLightRange.z) + if (uLightIndex >= 0) { - vec4 addlight = vec4(0.0,0.0,0.0,0.0); - - // - // additive lights - these can be done after the alpha test. - // - for(int i=uLightRange.z; i lightRange.z) { - vec4 lightpos = lights[i]; - vec4 lightcolor = lights[i+1]; - - lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; - addlight.rgb += lightcolor.rgb; + 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 Date: Fri, 1 Aug 2014 22:42:39 +0200 Subject: [PATCH 101/138] - decided to restrict the 2.0 beta to OpenGL 4.x with GL_ARB_buffer_storage extension and removed all code for supporting older versions. Sadly, anything else makes no sense. All the recently made changes live or die, depending on this extension's presence. Without it, there are major performance issues with the buffer uploads. All of the traditional buffer upload methods are without exception horrendously slow, especially in the context of a Doom engine where frequent small updates are required. It could be solved with a complete restructuring of the engine, of course, but that's hardly worth the effort, considering it's only for legacy hardware whose market share will inevitably shrink considerably over the next years. And even then, under the best circumstances I'd still get the same performance as the old immediate mode renderer in GZDoom 1.x and still couldn't implement the additions I'd like to make. So, since I need to keep GZDoom 1.x around anyway for older GL 2.x hardware, it may as well serve for 3.x hardware, too. It's certainly less work than constantly trying to find workarounds for the older hardware's limitations that cost more time than working on future-proofing the engine. This new, trimmed down 4.x renderer runs on a core profile configuration and uses persistently mapped buffers for nearly everything that is getting transferred to the GPU. (The global uniforms are still being used as such but they'll be phased out after the first beta release. --- src/gl/data/gl_vertexbuffer.cpp | 169 +++------------------------- src/gl/data/gl_vertexbuffer.h | 9 +- src/gl/dynlights/gl_lightbuffer.cpp | 39 +------ src/gl/shaders/gl_shader.cpp | 12 +- src/gl/system/gl_interface.cpp | 15 +-- src/gl/system/gl_interface.h | 3 - src/gl/textures/gl_bitmap.cpp | 56 +++------ src/gl/textures/gl_hwtexture.cpp | 14 +-- src/win32/win32gliface.cpp | 14 +-- wadsrc/static/menudef.z | 9 -- wadsrc/static/shaders/glsl/main.vp | 30 +---- 11 files changed, 46 insertions(+), 324 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index f68883edf..854750ecb 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -90,27 +90,11 @@ void FVertexBuffer::BindVBO() FFlatVertexBuffer::FFlatVertexBuffer() : FVertexBuffer() { - 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); - mNumReserved = mIndex = mCurIndex = 0; - } - else - { - vbo_shadowdata.Reserve(BUFFER_SIZE); - map = &vbo_shadowdata[0]; - - for (int i = 0; i < 20; i++) - { - map[i].Set(0, 0, 0, 100001.f, i); - } - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, BUFFER_SIZE * sizeof(FFlatVertex), map, GL_STREAM_DRAW); - mNumReserved = mIndex = mCurIndex = 20; - } + 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); + mNumReserved = mIndex = mCurIndex = 0; glBindVertexArray(vao_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); @@ -128,101 +112,6 @@ FFlatVertexBuffer::~FFlatVertexBuffer() glBindBuffer(GL_ARRAY_BUFFER, 0); } -//========================================================================== -// -// Renders the buffer's contents with immediate mode functions -// This is here so that the immediate mode fallback does not need -// to double all rendering code and can instead reuse the buffer-based version -// -//========================================================================== - -CUSTOM_CVAR(Int, gl_rendermethod, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - int newself = self; - if (newself < 0) newself = 0; - if (newself == 0 && (gl.flags & RFL_COREPROFILE)) newself = 1; - if (newself > 3) newself = 3; -} - -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. - // Any of the provided methods are rather shitty, with immediate mode being the most reliable across different hardware. - // Still, allow this to be set per CVAR, just in case. Fortunately for newer hardware all this nonsense is not needed anymore. - switch (gl_rendermethod) - { - case 0: - // trusty old immediate mode -#ifndef CORE_PROFILE - if (!(gl.flags & RFL_COREPROFILE)) - { - 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(); - break; - } -#endif - case 1: - // uniform array - if (count > 20) - { - int start = offset; - FFlatVertex ff = map[offset]; - while (count > 20) - { - - if (primtype == GL_TRIANGLE_FAN) - { - // split up the fan into multiple sub-fans - map[offset] = map[start]; - glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, 20 * 5, &map[offset].x); - glDrawArrays(primtype, 0, 20); - offset += 18; - count -= 18; - } - else - { - // we only have triangle fans of this size so don't bother with strips and triangles here. - break; - } - } - map[offset] = map[start]; - glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, count * 5, &map[offset].x); - glDrawArrays(primtype, 0, count); - map[offset] = ff; - } - else - { - glUniform1fv(GLRenderer->mShaderManager->GetActiveShader()->fakevb_index, count * 5, &map[offset].x); - glDrawArrays(primtype, 0, count); - } - break; - - case 2: - // glBufferSubData - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferSubData(GL_ARRAY_BUFFER, offset * sizeof(FFlatVertex), count * sizeof(FFlatVertex), &vbo_shadowdata[offset]); - glDrawArrays(primtype, offset, count); - break; - - case 3: - // glMapBufferRange - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - void *p = glMapBufferRange(GL_ARRAY_BUFFER, offset * sizeof(FFlatVertex), count * sizeof(FFlatVertex), GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); - if (p != NULL) - { - memcpy(p, &vbo_shadowdata[offset], count * sizeof(FFlatVertex)); - glUnmapBuffer(GL_ARRAY_BUFFER); - glDrawArrays(primtype, offset, count); - } - break; - } -} - //========================================================================== // // Initialize a single vertex @@ -390,11 +279,6 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) if (plane == sector_t::floor && sec->transdoor) vt->z -= 1; mapvt->z = vt->z; } - if (!(gl.flags & RFL_BUFFER_STORAGE)) - { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferSubData(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex), &vbo_shadowdata[startvt]); - } } //========================================================================== @@ -405,32 +289,10 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { - if (!(gl.flags & RFL_NOBUFFER)) - { - vbo_shadowdata.Resize(mNumReserved); - CreateFlatVBO(); - mCurIndex = mIndex = vbo_shadowdata.Size(); - if (gl.flags & RFL_BUFFER_STORAGE) - { - memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); - } - else - { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferSubData(GL_ARRAY_BUFFER, mNumReserved * sizeof(FFlatVertex), (mIndex - mNumReserved) * sizeof(FFlatVertex), &vbo_shadowdata[mNumReserved]); - } - } - else if (sectors) - { - // set all VBO info to invalid values so that we can save some checks in the rendering code - for(int i=0;iGetHeightSec(); - if (hs != NULL) CheckPlanes(hs); - for(unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) - CheckPlanes(sector->e->XFloor.ffloors[i]->model); - } + CheckPlanes(sector); + sector_t *hs = sector->GetHeightSec(); + if (hs != NULL) CheckPlanes(hs); + 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 b6d61f2da..de61fb7cb 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -83,14 +83,7 @@ public: 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); - } + glDrawArrays(primtype, offset, count); drawcalls.Unclock(); } diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index b91b0fe55..c507b1657 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -64,18 +64,10 @@ FLightBuffer::FLightBuffer() glGenBuffers(1, &mBufferId); glBindBuffer(mBufferType, mBufferId); unsigned int bytesize = BUFFER_SIZE * 4 * sizeof(float); - if (gl.flags & RFL_BUFFER_STORAGE) - { - glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - mBufferPointer = (float*)map; - glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId); - } - else - { - glBufferData(mBufferType, bytesize, NULL, GL_STREAM_DRAW); - mBufferPointer = NULL; - } + glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + mBufferPointer = (float*)map; + glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId); Clear(); mLastMappedIndex = UINT_MAX; @@ -109,15 +101,7 @@ int FLightBuffer::UploadLights(FDynLightData &data) float *copyptr; - if (mBufferPointer != NULL) - { - copyptr = mBufferPointer + mIndex * 4; - } - else - { - unsigned int pos = mBufferArray.Reserve(totalsize * 4); - copyptr = &mBufferArray[pos]; - } + copyptr = mBufferPointer + mIndex * 4; float parmcnt[] = { 0, size0, size0 + size1, size0 + size1 + size2 }; @@ -126,12 +110,6 @@ int FLightBuffer::UploadLights(FDynLightData &data) 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)); - if (mBufferPointer == NULL) // if we can't persistently map the buffer we need to upload it after all lights have been added. - { - glBindBuffer(mBufferType, mBufferId); - glBufferSubData(mBufferType, mIndex, totalsize * 4 * sizeof(float), copyptr); - } - unsigned int bufferindex = mIndex; mIndex += totalsize; draw_dlight += (totalsize-1) / 2; @@ -140,13 +118,6 @@ int FLightBuffer::UploadLights(FDynLightData &data) void FLightBuffer::Finish() { - /* - if (!(gl.flags & RFL_BUFFER_STORAGE)) // if we can't persistently map the buffer we need to upload it after all lights have been added. - { - glBindBuffer(mBufferType, mBufferId); - glBufferSubData(mBufferType, 0, mBufferArray.Size() * sizeof(float), &mBufferArray[0]); - } - */ Clear(); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 00683dd20..a1a22e770 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -94,17 +94,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * if (lightbuffertype == GL_UNIFORM_BUFFER) { - vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); + vp_comb.Format("#version 330 core\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } else { - vp_comb = "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; - } - - if (!(gl.flags & RFL_BUFFER_STORAGE)) - { - // we only want the uniform array hack in the shader if we actually need it. - vp_comb << "#define UNIFORM_VB\n"; + 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(); @@ -306,7 +300,7 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - if (gl.flags & RFL_SEPARATE_SHADER_OBJECTS) + if (gl.flags & RFL_SEPARATE_SHADER_OBJECTS) // this check is just for safety. All supported hardware reports this extension as being present. { glProgramUniformMatrix4fv(hShader, projectionmatrix_index, 1, false, proj->get()); glProgramUniformMatrix4fv(hShader, viewmatrix_index, 1, false, view->get()); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index ee30084f0..2f9425fe9 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -52,8 +52,6 @@ RenderContext gl; int occlusion_type=0; -CVAR(Bool, gl_persistent_avail, false, CVAR_NOSET); - //========================================================================== // // @@ -118,11 +116,10 @@ void gl_LoadExtensions() 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 3.0 - if (strcmp(version, "3.0") < 0) + if (strcmp(version, "3.3") < 0 || !CheckExtension("GL_ARB_buffer_storage")) { - I_FatalError("Unsupported OpenGL version.\nAt least GL 3.0 is required to run " GAMENAME ".\n"); + I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.3 and the »GL_ARB_buffer_storage« extension is required to run " GAMENAME ".\n"); } // add 0.01 to account for roundoff errors making the number a tad smaller than the actual version @@ -134,16 +131,8 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_shader_storage_buffer_object")) gl.flags |= RFL_SHADER_STORAGE_BUFFER; - if (CheckExtension("GL_ARB_buffer_storage") && !Args->CheckParm("-nopersistentbuffers")) - { - gl.flags |= RFL_BUFFER_STORAGE; // the cmdline option is for testing the fallback implementation on newer hardware. - gl_persistent_avail = true; - } if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS; - if (!CheckExtension("GL_ARB_compatibility")) gl.flags |= RFL_COREPROFILE; - if (!(gl.flags & (RFL_COREPROFILE|RFL_BUFFER_STORAGE)) && !strstr(gl.vendorstring, "NVIDIA Corporation")) gl.flags |= RFL_NOBUFFER; - glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 9a5c18ac4..fbafc7ca6 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -10,11 +10,8 @@ enum RenderFlags RFL_TEXTURE_COMPRESSION_S3TC=2, RFL_SEPARATE_SHADER_OBJECTS = 4, // we need this extension for glProgramUniform. On hardware not supporting it we need some rather clumsy workarounds - RFL_BUFFER_STORAGE = 8, // allows persistently mapped buffers, which are the only efficient way to actually use a dynamic vertex buffer. If this isn't present, a workaround with uniform arrays is used. RFL_SHADER_STORAGE_BUFFER = 16, // to be used later for a parameter buffer RFL_BASEINDEX = 32, // currently unused - RFL_COREPROFILE = 64, - RFL_NOBUFFER = 128, // the static buffer makes no sense on GL 3.x AMD and Intel hardware, as long as compatibility mode is on }; enum TexMode diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index c37e7a90e..0c74c9ae7 100644 --- a/src/gl/textures/gl_bitmap.cpp +++ b/src/gl/textures/gl_bitmap.cpp @@ -55,34 +55,17 @@ void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, { int i; - if (!alphatex || gl.version >= 3.3f) // GL 3.3+ uses a GL_R8 texture for alpha textures so the channels can remain as they are. + for(i=0;i 0) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 98229a1ca..697bcda4d 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -191,17 +191,7 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i if (alphatexture) { - // thanks to deprecation and delayed introduction of a suitable replacement feature this has become a bit messy... - // Of all the targeted hardware, the Intel GMA 2000 and 3000 are the only ones not supporting texture swizzle, and they - // are also the only ones not supoorting GL 3.3. On those we are forced to use a full RGBA texture here. - if (gl.version >= 3.3f) - { - texformat = GL_R8; - } - else - { - texformat = GL_RGBA8; - } + texformat = GL_R8; } else if (forcenocompression) { @@ -246,7 +236,7 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i if (deletebuffer) free(buffer); if (mipmap && use_mipmapping && !forcenofiltering) glGenerateMipmap(GL_TEXTURE_2D); - if (alphatexture && gl.version >= 3.3f) + if (alphatexture) { static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index a0e55d673..ab6d15254 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -740,14 +740,9 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) m_hRC = NULL; if (myWglCreateContextAttribsARB != NULL) { -#ifndef CORE_PROFILE - bool core = !!Args->CheckParm("-core"); -#else - bool core = true; -#endif // 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[] = { 44, 43, 42, 41, 40, 33, 32, 30, -1 }; + static int versions[] = { 44, 43, 42, 41, 40, 33, -1 }; for (int i = 0; versions[i] > 0; i++) { @@ -755,7 +750,7 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) 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, core? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0 }; @@ -763,11 +758,6 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) if (m_hRC != NULL) break; } } - if (m_hRC == 0) - { - // If we are unable to get a core context, let's try whatever the system gives us. - m_hRC = wglCreateContext(m_hDC); - } if (m_hRC == NULL) { diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index e448e42d9..cdfce4145 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -124,14 +124,6 @@ OptionValue "FuzzStyle" //5, "Jagged fuzz" I can't see any difference between this and 4 so it's disabled for now. } -OptionValue "RenderMethods" -{ - 0, "Immediate mode" - 1, "Uniform array" - 2, "Buffer upload" - 3, "Mapped buffer" -} - OptionMenu "GLTextureGLOptions" { Title "TEXTURE OPTIONS" @@ -180,7 +172,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 "Render method", gl_rendermethod, "RenderMethods", "gl_persistent_avail" } OptionMenu "OpenGLOptions" diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index e355141f0..16c3c8738 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -11,34 +11,12 @@ out vec2 glowdist; out vec4 vTexCoord; out vec4 vColor; -#ifdef UNIFORM_VB -uniform float fakeVB[100]; -#endif - void main() { - vec4 vert; - vec4 tc; - -#ifdef UNIFORM_VB - - if (aTexCoord.x >= 100000.0) - { - int fakeVI = int(aTexCoord.y)*5; - vert = aPosition + vec4(fakeVB[fakeVI], fakeVB[fakeVI+1], fakeVB[fakeVI+2], 0.0); - tc = vec4(fakeVB[fakeVI+3], fakeVB[fakeVI+4], 0.0, 0.0); - } - else -#endif - { - vert = aPosition; - tc = vec4(aTexCoord, 0.0, 0.0); - } - #ifndef SIMPLE - vec4 worldcoord = ModelMatrix * mix(vert, aVertex2, uInterpolationFactor); + vec4 worldcoord = ModelMatrix * mix(aPosition, aVertex2, uInterpolationFactor); #else - vec4 worldcoord = ModelMatrix * vert; + vec4 worldcoord = ModelMatrix * aPosition; #endif vec4 eyeCoordPos = ViewMatrix * worldcoord; @@ -55,13 +33,13 @@ void main() #ifdef SPHEREMAP vec3 u = normalize(eyeCoordPos.xyz); - vec4 n = normalize(TextureMatrix * vec4(tc.x, 0.0, tc.y, 0.0)); // use texture matrix and coordinates for our normal. Since this is only used on walls, the normal's y coordinate is always 0. + vec4 n = normalize(TextureMatrix * vec4(aTexCoord.x, 0.0, aTexCoord.y, 0.0)); // use texture matrix and coordinates for our normal. Since this is only used on walls, the normal's y coordinate is always 0. vec3 r = reflect(u, n.xyz); float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) ); vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5); vTexCoord.xy = sst; #else - vTexCoord = TextureMatrix * tc; + vTexCoord = TextureMatrix * vec4(aTexCoord, 0.0, 0.0); #endif gl_Position = ProjectionMatrix * eyeCoordPos; From b2860a1d63170ed4ff4e1db651764dbd64af6b1e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Aug 2014 11:57:42 +0200 Subject: [PATCH 102/138] - it looks like glProgramUniform is not working correctly with Intel drivers, so better forget about it for setting the view and projection matrices. Even on NVidia the time difference can only be measured in microseconds per frame so it's not a big loss. --- src/gl/shaders/gl_shader.cpp | 15 +++------------ src/gl/system/gl_interface.cpp | 1 - src/gl/system/gl_interface.h | 4 +--- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index a1a22e770..480d97d25 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -299,18 +299,9 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - - if (gl.flags & RFL_SEPARATE_SHADER_OBJECTS) // this check is just for safety. All supported hardware reports this extension as being present. - { - glProgramUniformMatrix4fv(hShader, projectionmatrix_index, 1, false, proj->get()); - glProgramUniformMatrix4fv(hShader, viewmatrix_index, 1, false, view->get()); - } - else - { - Bind(); - glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get()); - glUniformMatrix4fv(viewmatrix_index, 1, false, view->get()); - } + Bind(); + glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get()); + glUniformMatrix4fv(viewmatrix_index, 1, false, view->get()); } diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 2f9425fe9..4da1d9a42 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -131,7 +131,6 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_shader_storage_buffer_object")) gl.flags |= RFL_SHADER_STORAGE_BUFFER; - if (CheckExtension("GL_ARB_separate_shader_objects")) gl.flags |= RFL_SEPARATE_SHADER_OBJECTS; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index fbafc7ca6..5d59e5560 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -9,9 +9,7 @@ enum RenderFlags RFL_TEXTURE_COMPRESSION=1, RFL_TEXTURE_COMPRESSION_S3TC=2, - RFL_SEPARATE_SHADER_OBJECTS = 4, // we need this extension for glProgramUniform. On hardware not supporting it we need some rather clumsy workarounds - RFL_SHADER_STORAGE_BUFFER = 16, // to be used later for a parameter buffer - RFL_BASEINDEX = 32, // currently unused + RFL_SHADER_STORAGE_BUFFER = 4, // to be used later for a parameter buffer }; enum TexMode From e35fefdc06b9a185899df9f3d3bcdaedfb0d2895 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Aug 2014 11:59:04 +0200 Subject: [PATCH 103/138] - better rebind the active shader after updating the matrices. --- src/gl/shaders/gl_shader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 480d97d25..7cd6ead74 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -520,6 +520,7 @@ void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { mEffectShaders[i]->ApplyMatrices(proj, view); } + if (mActiveShader != NULL) mActiveShader->Bind(); } //========================================================================== From a97b58fa27e648afff6f6097896957ba6db0f4d9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Aug 2014 20:41:13 +0200 Subject: [PATCH 104/138] - added check for light uniform buffer overflows, because uniform buffers on Intel are rather small. --- src/gl/dynlights/gl_lightbuffer.cpp | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index c507b1657..b787be9e2 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -52,13 +52,15 @@ FLightBuffer::FLightBuffer() if (gl.flags & RFL_SHADER_STORAGE_BUFFER) { mBufferType = GL_SHADER_STORAGE_BUFFER; - mBlockAlign = 0; + mBlockAlign = -1; + mBlockSize = BUFFER_SIZE; } else { mBufferType = GL_UNIFORM_BUFFER; - mBlockSize = 2048;// gl.maxuniformblock / 4 - 100; - mBlockAlign = 1024;// ((mBlockSize * 2) & ~(gl.uniformblockalignment - 1)) / 4; // count in vec4's + mBlockSize = gl.maxuniformblock / 16; + if (mBlockSize > 2048) mBlockSize = 2048; // we don't really need a larger buffer + mBlockAlign = mBlockSize / 2; } glGenBuffers(1, &mBufferId); @@ -92,6 +94,30 @@ int FLightBuffer::UploadLights(FDynLightData &data) int size2 = data.arrays[2].Size()/4; int totalsize = size0 + size1 + size2 + 1; + if (mBlockAlign >= 0 && totalsize + (mIndex % mBlockAlign) > mBlockSize) + { + mIndex = ((mIndex + mBlockAlign) / mBlockAlign) * mBlockAlign; + + // can't be rendered all at once. + if (totalsize > mBlockSize) + { + int diff = totalsize - mBlockSize; + + size2 -= diff; + if (size2 < 0) + { + size1 += size2; + size2 = 0; + } + if (size1 < 0) + { + size0 += size1; + size1 = 0; + } + totalsize = size0 + size1 + size2 + 1; + } + } + if (totalsize <= 1) return -1; if (mIndex + totalsize > BUFFER_SIZE) From a63871d1709beedb4a8ec34a2f81733e491bdb3d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Aug 2014 21:06:34 +0200 Subject: [PATCH 105/138] - at least for Intel GMA we need shaders without 'discard' to render non-transparent stuff. The performance penalty is rather hefty here. --- src/gl/renderer/gl_renderstate.cpp | 3 +-- src/gl/shaders/gl_shader.cpp | 16 +++++++++++++++- src/gl/shaders/gl_shader.h | 7 ++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 464880895..bdd0867b9 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -106,8 +106,7 @@ bool FRenderState::ApplyShader() } else { - // todo: check how performance is affected by using 'discard' in a shader and if necessary create a separate set of discard-less shaders. - activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); + activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f); activeShader->Bind(); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 7cd6ead74..26a1b3159 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -387,6 +387,8 @@ void FShaderManager::CompileShaders() { mActiveShader = NULL; + mTextureEffects.Clear(); + mTextureEffectsNAT.Clear(); for (int i = 0; i < MAX_EFFECTS; i++) { mEffectShaders[i] = NULL; @@ -396,6 +398,11 @@ void FShaderManager::CompileShaders() { FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true); mTextureEffects.Push(shc); + if (i <= 3) + { + FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false); + mTextureEffectsNAT.Push(shc); + } } for(unsigned i = 0; i < usershaders.Size(); i++) @@ -430,6 +437,10 @@ void FShaderManager::Clean() glUseProgram(0); mActiveShader = NULL; + for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++) + { + if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i]; + } for (unsigned int i = 0; i < mTextureEffects.Size(); i++) { if (mTextureEffects[i] != NULL) delete mTextureEffects[i]; @@ -440,6 +451,7 @@ void FShaderManager::Clean() mEffectShaders[i] = NULL; } mTextureEffects.Clear(); + mTextureEffectsNAT.Clear(); } //========================================================================== @@ -504,10 +516,12 @@ EXTERN_CVAR(Int, gl_fuzztype) void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - for (int i = 0; i <= 4; i++) + 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); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index e100e9bf1..92ef221af 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -249,6 +249,7 @@ public: class FShaderManager { TArray mTextureEffects; + TArray mTextureEffectsNAT; FShader *mActiveShader; FShader *mEffectShaders[MAX_EFFECTS]; @@ -268,9 +269,13 @@ public: return mActiveShader; } - FShader *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]; From cd5e429d3b0251b3d6da23e64e2a0d59cd2b9499 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Aug 2014 23:12:08 +0200 Subject: [PATCH 106/138] - adjust version number. --- src/version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/version.h b/src/version.h index fca56ab8c..4db09f1c6 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.0.01pre" // 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.0.01pre" // Version identifier for network games. // Bump it every time you do a release unless you're certain you From 19cfffebb3a141f9fa3a5a167e96cb3ac8d6582e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Aug 2014 12:21:05 +0200 Subject: [PATCH 107/138] - fixed: the WallTypes enum contained a value that no longer was valid. This was fixed orignally last week but it seems to have gotten lost. --- src/gl/scene/gl_wall.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index ffe9ba2a5..37501c607 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -39,7 +39,6 @@ enum WallTypes RENDERWALL_MIRROR, RENDERWALL_MIRRORSURFACE, RENDERWALL_M2SNF, - RENDERWALL_M2SFOG, RENDERWALL_COLOR, RENDERWALL_FFBLOCK, RENDERWALL_COLORLAYER, From 370582d2fad3429d99dcc7811cfed454709f2eda Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Aug 2014 12:25:59 +0200 Subject: [PATCH 108/138] - corrected versioning info for development branch. --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 4db09f1c6..c24e51a21 100644 --- a/src/version.h +++ b/src/version.h @@ -41,12 +41,12 @@ const char *GetVersionString(); /** Lots of different version numbers **/ -#define VERSIONSTR "2.0.01pre" +#define VERSIONSTR "2.1pre" // The version as seen in the Windows resource #define RC_FILEVERSION 2,0,9999,0 #define RC_PRODUCTVERSION 2,0,9999,0 -#define RC_PRODUCTVERSION2 "2.0.01pre" +#define RC_PRODUCTVERSION2 "2.1pre" // Version identifier for network games. // Bump it every time you do a release unless you're certain you From b9ffb51d0c7d61693982fdfe7e7d5803d29c853f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 4 Aug 2014 23:00:40 +0200 Subject: [PATCH 109/138] - small but important optimization: Two-sided lines with both sides in the same sector don't really require vertex splitting for precise rendering. --- src/gl/scene/gl_wall.h | 1 + src/gl/scene/gl_walls.cpp | 1 + src/gl/scene/gl_walls_draw.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 37501c607..a317ac267 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -99,6 +99,7 @@ public: GLWF_GLOW=8, // illuminated by glowing flats GLWF_NOSPLITUPPER=16, GLWF_NOSPLITLOWER=32, + GLWF_NOSPLIT=64, }; enum diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index cd179a265..ab6d710d4 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -984,6 +984,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! diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 98bc9f661..c4576acc8 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -166,7 +166,7 @@ void GLWall::SetupLights() void GLWall::RenderWall(int textured, unsigned int *store) { 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)); + bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT)); tcs[0]=lolft; tcs[1]=uplft; From 38796e7714730ba4836720ef4023b3234fb53e03 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Aug 2014 11:41:03 +0200 Subject: [PATCH 110/138] - removed some obsolete and useless GL calls. --- src/gl/scene/gl_scene.cpp | 1 - src/gl/system/gl_framebuffer.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index e301b3da6..38fc5a7eb 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -659,7 +659,6 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) } glDisable(GL_STENCIL_TEST); - glDisable(GL_POLYGON_SMOOTH); framebuffer->Begin2D(false); diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index b2f147dc1..2b03db013 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -150,8 +150,6 @@ void OpenGLFrameBuffer::InitializeState() glEnable(GL_TEXTURE_2D); glDisable(GL_LINE_SMOOTH); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); From 00d7707aef51582a391edb9c9a546a92ad1dd051 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 19 Aug 2014 14:18:21 +0200 Subject: [PATCH 111/138] - allow reallocation of light buffer if more lights are needed. - added a light preprocessing pass to the renderer so that a non-persistent buffer can be used with minimal mapping/unmapping. This only gets used if necessary because it adds some overhead to the renderer. --- src/gl/dynlights/gl_lightbuffer.cpp | 81 ++++++++-- src/gl/dynlights/gl_lightbuffer.h | 9 +- src/gl/renderer/gl_renderer.cpp | 2 +- src/gl/scene/gl_drawinfo.cpp | 10 +- src/gl/scene/gl_drawinfo.h | 5 +- src/gl/scene/gl_flats.cpp | 94 ++++++++++-- src/gl/scene/gl_scene.cpp | 37 +++-- src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_wall.h | 7 +- src/gl/scene/gl_walls.cpp | 222 ++++++++++++++-------------- src/gl/scene/gl_walls_draw.cpp | 23 ++- 11 files changed, 323 insertions(+), 169 deletions(-) diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index b787be9e2..05dc7ec55 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -45,15 +45,20 @@ #include "gl/system/gl_interface.h" #include "gl/utility//gl_clock.h" -static const int BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB. +static const int INITIAL_BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB. + +float *mMap; FLightBuffer::FLightBuffer() { + + mBufferSize = INITIAL_BUFFER_SIZE; + mByteSize = mBufferSize * sizeof(float); if (gl.flags & RFL_SHADER_STORAGE_BUFFER) { mBufferType = GL_SHADER_STORAGE_BUFFER; mBlockAlign = -1; - mBlockSize = BUFFER_SIZE; + mBlockSize = mBufferSize; } else { @@ -64,12 +69,17 @@ FLightBuffer::FLightBuffer() } glGenBuffers(1, &mBufferId); - glBindBuffer(mBufferType, mBufferId); - unsigned int bytesize = BUFFER_SIZE * 4 * sizeof(float); - glBufferStorage(mBufferType, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - void *map = glMapBufferRange(mBufferType, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - mBufferPointer = (float*)map; glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId); + if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + { + 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; + } Clear(); mLastMappedIndex = UINT_MAX; @@ -84,7 +94,8 @@ FLightBuffer::~FLightBuffer() void FLightBuffer::Clear() { mIndex = 0; - mBufferArray.Clear(); + mIndices.Clear(); + mUploadIndex = 0; } int FLightBuffer::UploadLights(FDynLightData &data) @@ -120,13 +131,45 @@ int FLightBuffer::UploadLights(FDynLightData &data) if (totalsize <= 1) return -1; - if (mIndex + totalsize > BUFFER_SIZE) + if (mIndex + totalsize > mBufferSize) { - return -1; // we ran out of space. All following lights will be ignored + // 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_SHADER_STORAGE_BUFFER) + { + 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 }; @@ -142,9 +185,23 @@ int FLightBuffer::UploadLights(FDynLightData &data) return bufferindex; } +void FLightBuffer::Begin() +{ + if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + { + glBindBuffer(mBufferType, mBufferId); + mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT); + } +} + void FLightBuffer::Finish() { - Clear(); + if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + { + glBindBuffer(mBufferType, mBufferId); + glUnmapBuffer(mBufferType); + mBufferPointer = NULL; + } } int FLightBuffer::BindUBO(unsigned int index) diff --git a/src/gl/dynlights/gl_lightbuffer.h b/src/gl/dynlights/gl_lightbuffer.h index 8e50555c3..8781ccb57 100644 --- a/src/gl/dynlights/gl_lightbuffer.h +++ b/src/gl/dynlights/gl_lightbuffer.h @@ -6,15 +6,18 @@ struct FDynLightData; class FLightBuffer { - TArray mBufferArray; + TArray mIndices; unsigned int mBufferId; float * mBufferPointer; 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: @@ -22,10 +25,14 @@ public: ~FLightBuffer(); 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 diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index ceb553f86..effbec942 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -110,7 +110,7 @@ void FGLRenderer::Initialize() mVBO = new FFlatVertexBuffer; mSkyVBO = new FSkyVertexBuffer; mModelVBO = new FModelVertexBuffer; - mLights = new FLightBuffer; + mLights = new FLightBuffer(); gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; SetupLevel(); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index cac3bad6a..8461a90eb 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -692,7 +692,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 +700,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; @@ -739,13 +739,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 +779,7 @@ void GLDrawList::Draw(int pass) { for(unsigned i=0;imLights->GetIndex(*dli)); + (*dli)++; + return; + } + lightdata.Clear(); FLightNode * node = sub->lighthead; while (node) @@ -143,9 +150,15 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) node = node->nextLight; } - dynlightindex = GLRenderer->mLights->UploadLights(lightdata); - gl_RenderState.ApplyLightIndex(dynlightindex); - return false; + int d = GLRenderer->mLights->UploadLights(lightdata); + if (pass == GLPASS_LIGHTSONLY) + { + GLRenderer->mLights->StoreIndex(d); + } + else + { + gl_RenderState.ApplyLightIndex(d); + } } //========================================================================== @@ -197,15 +210,59 @@ void GLFlat::DrawSubsector(subsector_t * sub) // //========================================================================== -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 @@ -216,10 +273,10 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) 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(); @@ -237,7 +294,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) 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); } } @@ -252,7 +309,7 @@ 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; } @@ -266,7 +323,7 @@ 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 rel = getExtraLight(); @@ -286,10 +343,17 @@ void GLFlat::Draw(int pass) gl_SetFog(lightlevel, rel, &Colormap, false); gltexture->Bind(); gl_SetPlaneTextureRotation(&plane, gltexture); - DrawSubsectors(pass, false); + DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false); gl_RenderState.EnableTextureMatrix(false); break; + case GLPASS_LIGHTSONLY: + if (!trans || gltexture) + { + ProcessLights(trans); + } + break; + case GLPASS_TRANSLUCENT: if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE); gl_SetColor(lightlevel, rel, Colormap, alpha); @@ -298,14 +362,14 @@ void GLFlat::Draw(int pass) if (!gltexture) { gl_RenderState.EnableTexture(false); - DrawSubsectors(pass, true); + DrawSubsectors(pass, false, true); gl_RenderState.EnableTexture(true); } else { gltexture->Bind(); gl_SetPlaneTextureRotation(&plane, gltexture); - DrawSubsectors(pass, true); + DrawSubsectors(pass, true, true); gl_RenderState.EnableTextureMatrix(false); } if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 38fc5a7eb..93bda9494 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -340,20 +340,31 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableFog(true); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); - // First draw all single-pass stuff + gl_drawinfo->drawlists[GLDL_PLAIN].Sort(); + gl_drawinfo->drawlists[GLDL_MASKED].Sort(); + gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort(); + + // 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_SHADER_STORAGE_BUFFER)) + { + GLRenderer->mLights->Begin(); + gl_drawinfo->drawlists[GLDL_PLAIN].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKED].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(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.AlphaFunc(GL_GEQUAL, 0.f); - - glDisable(GL_POLYGON_OFFSET_FILL); // just in case - GLRenderer->mLights->Finish(); + glDisable(GL_POLYGON_OFFSET_FILL); int pass; - if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights) + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_SHADER_STORAGE_BUFFER)) { pass = GLPASS_ALL; } @@ -364,7 +375,6 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_PLAIN].Sort(); gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass); @@ -375,15 +385,13 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.SetTextureMode(TM_MASK); } gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->drawlists[GLDL_MASKED].Sort(); gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); - // this list is empty most of the time so only waste time on it when in use. + // 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_MASKEDOFS].Size() > 0) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); - gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort(); gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(pass); glDisable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0, 0); @@ -393,7 +401,7 @@ void FGLRenderer::RenderScene(int recursion) 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); @@ -413,8 +421,8 @@ 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); @@ -782,6 +790,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo SetCameraPos(viewx, viewy, viewz, viewangle); SetViewMatrix(false, false); gl_RenderState.ApplyMatrices(); + GLRenderer->mLights->Clear(); clipper.Clear(); angle_t a1 = FrustumAngle(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index e21b0e985..4aa0f90bc 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -112,7 +112,7 @@ CVAR(Bool, gl_nolayer, false, 0) //========================================================================== void GLSprite::Draw(int pass) { - if (pass == GLPASS_DECALS) return; + if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index a317ac267..7a6acbc89 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -279,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); }; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index ab6d710d4..bcf0080d0 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -1408,7 +1408,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; @@ -1422,7 +1422,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; @@ -1437,24 +1437,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); @@ -1463,29 +1463,29 @@ 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; + 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; @@ -1495,10 +1495,10 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) 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 @@ -1506,35 +1506,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 { @@ -1543,27 +1543,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), 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 @@ -1576,8 +1576,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 { @@ -1586,51 +1586,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), 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), 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)) @@ -1650,58 +1650,58 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) { tex = tex->GetRawTexture(); } - gltexture=FMaterial::ValidateTexture(tex); + gltexture = FMaterial::ValidateTexture(tex); } 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), 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), 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)) { gl_drawinfo->AddLowerMissingTexture(seg->sidedef, sub, bfh1); @@ -1717,19 +1717,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); @@ -1758,10 +1758,10 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), 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 c4576acc8..51bf5de18 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -70,8 +70,19 @@ EXTERN_CVAR(Bool, gl_seamless) //========================================================================== 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; @@ -357,7 +368,7 @@ void GLWall::Draw(int pass) #endif - if (type == RENDERWALL_COLORLAYER) + if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); @@ -365,10 +376,14 @@ void GLWall::Draw(int pass) 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); if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false); @@ -409,7 +424,7 @@ void GLWall::Draw(int pass) } } - if (type == RENDERWALL_COLORLAYER) + if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY) { glDisable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0, 0); From a2dc4afe3f7318c4d5650b77b1277e5e26d2b640 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 19 Aug 2014 14:25:47 +0200 Subject: [PATCH 112/138] - screwed by the editor's autocompletion... (wrong GL flag was used...) --- src/gl/dynlights/gl_lightbuffer.cpp | 10 +++++----- src/gl/scene/gl_scene.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index 05dc7ec55..3031d3916 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -54,7 +54,7 @@ FLightBuffer::FLightBuffer() mBufferSize = INITIAL_BUFFER_SIZE; mByteSize = mBufferSize * sizeof(float); - if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + if (gl.flags & RFL_BUFFER_STORAGE) { mBufferType = GL_SHADER_STORAGE_BUFFER; mBlockAlign = -1; @@ -70,7 +70,7 @@ FLightBuffer::FLightBuffer() glGenBuffers(1, &mBufferId); glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId); - if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + 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); @@ -148,7 +148,7 @@ int FLightBuffer::UploadLights(FDynLightData &data) // create the new buffer's storage (twice as large as the old one) mBufferSize *= 2; mByteSize *= 2; - if (gl.flags & RFL_SHADER_STORAGE_BUFFER) + 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); @@ -187,7 +187,7 @@ int FLightBuffer::UploadLights(FDynLightData &data) void FLightBuffer::Begin() { - if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (!(gl.flags & RFL_BUFFER_STORAGE)) { glBindBuffer(mBufferType, mBufferId); mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT); @@ -196,7 +196,7 @@ void FLightBuffer::Begin() void FLightBuffer::Finish() { - if (!(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (!(gl.flags & RFL_BUFFER_STORAGE)) { glBindBuffer(mBufferType, mBufferId); glUnmapBuffer(mBufferType); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 93bda9494..afd9259f2 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -346,7 +346,7 @@ void FGLRenderer::RenderScene(int recursion) // 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_SHADER_STORAGE_BUFFER)) + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE)) { GLRenderer->mLights->Begin(); gl_drawinfo->drawlists[GLDL_PLAIN].Draw(GLPASS_LIGHTSONLY); @@ -364,7 +364,7 @@ void FGLRenderer::RenderScene(int recursion) int pass; - if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_BUFFER_STORAGE)) { pass = GLPASS_ALL; } From 86d37e06f961c55d4ad02d5aac8788cd15e5190b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 19 Aug 2014 15:56:33 +0200 Subject: [PATCH 113/138] - lowered requirements of GL 2.x to OpenGL 3.3. There was one issue preventing the previous 2.0 betas from running under GL 3.x: The lack of persistently mapped buffers. For the dynamic light buffer today's changes take care of that problem. For the vertex buffer there is no good workaround but we can use immediate mode render calls instead which have been reinstated. To handle the current setup, the engine first tries to get a core profile context and checks for presence of GL 4.4 or the GL_ARB_buffer_storage extension. If this fails the context is deleted again and a compatibility context retrieved which is then used for 'old style' rendering which does work on older GL versions. This new version does not support GL 3.2 or lower, meaning that Intel GMA 3000 or lower is not supported. The reason for this is that the engine uses a few GL 3.3 features which are not present in the latest Intel driver. In general the Intel GMA 3000 is far too weak, though, to run the demanding shader of GZDoom 2.x, so this is no real loss. Performance would be far from satisfying. A command line option '-gl3' exists to force the fallback render path. On my Geforce 550Ti there's approx. 10% performance loss on this path. --- src/gl/data/gl_vertexbuffer.cpp | 99 +++++++++++++++++++++++++-------- src/gl/data/gl_vertexbuffer.h | 9 ++- src/gl/system/gl_interface.cpp | 11 +++- src/gl/system/gl_interface.h | 3 +- src/win32/win32gliface.cpp | 90 +++++++++++++++++++++--------- src/win32/win32gliface.h | 1 + 6 files changed, 159 insertions(+), 54 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 854750ecb..0e9065557 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -90,26 +90,60 @@ void FVertexBuffer::BindVBO() FFlatVertexBuffer::FFlatVertexBuffer() : FVertexBuffer() { - 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); - mNumReserved = mIndex = mCurIndex = 0; + 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); + 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() { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); + 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 } //========================================================================== @@ -289,10 +323,24 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane) void FFlatVertexBuffer::CreateVBO() { - vbo_shadowdata.Resize(mNumReserved); - CreateFlatVBO(); - mCurIndex = mIndex = vbo_shadowdata.Size(); - memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); + if (gl.flags & RFL_BUFFER_STORAGE) + { + vbo_shadowdata.Resize(mNumReserved); + CreateFlatVBO(); + mCurIndex = mIndex = vbo_shadowdata.Size(); + memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); + } + else if (sectors) + { + // set all VBO info to invalid values so that we can save some checks in the rendering code + for(int i=0;iGetHeightSec(); - if (hs != NULL) CheckPlanes(hs); - for(unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) - CheckPlanes(sector->e->XFloor.ffloors[i]->model); + 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++) + 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 de61fb7cb..b6d61f2da 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -83,7 +83,14 @@ public: void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count) { drawcalls.Clock(); - glDrawArrays(primtype, offset, count); + if (gl.flags & RFL_BUFFER_STORAGE) + { + glDrawArrays(primtype, offset, count); + } + else + { + ImmRenderBuffer(primtype, offset, count); + } drawcalls.Unclock(); } diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 4da1d9a42..7a745110b 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -117,9 +117,9 @@ void gl_LoadExtensions() else Printf("Emulating OpenGL v %s\n", version); // Don't even start if it's lower than 3.0 - if (strcmp(version, "3.3") < 0 || !CheckExtension("GL_ARB_buffer_storage")) + if (strcmp(version, "3.3") < 0) { - I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.3 and the »GL_ARB_buffer_storage« extension is required to run " GAMENAME ".\n"); + I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.3 is required to run " GAMENAME ".\n"); } // add 0.01 to account for roundoff errors making the number a tad smaller than the actual version @@ -130,7 +130,12 @@ void gl_LoadExtensions() 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 (CheckExtension("GL_ARB_shader_storage_buffer_object")) gl.flags |= RFL_SHADER_STORAGE_BUFFER; + 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; + } glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 5d59e5560..af4c4f7c2 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -9,7 +9,8 @@ enum RenderFlags RFL_TEXTURE_COMPRESSION=1, RFL_TEXTURE_COMPRESSION_S3TC=2, - RFL_SHADER_STORAGE_BUFFER = 4, // to be used later for a parameter buffer + RFL_SHADER_STORAGE_BUFFER = 4, + RFL_BUFFER_STORAGE = 8 }; enum TexMode diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index ab6d15254..a9911460f 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -726,6 +726,32 @@ bool Win32GLVideo::SetupPixelFormat(int multisample) // //========================================================================== +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 GLEW 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; @@ -737,36 +763,50 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) return false; } - m_hRC = NULL; - if (myWglCreateContextAttribsARB != NULL) + for (int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) { - // 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[] = { 44, 43, 42, 41, 40, 33, -1 }; - - for (int i = 0; versions[i] > 0; i++) + m_hRC = NULL; + if (myWglCreateContextAttribsARB != NULL) { - 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, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 0 - }; + // 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.3 is a requirement. + static int versions[] = { 45, 44, 43, 42, 41, 40, 33, -1 }; - m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); - if (m_hRC != NULL) break; + 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 + }; + + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); + if (m_hRC != NULL) break; + } + } + + 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; } } - - if (m_hRC == NULL) - { - Printf ("R_OPENGL: Couldn't create render context. Reverting to software mode...\n"); - return false; - } - - wglMakeCurrent(m_hDC, m_hRC); - return true; + return false; } //========================================================================== diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index f61c31857..f425757f1 100644 --- a/src/win32/win32gliface.h +++ b/src/win32/win32gliface.h @@ -87,6 +87,7 @@ protected: void MakeModesList(); void AddMode(int x, int y, int bits, int baseHeight, int refreshHz); void FreeModes(); + bool checkCoreUsability(); public: int GetTrueHeight() { return m_trueHeight; } From 6f65bccf1c805ef001294b86f604cd49d7a291ec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 20 Aug 2014 12:45:33 +0200 Subject: [PATCH 114/138] - reinstated the far superior assembly HQnX version for Visual C++. --- src/CMakeLists.txt | 6 + src/gl/hqnx_asm/hq2x_asm.cpp | 2991 +++++++++++++++ src/gl/hqnx_asm/hq3x_asm.cpp | 3874 ++++++++++++++++++++ src/gl/hqnx_asm/hq4x_asm.cpp | 5474 ++++++++++++++++++++++++++++ src/gl/hqnx_asm/hqnx_asm.h | 39 + src/gl/hqnx_asm/hqnx_asm_Image.cpp | 1179 ++++++ src/gl/hqnx_asm/hqnx_asm_Image.h | 150 + src/gl/textures/gl_hqresize.cpp | 52 +- 8 files changed, 13761 insertions(+), 4 deletions(-) create mode 100644 src/gl/hqnx_asm/hq2x_asm.cpp create mode 100644 src/gl/hqnx_asm/hq3x_asm.cpp create mode 100644 src/gl/hqnx_asm/hq4x_asm.cpp create mode 100644 src/gl/hqnx_asm/hqnx_asm.h create mode 100644 src/gl/hqnx_asm/hqnx_asm_Image.cpp create mode 100644 src/gl/hqnx_asm/hqnx_asm_Image.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1e495f6f6..a219d2054 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -581,6 +581,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 +731,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 @@ -1298,6 +1303,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/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/textures/gl_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp index 59e84051e..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 @@ -245,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 @@ -267,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; From e132fc5eed66fb4403c70055e500e2ffa727a337 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Aug 2014 11:02:46 +0200 Subject: [PATCH 115/138] - replaced GLEW with GLLoadGen for GL access. This allows to have a header that only contains what's actually required, namely OpenGL 3.3 plus glBegin and glEnd which are the only compatibility functions needed for the fallback render path. GLEW has two major problems: - it always includes everything, there is no way to restrict the header to a specific GL version - it is mostly broken with a core profile and only works if all sanity checks get switched off. --- src/CMakeLists.txt | 28 +- src/gl/system/gl_framebuffer.cpp | 6 +- src/gl/system/gl_load.c | 1344 ++++++++++++++++++++++ src/gl/system/gl_load.h | 1793 ++++++++++++++++++++++++++++++ src/gl/system/gl_system.h | 5 +- src/win32/win32gliface.cpp | 22 +- src/win32/win32gliface.h | 1 - 7 files changed, 3156 insertions(+), 43 deletions(-) create mode 100644 src/gl/system/gl_load.c create mode 100644 src/gl/system/gl_load.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a219d2054..dcaddff32 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 ) @@ -1099,6 +1072,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 diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 2b03db013..54df9b851 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -121,8 +121,7 @@ void OpenGLFrameBuffer::InitializeState() if (first) { - glewExperimental=true; - glewInit(); + ogl_LoadFunctions(); } gl_LoadExtensions(); @@ -536,4 +535,5 @@ void OpenGLFrameBuffer::GameRestart() ScreenshotBuffer = NULL; LastCamera = NULL; gl_GenerateGlobalBrightmapFromColormap(); -} \ No newline at end of file +} + diff --git a/src/gl/system/gl_load.c b/src/gl/system/gl_load.c new file mode 100644 index 000000000..2b55cb3a9 --- /dev/null +++ b/src/gl/system/gl_load.c @@ -0,0 +1,1344 @@ +#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 +#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_system.h b/src/gl/system/gl_system.h index 2130c9cbb..5cfd7fe5c 100644 --- a/src/gl/system/gl_system.h +++ b/src/gl/system/gl_system.h @@ -67,13 +67,10 @@ #include //GL headers -#include +#include "gl_load.h" #if defined(__APPLE__) #include -#elif defined(__unix__) - //#include -#else // !__APPLE__ && !__unix__ #endif #ifdef _WIN32 diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index a9911460f..81b1d9418 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -1,13 +1,15 @@ -#include "gl/system/gl_system.h" - -#define DWORD WINDOWS_DWORD -#include -#undef DWORD +//#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" @@ -22,8 +24,6 @@ #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; @@ -726,6 +726,12 @@ bool Win32GLVideo::SetupPixelFormat(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. @@ -734,7 +740,7 @@ bool Win32GLVideo::checkCoreUsability() // GL 4.4 implies GL_ARB_buffer_storage if (strcmp((char*)glGetString(GL_VERSION), "4.4") >= 0) return true; - // at this point GLEW has not been initialized so we have to retrieve glGetStringi ourselves. + // 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. diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h index f425757f1..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" From 78815a960195bc095a0041764e060b034ca280ab Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Aug 2014 11:29:43 +0200 Subject: [PATCH 116/138] -we need this, too. --- src/win32/wglext.h | 840 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 840 insertions(+) create mode 100644 src/win32/wglext.h 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 From 274a4216ea2b65d1d086884933adfb08bf8d1a0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Aug 2014 11:47:53 +0200 Subject: [PATCH 117/138] - disabling inlining in the GL loader produces an executable that's 8kb smaller. --- src/gl/system/gl_load.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gl/system/gl_load.c b/src/gl/system/gl_load.c index 2b55cb3a9..282395016 100644 --- a/src/gl/system/gl_load.c +++ b/src/gl/system/gl_load.c @@ -53,6 +53,8 @@ static void* SunGetProcAddress (const GLubyte* name) #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 From 1050013017a5c37814269f6823cafb0df5b0d49d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 22 Aug 2014 23:50:38 +0200 Subject: [PATCH 118/138] major cleanup of the texture manager: - use sampler objects to avoid creating up to 4 different system textures for one game texture just because of different clamping settings. - avoids flushing all textures for change of texture filter mode. - separate sprite and regular dimensions on the material level to have better control over which one gets used. It's now an explicit parameter of ValidateTexture. The main reason for this change is better handling of wall sprites which may not be subjected to such handling. - create mipmaps based on use case, not texture type. - allows removal of FCloneTexture hack for proper sharing of the same sprite for decals and other purposes. - better precaching of skyboxes. --- src/CMakeLists.txt | 1 + src/gl/models/gl_models_md2.cpp | 4 +- src/gl/models/gl_models_md3.cpp | 4 +- src/gl/models/gl_voxels.cpp | 4 +- src/gl/renderer/gl_renderer.cpp | 26 +- src/gl/renderer/gl_renderer.h | 2 + src/gl/scene/gl_decal.cpp | 22 +- src/gl/scene/gl_drawinfo.cpp | 4 +- src/gl/scene/gl_flats.cpp | 18 +- src/gl/scene/gl_portal.cpp | 4 +- src/gl/scene/gl_scene.cpp | 16 +- src/gl/scene/gl_sky.cpp | 8 +- src/gl/scene/gl_skydome.cpp | 30 +- src/gl/scene/gl_sprite.cpp | 20 +- src/gl/scene/gl_walls.cpp | 28 +- src/gl/scene/gl_walls_draw.cpp | 8 +- src/gl/scene/gl_weapon.cpp | 18 +- src/gl/system/gl_wipe.cpp | 35 +-- src/gl/textures/gl_hwtexture.cpp | 148 ++++------ src/gl/textures/gl_hwtexture.h | 27 +- src/gl/textures/gl_material.cpp | 414 +++++++-------------------- src/gl/textures/gl_material.h | 131 +++++---- src/gl/textures/gl_samplers.cpp | 112 ++++++++ src/gl/textures/gl_samplers.h | 28 ++ src/gl/textures/gl_skyboxtexture.cpp | 10 +- src/gl/textures/gl_skyboxtexture.h | 2 +- src/gl/textures/gl_texture.cpp | 134 +++++---- src/gl/textures/gl_texture.h | 17 -- src/textures/texturemanager.cpp | 2 + src/textures/textures.h | 11 +- src/v_video.cpp | 8 +- 31 files changed, 596 insertions(+), 700 deletions(-) create mode 100644 src/gl/textures/gl_samplers.cpp create mode 100644 src/gl/textures/gl_samplers.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dcaddff32..38cc45189 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1042,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 diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index df6d8f88e..76835c737 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -301,9 +301,9 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double i if (!skin) return; } - FMaterial * tex = FMaterial::ValidateTexture(skin); + FMaterial * tex = FMaterial::ValidateTexture(skin, false); - tex->Bind(0, translation); + tex->Bind(CLAMP_NONE, translation, -1, false); gl_RenderState.Apply(); GLRenderer->mModelVBO->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, inter); diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index cb9bb6c25..d3f71af5c 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -265,9 +265,9 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i if (!surfaceSkin) return; } - FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin); + FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin, false); - tex->Bind(0, translation); + tex->Bind(CLAMP_NONE, translation, -1, false); gl_RenderState.Apply(); GLRenderer->mModelVBO->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, inter); diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index ffd2a65de..0ce907aa5 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -416,8 +416,8 @@ int FVoxelModel::FindFrame(const char * name) void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation) { - FMaterial * tex = FMaterial::ValidateTexture(skin); - tex->Bind(0, translation); + FMaterial * tex = FMaterial::ValidateTexture(skin, false); + tex->Bind(CLAMP_NOFILTER, translation, -1, false); gl_RenderState.Apply(); GLRenderer->mModelVBO->SetupFrame(vindex, vindex, 0.f); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index effbec942..ec0680bbc 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -64,6 +64,7 @@ #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" @@ -115,6 +116,7 @@ void FGLRenderer::Initialize() mFBID = 0; SetupLevel(); mShaderManager = new FShaderManager; + mSamplerManager = new FSamplerManager; //mThreadManager = new FGLThreadManager; } @@ -124,6 +126,7 @@ FGLRenderer::~FGLRenderer() 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; @@ -243,7 +246,7 @@ 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(0, w, h); @@ -310,7 +313,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) 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) { @@ -331,7 +334,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) } } gl_SetRenderStyle(parms.style, !parms.masked, false); - gltex->BindPatch(translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha)); + gltex->Bind(CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha)); u1 = gltex->GetUL(); v1 = gltex->GetVT(); @@ -341,10 +344,11 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) } else { - gltex->Bind(0, 0); - u2=1.f; - v2=-1.f; - u1 = v1 = 0.f; + gltex->Bind(CLAMP_XY_NOMIP, 0, -1, false); + u1 = 0.f; + v1 = 1.f; + u2 = 1.f; + v2 = 0.f; gl_RenderState.SetTextureMode(TM_OPAQUE); } @@ -490,11 +494,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(0, 0); + gltexture->Bind(CLAMP_NONE, 0, -1, false); // scaling is not used here. if (!local_origin) @@ -575,7 +579,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) { @@ -587,7 +591,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint gl_SetColor(lightlevel, 0, cm, 1.f); - gltexture->Bind(); + gltexture->Bind(CLAMP_NONE, 0, -1, false); int i; float rot = float(rotation * M_PI / float(1u << 31)); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 15c8a2e16..aee400def 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -18,6 +18,7 @@ class FShaderManager; class GLPortal; class FGLThreadManager; class FLightBuffer; +class FSamplerManager; enum SectorRenderFlags { @@ -56,6 +57,7 @@ public: float mCurrentFoV; AActor *mViewActor; FShaderManager *mShaderManager; + FSamplerManager *mSamplerManager; FGLThreadManager *mThreadManager; int gl_spriteindex; unsigned int mFBID; diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 98101c987..db6d1ad7c 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -103,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 @@ -192,10 +182,10 @@ void GLWall::DrawDecal(DBaseDecal *decal) 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; @@ -329,7 +319,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_SetRenderStyle(decal->RenderStyle, false, false); - tex->BindPatch(decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha)); + tex->Bind(CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha)); // If srcalpha is one it looks better with a higher alpha threshold diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 8461a90eb..2cda1e396 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -1055,7 +1055,7 @@ 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) @@ -1077,7 +1077,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo int rel = getExtraLight(); gl_SetColor(lightlevel, rel, Colormap, 1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gltexture->Bind(); + gltexture->Bind(CLAMP_NONE, 0, -1, false); float fviewx = FIXED2FLOAT(viewx); float fviewy = FIXED2FLOAT(viewy); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index f997e69da..0df465caf 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -77,11 +77,11 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte 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,8 +91,8 @@ void 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(); gl_RenderState.mTextureMatrix.loadIdentity(); gl_RenderState.mTextureMatrix.scale(xscale1 ,yscale1,1.0f); @@ -341,7 +341,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG case GLPASS_ALL: gl_SetColor(lightlevel, rel, Colormap,1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gltexture->Bind(); + gltexture->Bind(CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false); gl_RenderState.EnableTextureMatrix(false); @@ -367,7 +367,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG } else { - gltexture->Bind(); + gltexture->Bind(CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, true, true); gl_RenderState.EnableTextureMatrix(false); @@ -424,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()) { diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 7c7efc91d..5e82dbd7b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -985,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(); @@ -1011,7 +1011,7 @@ void GLHorizonPortal::DrawContents() } - gltexture->Bind(); + gltexture->Bind(CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(sp, gltexture); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index afd9259f2..fb4de22ea 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -959,7 +959,7 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache) { if (cache) { - tex->PrecacheGL(); + tex->PrecacheGL(cache); } else { @@ -1067,10 +1067,10 @@ 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); @@ -1102,15 +1102,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(0, 0); + gltex->Bind(0, 0, -1, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height); } else @@ -1118,8 +1118,6 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in GLRenderer->EndOffscreen(); } - gltex->Bind(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 583c6fc62..b12ada3fc 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -268,9 +268,9 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in if (tex) { - tex->Bind(0, 0); - texw = tex->TextureWidth(GLUSE_TEXTURE); - texh = tex->TextureHeight(GLUSE_TEXTURE); + tex->Bind(CLAMP_NONE, 0, -1, false); + texw = tex->TextureWidth(); + texh = tex->TextureHeight(); gl_RenderState.EnableModelMatrix(true); gl_RenderState.mModelMatrix.loadIdentity(); @@ -332,8 +332,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool faces=4; // north - tex = FMaterial::ValidateTexture(sb->faces[0]); - tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[0], false); + tex->Bind(CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -348,8 +348,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // east - tex = FMaterial::ValidateTexture(sb->faces[1]); - tex->Bind(GLT_CLAMPX | GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[1], false); + tex->Bind(CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -364,8 +364,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // south - tex = FMaterial::ValidateTexture(sb->faces[2]); - tex->Bind(GLT_CLAMPX | GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[2], false); + tex->Bind(CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -380,8 +380,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // west - tex = FMaterial::ValidateTexture(sb->faces[3]); - tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[3], false); + tex->Bind(CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -424,8 +424,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool } // top - tex = FMaterial::ValidateTexture(sb->faces[faces]); - tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[faces], false); + tex->Bind(CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -440,8 +440,8 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); // bottom - tex = FMaterial::ValidateTexture(sb->faces[faces+1]); - tex->Bind(GLT_CLAMPX|GLT_CLAMPY, 0); + tex = FMaterial::ValidateTexture(sb->faces[faces+1], false); + tex->Bind(CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 4aa0f90bc..502264e20 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -214,7 +214,7 @@ void GLSprite::Draw(int pass) gl_RenderState.SetFog(0, 0); } - if (gltexture) gltexture->BindPatch(translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); + if (gltexture) gltexture->Bind(CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); else if (!modelframe) gl_RenderState.EnableTexture(false); if (!modelframe) @@ -455,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) @@ -598,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 @@ -624,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) @@ -734,7 +736,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) translation=thing->Translation; - OverrideShader = 0; + OverrideShader = -1; trans = FIXED2FLOAT(thing->alpha); hw_styleflags = STYLEHW_Normal; @@ -923,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(); @@ -931,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_walls.cpp b/src/gl/scene/gl_walls.cpp index bcf0080d0..1a9e30a72 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -783,12 +783,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; } @@ -1094,19 +1094,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)); } @@ -1558,7 +1558,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) SkyNormal(frontsector, v1, v2); // normal texture - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true); + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true); if (gltexture) { DoTexture(RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, @@ -1613,7 +1613,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (bch1a < fch1 || bch2a < fch2) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true); + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true); if (gltexture) { DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0, @@ -1625,7 +1625,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) 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, @@ -1650,7 +1650,7 @@ 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; @@ -1675,7 +1675,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (bfh1>ffh1 || bfh2>ffh2) { - gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true); + gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true); if (gltexture) { DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0, @@ -1693,7 +1693,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) // 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, @@ -1756,7 +1756,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * 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) { diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 51bf5de18..5bb81fbe5 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -273,8 +273,8 @@ void GLWall::RenderMirrorSurface() gl_RenderState.AlphaFunc(GL_GREATER,0); glDepthFunc(GL_LEQUAL); - FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture); - pat->BindPatch(0); + FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture, false); + pat->Bind(CLAMP_NONE, 0, -1, false); flags &= ~GLWF_GLOW; RenderWall(RWF_BLANK); @@ -326,7 +326,7 @@ void GLWall::RenderTranslucentWall() if (gltexture) { gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(flags, 0); + gltexture->Bind(flags & 3, 0, -1, false); extra = getExtraLight(); } else @@ -390,7 +390,7 @@ void GLWall::Draw(int pass) else gl_SetFog(255, 0, NULL, false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(flags, 0); + gltexture->Bind(flags & 3, false, -1, false); RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); break; diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index d0f2ab370..67e2f9576 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -93,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(0, OverrideShader, alphatexture); + tex->Bind(CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture); int vw = viewwidth; int vh = viewheight; @@ -104,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) @@ -132,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) { @@ -149,7 +149,7 @@ 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.AlphaFunc(GL_GEQUAL, 0.f); } @@ -207,7 +207,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL); if (lump.isValid()) { - FMaterial * tex=FMaterial::ValidateTexture(lump, false); + FMaterial * tex=FMaterial::ValidateTexture(lump, false, false); if (tex) disablefullbright = tex->tex->gl_info.bBrightmapDisablesFullbright; } @@ -306,7 +306,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // 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) { diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 12e7c9e02..57ad3ba89 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -56,6 +56,7 @@ #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" @@ -146,13 +147,12 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) return false; } - wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true); - wipestartscreen->CreateTexture(NULL, Width, Height, false, 0); + wipestartscreen = new FHardwareTexture(Width, Height, true); + wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); + GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); glFinish(); - wipestartscreen->Bind(0); + wipestartscreen->Bind(0, false, 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); @@ -169,10 +169,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); - glFlush(); - wipeendscreen->Bind(0); + wipeendscreen = new FHardwareTexture(Width, Height, true); + wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); + GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); + glFinish(); + wipeendscreen->Bind(0, false, 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); @@ -283,7 +284,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0); + fb->wipestartscreen->Bind(0, 0, false, false); FFlatVertex *ptr; unsigned int offset, count; @@ -298,7 +299,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); - fb->wipeendscreen->Bind(0); + fb->wipeendscreen->Bind(0, 0, false, false); gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f)); gl_RenderState.Apply(); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); @@ -345,7 +346,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipeendscreen->Bind(0); + fb->wipeendscreen->Bind(0, 0, false, false); FFlatVertex *ptr; ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(0, 0, 0, 0, vb); @@ -361,7 +362,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) int i, dy; bool done = false; - fb->wipestartscreen->Bind(0); + fb->wipestartscreen->Bind(0, 0, false, false); // Copy the old screen in vertical strips on top of the new one. while (ticks--) { @@ -468,7 +469,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]; @@ -493,7 +494,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0); + fb->wipestartscreen->Bind(0, 0, false, false); FFlatVertex *ptr; unsigned int offset, count; ptr = GLRenderer->mVBO->GetBuffer(); @@ -513,9 +514,9 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.Apply(); // Burn the new screen on top of it. - fb->wipeendscreen->Bind(1); + fb->wipeendscreen->Bind(1, 0, false, false); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 0, false, 0, false); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); gl_RenderState.SetEffect(EFF_NONE); diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 697bcda4d..d076f6a3e 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 @@ -173,6 +173,7 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un } + //=========================================================================== // // Loads the texture image into the hardware @@ -182,24 +183,27 @@ 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, bool alphatexture) { int rh,rw; int texformat=TexFormat[gl_texture_format]; bool deletebuffer=false; - bool use_mipmapping = TexFilter[gl_texture_filter].mipmapping; if (alphatexture) { texformat = GL_R8; + translation = TRANS_Alpha; } else if (forcenocompression) { texformat = GL_RGBA8; } - if (glTexID==0) glGenTextures(1,&glTexID); - glBindTexture(GL_TEXTURE_2D, glTexID); - lastbound[texunit]=glTexID; + 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) { @@ -209,7 +213,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; + glTex->mipmapped = false; buffer=(unsigned char *)calloc(4,rw * (rh+1)); deletebuffer=true; //texheight=-h; @@ -235,42 +239,19 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i if (deletebuffer) free(buffer); - if (mipmap && use_mipmapping && !forcenofiltering) glGenerateMipmap(GL_TEXTURE_2D); + if (mipmap && TexFilter[gl_texture_filter].mipmapping) + { + glGenerateMipmap(GL_TEXTURE_2D); + glTex->mipmapped = true; + } + if (alphatexture) { static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - - // 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); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapparam); - clampmode = wrapparam==GL_CLAMP_TO_EDGE? GLT_CLAMPX|GLT_CLAMPY : 0; - - if (forcenofiltering) - { - 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); - } + if (texunit != 0) glActiveTexture(GL_TEXTURE0); + return glTex->glTexID; } @@ -279,17 +260,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; - glDefTexID = 0; - clampmode=0; + glDefTex.glTexID = 0; + glDefTex.translation = 0; + glDefTex.mipmapped = false; glDepthID = 0; - forcenofiltering = nofilter; } @@ -298,18 +278,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; } } @@ -324,14 +306,13 @@ void FHardwareTexture::Clean(bool all) if (all) { - DeleteTexture(glDefTexID); - glDefTexID = 0; + glDefTex.Delete(); } - 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; } @@ -445,25 +433,7 @@ int FHardwareTexture::GetDepthBuffer() void FHardwareTexture::BindToFrameBuffer() { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTexID, 0); + 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 translation, bool alphatexture) -{ - if (alphatexture) translation = TRANS_Alpha; - unsigned int * pTexID=GetTexID(translation); - - if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); - LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP_TO_EDGE, alphatexture, 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 4e13bc841..eabc7a6ef 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -33,23 +33,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); @@ -57,25 +60,20 @@ public: private: short texwidth, texheight; - //float scalexfac, scaleyfac; - bool mipmap; - BYTE clampmode; - bool forcenofiltering; bool forcenocompression; - unsigned glDefTexID; - 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 translation); + void LoadImage(unsigned char * buffer,int w, int h, TranslatedTexture *glTex, bool mipmap, bool alphatexture, int texunit); + 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); @@ -83,9 +81,8 @@ public: void BindToFrameBuffer(); - unsigned int Bind(int texunit, int translation=0, bool alphatexture = false); - unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int translation=0, bool alphatexture = false); - void Resize(int _width, int _height) ; + unsigned int Bind(int texunit, int translation, bool alphatexture, bool needmipmap); + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture); void Clean(bool all); }; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 9ec948b37..443560c7f 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,17 +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; bHasColorkey = false; bIsTransparent = -1; bExpand = expandpatches; - tex->gl_info.SystemTexture = this; + tex->gl_info.SystemTexture[expandpatches] = this; } //=========================================================================== @@ -162,25 +163,13 @@ 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; } } } @@ -192,7 +181,7 @@ void FGLTexture::Clean(bool all) // //=========================================================================== -unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, bool alphatexture) +unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture) { unsigned char * buffer; int W, H; @@ -209,8 +198,8 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b } } - 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]; @@ -229,7 +218,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b 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; @@ -237,7 +226,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b } 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; } @@ -246,7 +235,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b // 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; } @@ -262,64 +251,32 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, b // //=========================================================================== -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 clampmode, int translation, FTexture *hirescheck) +const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, bool alphatexture, 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, 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) { @@ -327,11 +284,11 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified()) { Clean(true); - hwtex = CreateTexture(clampmode); + hwtex = CreateHwTexture(); } // Bind it to the system. - if (!hwtex->Bind(texunit, translation)) + if (!hwtex->Bind(texunit, translation, alphatexture, needmipmap)) { int w=0, h=0; @@ -341,73 +298,25 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(translation, w, h, false, hirescheck); + buffer = CreateTexBuffer(translation, w, h, hirescheck, alphatexture); tex->ProcessData(buffer, w, h, false); } - if (!hwtex->CreateTexture(buffer, w, h, true, texunit, translation)) + if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, alphatexture)) { // 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 translation, bool alphatexture) -{ - bool usebright = false; - int transparm = translation; - - if (translation <= 0) translation = -translation; - else translation = GLTranslationPalette::GetInternalTranslation(translation); - - if (CreatePatch()) - { - // Texture has become invalid - this is only for special textures, not the regular warping, which is handled above - if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified()) - { - Clean(true); - CreatePatch(); - } - - - // Bind it to the system. - if (!glpatch->Bind(texunit, translation, alphatexture)) - { - int w, h; - - // Create this texture - unsigned char * buffer = CreateTexBuffer(translation, w, h, bExpand, NULL, alphatexture); - tex->ProcessData(buffer, w, h, true); - if (!glpatch->CreateTexture(buffer, w, h, false, texunit, translation, alphatexture)) - { - // 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; -} - - //=========================================================================== // // @@ -475,7 +384,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); @@ -493,15 +402,8 @@ 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; // TODO: apply custom shader object here @@ -539,83 +441,62 @@ 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; - - tx->gl_info.mExpanded = expanded; FTexture *basetex = tx->GetRedirect(false); - 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 + mBaseLayer = ValidateSysTexture(basetex, expanded); + + // 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; + tex = tx; + mExpanded = expanded; } //=========================================================================== @@ -657,7 +538,7 @@ bool FMaterial::TrimBorders(int *rect) { return false; } - if (w != Width[GLUSE_TEXTURE] || h != Height[GLUSE_TEXTURE]) + if (w != mWidth || h != mHeight) { // external Hires replacements cannot be trimmed. delete [] buffer; @@ -730,20 +611,19 @@ outl: // //=========================================================================== -void FMaterial::Bind(int clampmode, int translation, int overrideshader) +void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool alphatexture) { 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; gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); - if (tex->bHasCanvas || tex->bWarped) clampmode = 0; - else if (clampmode != -1) clampmode &= 3; - else clampmode = 4; + if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; + else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL); + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, alphatexture, allowhires? tex:NULL); if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) { 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, clampmode, 0, NULL); + layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, false, NULL); maxbound = i+1; } } @@ -772,36 +652,6 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader) } -//=========================================================================== -// -// Binds a texture to the renderer -// -//=========================================================================== - -void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture) -{ - int usebright = false; - int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; - int maxbound = 0; - - gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); - - const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, alphatexture); - // The only multitexture effect usable on sprites is the brightmap. - if (glpatch != NULL && shaderindex == 3) - { - mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, 0, false); - 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; - } -} - - //=========================================================================== // // @@ -809,31 +659,12 @@ void FMaterial::BindPatch(int translation, int overrideshader, bool alphatexture //=========================================================================== void FMaterial::Precache() { - if (tex->UseType==FTexture::TEX_Sprite) - { - BindPatch(0); - } - else - { - int cached = 0; - for(int i=0;i<4;i++) - { - if (mBaseLayer->gltexture[i] != 0) - { - Bind (i, 0); - cached++; - } - if (cached == 0) Bind(-1, 0); - } - } + Bind(0, 0, 0, false); } //=========================================================================== // -// 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 // //=========================================================================== @@ -841,14 +672,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; @@ -856,14 +687,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; @@ -874,7 +705,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; } //=========================================================================== @@ -905,30 +736,15 @@ 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, 0, 0, NULL); + mBaseLayer->Bind(0, 0, 0, false, NULL); FHardwareTexture::Unbind(0); } - 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 @@ -936,24 +752,24 @@ 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) { //@sync-tex - 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); } @@ -973,47 +789,11 @@ 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); } diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 259f881b4..714ab5a03 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,13 +51,6 @@ struct FTexCoordInfo //=========================================================================== class FMaterial; -enum ETexUse -{ - GLUSE_PATCH, - GLUSE_TEXTURE, - GLUSE_SPRITE, -}; - class FGLTexture { @@ -58,26 +62,23 @@ public: int HiresLump; private: - FHardwareTexture *gltexture[5]; - FHardwareTexture *glpatch; + FHardwareTexture *mHwTexture; bool bHasColorkey; // only for hires bool bExpand; unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture); - FHardwareTexture *CreateTexture(int clampmode); - //bool CreateTexture(); - bool CreatePatch(); + FHardwareTexture *CreateHwTexture(); - const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck); + const FHardwareTexture *Bind(int texunit, int clamp, int translation, bool alphatexture, FTexture *hirescheck); const FHardwareTexture *BindPatch(int texunit, int translation, bool alphatexture); public: FGLTexture(FTexture * tx, bool expandpatches); ~FGLTexture(); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, bool alphatexture = false); + unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture); void Clean(bool all); int Dump(int i); @@ -105,15 +106,16 @@ 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; FGLTexture * ValidateSysTexture(FTexture * tex, bool expand); bool TrimBorders(int *rect); @@ -129,12 +131,17 @@ public: return !!mBaseLayer->tex->bMasked; } - void Bind(int clamp = 0, int translation = 0, int overrideshader = 0); - void BindPatch(int translation = 0, int overrideshader = 0, bool alphatexture = false); - - unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand = false, bool allowhires=true) const + int GetLayers() const { - return mBaseLayer->CreateTexBuffer(translation, w, h, expand, allowhires? tex:NULL, 0); + return mTextureLayers.Size() + 1; + } + + //void Bind(int clamp = 0, int translation = 0, int overrideshader = 0, bool alphatexture = false); + void Bind(int clamp, int translation, int overrideshader, bool alphatexture); + + unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true) const + { + return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex:NULL, 0); } void Clean(bool f) @@ -145,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]; } @@ -240,8 +251,8 @@ 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); }; 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 a864c7e3e..5725f831c 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) @@ -235,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; - } //=========================================================================== @@ -319,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; } } @@ -336,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; + } } //========================================================================== @@ -640,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 @@ -829,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, 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/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; } } From bf6079af4693bb1e486da4620c4629d9bee730ae Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 23 Aug 2014 00:47:05 +0200 Subject: [PATCH 119/138] - fixed incorrect check for overrideshader. --- src/gl/textures/gl_material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 443560c7f..d29f75ddb 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -614,7 +614,7 @@ outl: void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool alphatexture) { int usebright = false; - int shaderindex = overrideshader > 0? overrideshader : mShaderIndex; + int shaderindex = overrideshader >= 0? overrideshader : mShaderIndex; int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT && clampmode <= CLAMP_XY && !mExpanded; @@ -624,7 +624,7 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool al else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, alphatexture, allowhires? tex:NULL); - if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) + if (gltexture != NULL && shaderindex > 0 && overrideshader == -1) { for(unsigned i=0;i Date: Sat, 23 Aug 2014 18:54:24 +0200 Subject: [PATCH 120/138] - some code cleanup. --- src/gl/renderer/gl_renderer.cpp | 5 - src/gl/renderer/gl_renderer.h | 2 - src/gl/scene/gl_bsp.cpp | 59 ++------ src/gl/system/gl_cvars.h | 1 - src/gl/system/gl_threads.h | 247 -------------------------------- 5 files changed, 9 insertions(+), 305 deletions(-) delete mode 100644 src/gl/system/gl_threads.h diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index ec0680bbc..ea48d6486 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -52,7 +52,6 @@ #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" @@ -76,8 +75,6 @@ // //=========================================================================== -EXTERN_CVAR(Bool, gl_render_segs) - //----------------------------------------------------------------------------- // // Initialize @@ -117,14 +114,12 @@ void FGLRenderer::Initialize() SetupLevel(); mShaderManager = new FShaderManager; mSamplerManager = new FSamplerManager; - //mThreadManager = new FGLThreadManager; } FGLRenderer::~FGLRenderer() { gl_DeleteAllAttachedLights(); FMaterial::FlushAll(); - //if (mThreadManager != NULL) delete mThreadManager; if (mShaderManager != NULL) delete mShaderManager; if (mSamplerManager != NULL) delete mSamplerManager; if (mVBO != NULL) delete mVBO; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index aee400def..90f2c4a46 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -16,7 +16,6 @@ struct FDrawInfo; struct pspdef_t; class FShaderManager; class GLPortal; -class FGLThreadManager; class FLightBuffer; class FSamplerManager; @@ -58,7 +57,6 @@ public: AActor *mViewActor; FShaderManager *mShaderManager; FSamplerManager *mSamplerManager; - FGLThreadManager *mThreadManager; int gl_spriteindex; unsigned int mFBID; 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/system/gl_cvars.h b/src/gl/system/gl_cvars.h index 567d9f85f..cedeec06a 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -36,7 +36,6 @@ 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(Float, gl_mask_threshold) 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 From bf03d022280a82f27bf947b5854a8f4edbf2d741 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Aug 2014 01:09:44 +0200 Subject: [PATCH 121/138] - print OpenGL profile type in startup log. --- src/gl/system/gl_interface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 7a745110b..95ab2e289 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -149,16 +149,18 @@ 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:"); for (unsigned i = 0; i < m_Extensions.Size(); i++) { Printf(" %s", m_Extensions[i].GetChars()); } - int v; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &v); Printf("\nMax. texture size: %d\n", v); From a903cbe12e9122ba0b325321cc2ad8e241da73ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Aug 2014 13:10:45 +0200 Subject: [PATCH 122/138] - sorting draw items by light level no longer makes sense so remove all corresponding code from dicmp. --- src/gl/scene/gl_drawinfo.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 2cda1e396..050860a48 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -794,7 +794,6 @@ static int __cdecl dicmp (const void *a, const void *b) { const GLDrawItem * di[2]; FMaterial * tx[2]; - int lights[2]; int clamp[2]; //colormap_t cm[2]; di[0]=(const GLDrawItem *)a; @@ -808,7 +807,6 @@ static int __cdecl dicmp (const void *a, const void *b) { GLFlat * f=&sortinfo->flats[di[i]->index]; tx[i]=f->gltexture; - lights[i]=f->lightlevel; clamp[i] = 0; } break; @@ -817,7 +815,6 @@ static int __cdecl dicmp (const void *a, const void *b) { GLWall * w=&sortinfo->walls[di[i]->index]; tx[i]=w->gltexture; - lights[i]=w->lightlevel; clamp[i] = w->flags & 3; } break; @@ -826,16 +823,14 @@ static int __cdecl dicmp (const void *a, const void *b) { GLSprite * s=&sortinfo->sprites[di[i]->index]; tx[i]=s->gltexture; - lights[i]=s->lightlevel; - clamp[i] = 4; + clamp[i] = 3; } 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]; + return clamp[0]-clamp[1]; // clamping forces different textures. } From 49ec7beb8f1211cf76191e117f49e63fb70e9b66 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Aug 2014 13:04:41 +0200 Subject: [PATCH 123/138] - separate draw lists for walls and flats. This makes the sorting much more efficient because draw types no longer need to be checked in the compare function. This is a lot more important than having perfect texture order. --- src/gl/scene/gl_drawinfo.cpp | 101 ++++++++++++++++++++--------------- src/gl/scene/gl_drawinfo.h | 13 +++-- src/gl/scene/gl_flats.cpp | 2 +- src/gl/scene/gl_scene.cpp | 26 +++++---- src/gl/scene/gl_walls.cpp | 4 +- 5 files changed, 87 insertions(+), 59 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 050860a48..c468b2a7a 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -644,7 +644,6 @@ SortNode * GLDrawList::DoSort(SortNode * head) case GLDIT_SPRITE: SortSpriteIntoPlane(head,node); break; - case GLDIT_POLY: break; } node=next; } @@ -670,7 +669,7 @@ SortNode * GLDrawList::DoSort(SortNode * head) case GLDIT_SPRITE: SortSpriteIntoWall(head,node); break; - case GLDIT_POLY: break; + case GLDIT_FLAT: break; } node=next; @@ -722,7 +721,6 @@ void GLDrawList::DoDraw(int pass, int i, bool trans) RenderSprite.Unclock(); } break; - case GLDIT_POLY: break; } } @@ -783,6 +781,36 @@ void GLDrawList::Draw(int pass) } } +//========================================================================== +// +// +// +//========================================================================== +void GLDrawList::DrawWalls(int pass) +{ + RenderWall.Clock(); + 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; - 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; - 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; - clamp[i] = 3; - } - break; - case GLDIT_POLY: break; - } - } - if (tx[0]!=tx[1]) return tx[0]-tx[1]; - return clamp[0]-clamp[1]; // clamping forces different textures. +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) { 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()!=0 && gl_sort_textures) + { + sortinfo=this; + qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp); } } diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 9f8b2c383..b0a139108 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -13,9 +13,11 @@ enum GLDrawItemType enum DrawListType { - GLDL_PLAIN, - GLDL_MASKED, - GLDL_MASKEDOFS, + GLDL_PLAINWALLS, + GLDL_PLAINFLATS, + GLDL_MASKEDWALLS, + GLDL_MASKEDFLATS, + GLDL_MASKEDWALLSOFS, GLDL_MODELS, GLDL_TRANSLUCENT, @@ -106,7 +108,8 @@ public: void AddFlat(GLFlat * flat); void AddSprite(GLSprite * sprite); void Reset(); - void Sort(); + void SortWalls(); + void SortFlats(); void MakeSortList(); @@ -125,6 +128,8 @@ public: void DoDrawSorted(SortNode * node); void DrawSorted(); void Draw(int pass); + void DrawWalls(int pass); + void DrawFlats(int pass); GLDrawList * next; } ; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 0df465caf..0bd4d9eb5 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -402,7 +402,7 @@ inline void GLFlat::PutFlat(bool fog) else { bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack); - list = masked ? GLDL_MASKED : GLDL_PLAIN; + list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS; } gl_drawinfo->drawlists[list].AddFlat (this); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index fb4de22ea..89d505168 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -340,18 +340,22 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableFog(true); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); - gl_drawinfo->drawlists[GLDL_PLAIN].Sort(); - gl_drawinfo->drawlists[GLDL_MASKED].Sort(); - gl_drawinfo->drawlists[GLDL_MASKEDOFS].Sort(); + 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_PLAIN].Draw(GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_MASKED].Draw(GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].Draw(GLPASS_LIGHTSONLY); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Draw(GLPASS_LIGHTSONLY); gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY); gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY); GLRenderer->mLights->Finish(); @@ -375,7 +379,8 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(pass); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].Draw(pass); // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show @@ -385,14 +390,15 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.SetTextureMode(TM_MASK); } gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].Draw(pass); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].Draw(pass); // 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_MASKEDOFS].Size() > 0) + if (gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); - gl_drawinfo->drawlists[GLDL_MASKEDOFS].Draw(pass); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Draw(pass); glDisable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0, 0); } diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 1a9e30a72..bb160a790 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -151,11 +151,11 @@ void GLWall::PutWall(bool translucent) if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S)) { - list = GLDL_MASKEDOFS; + list = GLDL_MASKEDWALLSOFS; } else { - list = masked ? GLDL_MASKED : GLDL_PLAIN; + list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS; } gl_drawinfo->drawlists[list].AddWall(this); From 6a3cd6378a833e15dc0af76d14d1602a34049824 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Aug 2014 14:33:06 +0200 Subject: [PATCH 124/138] - found out that reading the CPU's real time clock costs a not insignificant amount of time so this is now only done when either the benchmark command is running or the rendertimes are shown. --- src/gl/scene/gl_scene.cpp | 29 ++++++++++++++--------------- src/gl/utility/gl_clock.cpp | 11 ++++++++++- src/gl/utility/gl_clock.h | 6 ++++-- src/stats.h | 4 ++++ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 89d505168..f9b713335 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -351,11 +351,11 @@ void FGLRenderer::RenderScene(int recursion) if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE)) { GLRenderer->mLights->Begin(); - gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_PLAINFLATS].Draw(GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_MASKEDWALLS].Draw(GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_MASKEDFLATS].Draw(GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Draw(GLPASS_LIGHTSONLY); + 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(); @@ -379,8 +379,8 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(pass); - gl_drawinfo->drawlists[GLDL_PLAINFLATS].Draw(pass); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(pass); + gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(pass); // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show @@ -390,15 +390,15 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.SetTextureMode(TM_MASK); } gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->drawlists[GLDL_MASKEDWALLS].Draw(pass); - gl_drawinfo->drawlists[GLDL_MASKEDFLATS].Draw(pass); + gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(pass); + gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(pass); // 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) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); - gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Draw(pass); + gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(pass); glDisable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0, 0); } @@ -413,10 +413,8 @@ void FGLRenderer::RenderScene(int recursion) 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].Draw(GLPASS_DECALS); gl_RenderState.SetTextureMode(TM_MODULATE); @@ -439,8 +437,8 @@ void FGLRenderer::RenderScene(int recursion) glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); - RenderAll.Unclock(); + } //----------------------------------------------------------------------------- @@ -821,6 +819,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 diff --git a/src/gl/utility/gl_clock.cpp b/src/gl/utility/gl_clock.cpp index d8d3c28be..48c21dde2 100644 --- a/src/gl/utility/gl_clock.cpp +++ b/src/gl/utility/gl_clock.cpp @@ -221,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 604a40a02..f12cf1ef9 100644 --- a/src/gl/utility/gl_clock.h +++ b/src/gl/utility/gl_clock.h @@ -9,6 +9,7 @@ extern double gl_SecondsPerCycle; extern double gl_MillisecPerCycle; +extern bool gl_benching; __forceinline long long GetClockCycle () @@ -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; } @@ -118,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/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); From 12160bd29c7efd09f92aecd4a025fc6f77ed6b85 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 Aug 2014 15:34:14 +0200 Subject: [PATCH 125/138] - remove some obsolete code from decal rendering. - avoid rebinding the same texture multiple times, as there's considerable overhead in the texture manager. - check gl_sort_textures only once per scene, not per draw list. --- src/gl/scene/gl_decal.cpp | 12 ++++++++---- src/gl/scene/gl_drawinfo.cpp | 19 +++++++++++++++---- src/gl/scene/gl_drawinfo.h | 2 +- src/gl/scene/gl_scene.cpp | 16 ++++++++++------ src/gl/scene/gl_walls_draw.cpp | 12 ------------ src/gl/textures/gl_material.cpp | 18 +++++++++++++++--- wadsrc/static/menudef.z | 1 + 7 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index db6d1ad7c..4fc7603cf 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -349,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 c468b2a7a..3f469d999 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -59,8 +59,6 @@ FDrawInfo * gl_drawinfo; -CVAR(Bool, gl_sort_textures, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - //========================================================================== // // @@ -811,6 +809,19 @@ void GLDrawList::DrawFlats(int pass) RenderFlat.Unclock(); } +//========================================================================== +// +// +// +//========================================================================== +void GLDrawList::DrawDecals() +{ + for(unsigned i=0;i 1) { sortinfo=this; qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp); @@ -853,7 +864,7 @@ void GLDrawList::SortWalls() void GLDrawList::SortFlats() { - if (drawitems.Size()!=0 && gl_sort_textures) + if (drawitems.Size() > 1) { sortinfo=this; qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp); diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index b0a139108..67ed2099c 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -32,7 +32,6 @@ enum Drawpasses 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 }; @@ -130,6 +129,7 @@ public: void Draw(int pass); void DrawWalls(int pass); void DrawFlats(int pass); + void DrawDecals(); GLDrawList * next; } ; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index f9b713335..f1fdfb812 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -85,6 +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_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Int, screenblocks) EXTERN_CVAR (Bool, cl_capfps) @@ -340,11 +341,14 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableFog(true); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); - 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 (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. @@ -414,7 +418,7 @@ void FGLRenderer::RenderScene(int recursion) glDepthMask(false); // this is the only geometry type on which decals can possibly appear - gl_drawinfo->drawlists[GLDL_PLAINWALLS].Draw(GLPASS_DECALS); + gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals(); gl_RenderState.SetTextureMode(TM_MODULATE); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 5bb81fbe5..bf3e9dbd1 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -395,18 +395,6 @@ void GLWall::Draw(int pass) gl_RenderState.EnableGlow(false); 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: switch (type) { diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index d29f75ddb..503c0b793 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -611,15 +611,27 @@ outl: // //=========================================================================== +static FMaterial *last; +static int lastclamp; +static int lasttrans; +static bool lastalpha; + void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool alphatexture) { - int usebright = false; int shaderindex = overrideshader >= 0? overrideshader : mShaderIndex; + gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); + + // avoid rebinding the same texture multiple times. + if (this == last && lastclamp == clampmode && translation == lasttrans && lastalpha == alphatexture) return; + last = this; + lastclamp = clampmode; + lastalpha = alphatexture; + lasttrans = translation; + + int usebright = false; int maxbound = 0; bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT && clampmode <= CLAMP_XY && !mExpanded; - gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); - if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; diff --git a/wadsrc/static/menudef.z b/wadsrc/static/menudef.z index cdfce4145..d3394fc96 100644 --- a/wadsrc/static/menudef.z +++ b/wadsrc/static/menudef.z @@ -139,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" From a280c20b4eb7b378ae8e404d5d80112b47cffc3d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 31 Aug 2014 19:00:17 +0200 Subject: [PATCH 126/138] - fixed: If we want to cache texture binding state we have to reset it in all places where a texture becomes unbound. --- src/gl/system/gl_wipe.cpp | 1 + src/gl/textures/gl_hwtexture.cpp | 1 + src/gl/textures/gl_material.cpp | 5 +++++ src/gl/textures/gl_material.h | 1 + 4 files changed, 8 insertions(+) diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 57ad3ba89..53af826bd 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -240,6 +240,7 @@ void OpenGLFrameBuffer::WipeCleanup() delete wipeendscreen; wipeendscreen = NULL; } + FMaterial::ClearLastTexture(); } //========================================================================== diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index d076f6a3e..f491169b4 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -403,6 +403,7 @@ void FHardwareTexture::UnbindAll() { Unbind(texunit); } + FMaterial::ClearLastTexture(); } //=========================================================================== diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 503c0b793..efbbec332 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -753,6 +753,7 @@ void FMaterial::BindToFrameBuffer() // must create the hardware texture first mBaseLayer->Bind(0, 0, 0, false, NULL); FHardwareTexture::Unbind(0); + ClearLastTexture(); } mBaseLayer->mHwTexture->BindToFrameBuffer(); } @@ -809,3 +810,7 @@ void FMaterial::FlushAll() } } +void FMaterial::ClearLastTexture() +{ + last = NULL; +} diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 714ab5a03..dfdbeb743 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -253,6 +253,7 @@ public: static void FlushAll(); static FMaterial *ValidateTexture(FTexture * tex, bool expand); static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans); + static void ClearLastTexture(); }; From fa3a62e954f6f106e598f0721a5e264a0c77221f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 31 Aug 2014 23:01:53 +0200 Subject: [PATCH 127/138] - fix a render glitch with Back to Saturn X MAP06: Do not flood missing upper and lower textures with the backsector's flat if that backsector is malformed (i.e. has no area.) --- src/gl/data/gl_setup.cpp | 3 ++- src/gl/scene/gl_walls.cpp | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index fc63cb95b..5e6e0767b 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -233,6 +233,7 @@ static void SpreadHackedFlag(subsector_t * sub) if (!(sub2->hacked&1) && sub2->render_sector == sub->render_sector) { sub2->hacked|=1; + sub->hacked &= ~4; SpreadHackedFlag (sub2); } } @@ -285,7 +286,7 @@ static void PrepareSectorData() subsectors[i].render_sector != seg[j].PartnerSeg->Subsector->render_sector) { DPrintf("Found hack: (%d,%d) (%d,%d)\n", seg[j].v1->x>>16, seg[j].v1->y>>16, seg[j].v2->x>>16, seg[j].v2->y>>16); - subsectors[i].hacked|=1; + subsectors[i].hacked|=5; SpreadHackedFlag(&subsectors[i]); } if (seg[j].PartnerSeg==NULL) subsectors[i].hacked|=2; // used for quick termination checks diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index bb160a790..e86b03d49 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -1417,7 +1417,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) sector_t * realback; #ifdef _DEBUG - if (seg->linedef-lines==636) + if (seg->linedef-lines==1276) { int a = 0; } @@ -1635,7 +1635,11 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { - gl_drawinfo->AddUpperMissingTexture(seg->sidedef, sub, bch1a); + // skip processing if the back is a malformed subsector + if (!(seg->PartnerSeg->Subsector->hacked & 4)) + { + gl_drawinfo->AddUpperMissingTexture(seg->sidedef, sub, bch1a); + } } } } @@ -1704,7 +1708,11 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) else if (backsector->GetTexture(sector_t::floor) != skyflatnum && !(seg->sidedef->Flags & WALLF_POLYOBJ)) { - gl_drawinfo->AddLowerMissingTexture(seg->sidedef, sub, bfh1); + // skip processing if the back is a malformed subsector + if (!(seg->PartnerSeg->Subsector->hacked & 4)) + { + gl_drawinfo->AddLowerMissingTexture(seg->sidedef, sub, bfh1); + } } } } From b96dd6c42142fcd1683e5349480ecd0286522c8f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 2 Sep 2014 10:31:48 +0200 Subject: [PATCH 128/138] - fixed: The missing fourth component of the texture coordinate must be filled with 1.0, not 0.0 before applying the texture matrix. Not doing so will cancel out the translation part of the matrix. --- src/gl/scene/gl_flats.cpp | 8 ++++---- wadsrc/static/shaders/glsl/main.vp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 0bd4d9eb5..ec442294a 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -70,7 +70,7 @@ // information // //========================================================================== - +static float tics; void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture) { // only manipulate the texture matrix if needed. @@ -80,8 +80,8 @@ void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte gltexture->TextureWidth() != 64 || gltexture->TextureHeight() != 64) { - float uoffs=FIXED2FLOAT(secplane->xoffs)/gltexture->TextureWidth(); - float voffs=FIXED2FLOAT(secplane->yoffs)/gltexture->TextureHeight(); + float uoffs = FIXED2FLOAT(secplane->xoffs) / gltexture->TextureWidth(); + float voffs = FIXED2FLOAT(secplane->yoffs) / gltexture->TextureHeight(); float xscale1=FIXED2FLOAT(secplane->xscale); float yscale1=FIXED2FLOAT(secplane->yscale); @@ -328,7 +328,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG int rel = getExtraLight(); #ifdef _DEBUG - if (sector->sectornum == 2) + if (sector->sectornum == 130) { int a = 0; } diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 16c3c8738..86fad75cc 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -39,7 +39,7 @@ void main() vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5); vTexCoord.xy = sst; #else - vTexCoord = TextureMatrix * vec4(aTexCoord, 0.0, 0.0); + vTexCoord = TextureMatrix * vec4(aTexCoord, 0.0, 1.0); #endif gl_Position = ProjectionMatrix * eyeCoordPos; From c6f4c0b6f0c54bb27911f198a64a681da537d8c2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 Sep 2014 10:03:34 +0200 Subject: [PATCH 129/138] - fixed: FMaterial's tex pointer could be accessed before it was set. - allow more than two texture units in shaders. --- src/gl/shaders/gl_shader.cpp | 10 ++++++++-- src/gl/textures/gl_material.cpp | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 26a1b3159..72815f2e2 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -227,8 +227,14 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * glUseProgram(hShader); - tempindex = glGetUniformLocation(hShader, "texture2"); - if (tempindex > 0) glUniform1i(tempindex, 1); + // 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; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 05fcb992b..7995b572b 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -405,6 +405,7 @@ int FMaterial::mMaxBound; FMaterial::FMaterial(FTexture * tx, bool expanded) { mShaderIndex = 0; + tex = tx; // TODO: apply custom shader object here /* if (tx->CustomShaderDefinition) @@ -495,7 +496,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mMaterials.Push(this); tx->gl_info.Material[expanded] = this; if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0; - tex = tx; mExpanded = expanded; } From d5633701b4587ca38e838f53de18a91bb8845fba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 Sep 2014 10:17:44 +0200 Subject: [PATCH 130/138] - swapped order of textures in burn shader to avoid some problems with the texture samplers. - fixed: texture sampler state for the burn texture was never set. --- src/gl/system/gl_wipe.cpp | 5 +++-- wadsrc/static/shaders/glsl/burn.fp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 53af826bd..564dd1e03 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -150,6 +150,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) wipestartscreen = new FHardwareTexture(Width, Height, true); wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); + GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE); glFinish(); wipestartscreen->Bind(0, false, false, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); @@ -515,9 +516,9 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.Apply(); // Burn the new screen on top of it. - fb->wipeendscreen->Bind(1, 0, false, false); + fb->wipeendscreen->Bind(0, 0, false, false); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 0, false, 0, false); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0, false); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); gl_RenderState.SetEffect(EFF_NONE); diff --git a/wadsrc/static/shaders/glsl/burn.fp b/wadsrc/static/shaders/glsl/burn.fp index 0cc3f7950..4ab4cac95 100644 --- a/wadsrc/static/shaders/glsl/burn.fp +++ b/wadsrc/static/shaders/glsl/burn.fp @@ -8,8 +8,8 @@ void main() { vec4 frag = vColor; - vec4 t1 = texture2D(texture2, vTexCoord.xy); - vec4 t2 = texture2D(tex, vec2(vTexCoord.x, 1.0-vTexCoord.y)); + 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); } From 4bb320a27c461af3e99ad92e75dbf9679148df62 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 Sep 2014 12:00:42 +0200 Subject: [PATCH 131/138] - route texture binding through the renderstate class for better control. Currently it's just a direct passthrough but this will change. --- src/gl/models/gl_models_md2.cpp | 2 +- src/gl/models/gl_models_md3.cpp | 2 +- src/gl/models/gl_voxels.cpp | 2 +- src/gl/renderer/gl_renderer.cpp | 8 ++++---- src/gl/renderer/gl_renderstate.h | 8 +++++--- src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_drawinfo.cpp | 2 +- src/gl/scene/gl_flats.cpp | 4 ++-- src/gl/scene/gl_portal.cpp | 2 +- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_skydome.cpp | 14 +++++++------- src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_walls_draw.cpp | 6 +++--- src/gl/scene/gl_weapon.cpp | 2 +- src/gl/textures/gl_material.cpp | 10 ++++------ src/gl/textures/gl_material.h | 4 +++- 16 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/gl/models/gl_models_md2.cpp b/src/gl/models/gl_models_md2.cpp index 76835c737..3d0fad8aa 100644 --- a/src/gl/models/gl_models_md2.cpp +++ b/src/gl/models/gl_models_md2.cpp @@ -303,7 +303,7 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double i FMaterial * tex = FMaterial::ValidateTexture(skin, false); - tex->Bind(CLAMP_NONE, translation, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false); gl_RenderState.Apply(); GLRenderer->mModelVBO->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, inter); diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index d3f71af5c..4b1788306 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -267,7 +267,7 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin, false); - tex->Bind(CLAMP_NONE, translation, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false); gl_RenderState.Apply(); GLRenderer->mModelVBO->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, inter); diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index 0ce907aa5..b1bb4de5a 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -417,7 +417,7 @@ int FVoxelModel::FindFrame(const char * name) void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation) { FMaterial * tex = FMaterial::ValidateTexture(skin, false); - tex->Bind(CLAMP_NOFILTER, translation, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_NOFILTER, translation, -1, false); gl_RenderState.Apply(); GLRenderer->mModelVBO->SetupFrame(vindex, vindex, 0.f); diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index ea48d6486..dbf0c10c8 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -329,7 +329,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) } } gl_SetRenderStyle(parms.style, !parms.masked, false); - gltex->Bind(CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha)); + gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha)); u1 = gltex->GetUL(); v1 = gltex->GetVT(); @@ -339,7 +339,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) } else { - gltex->Bind(CLAMP_XY_NOMIP, 0, -1, false); + gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, 0, -1, false); u1 = 0.f; v1 = 1.f; u2 = 1.f; @@ -493,7 +493,7 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture * if (!gltexture) return; - gltexture->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); // scaling is not used here. if (!local_origin) @@ -586,7 +586,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint gl_SetColor(lightlevel, 0, cm, 1.f); - gltexture->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); int i; float rot = float(rotation * M_PI / float(1u << 31)); diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 0e290adb3..236b5d551 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -5,6 +5,7 @@ #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" @@ -97,10 +98,11 @@ public: void Reset(); - void SetShader(int shaderindex, float warptime) + void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) { - mEffectState = shaderindex; - mShaderTimer = warptime; + mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex; + mShaderTimer = mat->tex->gl_info.shaderspeed; + mat->Bind(clampmode, translation, alphatexture); } void Apply(); diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 4fc7603cf..c938e9043 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -319,7 +319,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) gl_SetRenderStyle(decal->RenderStyle, false, false); - tex->Bind(CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha)); + 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 diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 1e6bc1bfe..b92a2c6cf 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -1097,7 +1097,7 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo int rel = getExtraLight(); gl_SetColor(lightlevel, rel, Colormap, 1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gltexture->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); float fviewx = FIXED2FLOAT(viewx); float fviewy = FIXED2FLOAT(viewy); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index ec442294a..ac185aee9 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -341,7 +341,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG case GLPASS_ALL: gl_SetColor(lightlevel, rel, Colormap,1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gltexture->Bind(CLAMP_NONE, 0, -1, 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); @@ -367,7 +367,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG } else { - gltexture->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(&plane, gltexture); DrawSubsectors(pass, true, true); gl_RenderState.EnableTextureMatrix(false); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 5e82dbd7b..02e7747bc 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -1011,7 +1011,7 @@ void GLHorizonPortal::DrawContents() } - gltexture->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(sp, gltexture); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index f1fdfb812..b095d261b 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -1119,7 +1119,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in if (!usefb) { glFlush(); - gltex->Bind(0, 0, -1, false); + gl_RenderState.SetMaterial(gltex, 0, 0, -1, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height); } else diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index b12ada3fc..a6ee502d5 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -268,7 +268,7 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in if (tex) { - tex->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_NONE, 0, -1, false); texw = tex->TextureWidth(); texh = tex->TextureHeight(); gl_RenderState.EnableModelMatrix(true); @@ -333,7 +333,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // north tex = FMaterial::ValidateTexture(sb->faces[0], false); - tex->Bind(CLAMP_XY, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -349,7 +349,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // east tex = FMaterial::ValidateTexture(sb->faces[1], false); - tex->Bind(CLAMP_XY, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -365,7 +365,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // south tex = FMaterial::ValidateTexture(sb->faces[2], false); - tex->Bind(CLAMP_XY, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -381,7 +381,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // west tex = FMaterial::ValidateTexture(sb->faces[3], false); - tex->Bind(CLAMP_XY, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -425,7 +425,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // top tex = FMaterial::ValidateTexture(sb->faces[faces], false); - tex->Bind(CLAMP_XY, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); @@ -441,7 +441,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // bottom tex = FMaterial::ValidateTexture(sb->faces[faces+1], false); - tex->Bind(CLAMP_XY, 0, -1, false); + gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false); gl_RenderState.Apply(); ptr = GLRenderer->mVBO->GetBuffer(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 502264e20..5d8995a34 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -214,7 +214,7 @@ void GLSprite::Draw(int pass) gl_RenderState.SetFog(0, 0); } - if (gltexture) gltexture->Bind(CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); + if (gltexture) gl_RenderState.SetMaterial(gltexture, CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); else if (!modelframe) gl_RenderState.EnableTexture(false); if (!modelframe) diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index bf3e9dbd1..bad0aa5d1 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -274,7 +274,7 @@ void GLWall::RenderMirrorSurface() glDepthFunc(GL_LEQUAL); FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture, false); - pat->Bind(CLAMP_NONE, 0, -1, false); + gl_RenderState.SetMaterial(pat, CLAMP_NONE, 0, -1, false); flags &= ~GLWF_GLOW; RenderWall(RWF_BLANK); @@ -326,7 +326,7 @@ void GLWall::RenderTranslucentWall() if (gltexture) { gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(flags & 3, 0, -1, false); + gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false); extra = getExtraLight(); } else @@ -390,7 +390,7 @@ void GLWall::Draw(int pass) else gl_SetFog(255, 0, NULL, false); gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - gltexture->Bind(flags & 3, false, -1, false); + gl_RenderState.SetMaterial(gltexture, flags & 3, false, -1, false); RenderWall(RWF_TEXTURED|RWF_GLOW); gl_RenderState.EnableGlow(false); break; diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 67e2f9576..d64c0a39a 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -96,7 +96,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed FMaterial * tex = FMaterial::ValidateTexture(lump, true, false); if (!tex) return; - tex->Bind(CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture); + gl_RenderState.SetMaterial(tex, CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture); int vw = viewwidth; int vh = viewheight; diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 7995b572b..063f948c0 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -616,11 +616,9 @@ static int lastclamp; static int lasttrans; static bool lastalpha; -void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool alphatexture) -{ - int shaderindex = overrideshader >= 0? overrideshader : mShaderIndex; - gl_RenderState.SetShader(shaderindex, tex->gl_info.shaderspeed); +void FMaterial::Bind(int clampmode, int translation, bool alphatexture) +{ // avoid rebinding the same texture multiple times. if (this == last && lastclamp == clampmode && translation == lasttrans && lastalpha == alphatexture) return; last = this; @@ -636,7 +634,7 @@ void FMaterial::Bind(int clampmode, int translation, int overrideshader, bool al else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, alphatexture, allowhires? tex:NULL); - if (gltexture != NULL && shaderindex > 0 && overrideshader == -1) + if (gltexture != NULL) { for(unsigned i=0;i Date: Tue, 9 Sep 2014 13:21:36 +0200 Subject: [PATCH 132/138] - changed the handling of alpha textures. The only special case they need is with palette-less textures and this can be handled far more easily and robustly with a predefined translation instead of passing another parameter through all the layers of the texture management code. This also fixes problems with paletted PNGs that get used as an alpha texture because the old method clobbered the image's palette. --- src/gl/renderer/gl_lightdata.cpp | 6 +++++- src/gl/renderer/gl_renderstate.h | 10 ++++++++- src/gl/system/gl_interface.h | 7 ++++--- src/gl/system/gl_wipe.cpp | 22 ++++++++++---------- src/gl/textures/gl_bitmap.cpp | 19 ++++------------- src/gl/textures/gl_bitmap.h | 11 +--------- src/gl/textures/gl_hwtexture.cpp | 17 +++------------ src/gl/textures/gl_hwtexture.h | 10 ++------- src/gl/textures/gl_material.cpp | 33 +++++++++++++----------------- src/gl/textures/gl_material.h | 14 ++++++------- src/r_data/r_translate.cpp | 9 ++++++++ wadsrc/static/shaders/glsl/main.fp | 10 ++++++--- 12 files changed, 75 insertions(+), 93 deletions(-) diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 29013f280..a02762eb8 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -142,7 +142,11 @@ 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; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 236b5d551..e0f5406dd 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -8,6 +8,7 @@ #include "gl/textures/gl_material.h" #include "c_cvars.h" #include "r_defs.h" +#include "r_data/r_translate.h" class FVertexBuffer; class FShader; @@ -100,9 +101,16 @@ public: 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, alphatexture); + mat->Bind(clampmode, translation); } void Apply(); diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index af4c4f7c2..2d2e26d51 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -16,9 +16,10 @@ enum RenderFlags enum TexMode { TM_MODULATE = 0, // (r, g, b, a) - TM_MASK = 1, // (1, 1, 1, a) - TM_OPAQUE = 2, // (r, g, b, 1) - TM_INVERSE = 3, // (1-r, 1-g, 1-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 diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 564dd1e03..30a996816 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -148,11 +148,11 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) } wipestartscreen = new FHardwareTexture(Width, Height, true); - wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); + wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE); glFinish(); - wipestartscreen->Bind(0, false, false, false); + wipestartscreen->Bind(0, false, false); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -171,10 +171,10 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) void OpenGLFrameBuffer::WipeEndScreen() { wipeendscreen = new FHardwareTexture(Width, Height, true); - wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0, false); + wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER); glFinish(); - wipeendscreen->Bind(0, false, false, false); + 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); @@ -286,7 +286,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, 0, false, false); + fb->wipestartscreen->Bind(0, 0, false); FFlatVertex *ptr; unsigned int offset, count; @@ -301,7 +301,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb) ptr++; GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count); - fb->wipeendscreen->Bind(0, 0, false, false); + 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); @@ -348,7 +348,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipeendscreen->Bind(0, 0, false, false); + fb->wipeendscreen->Bind(0, 0, false); FFlatVertex *ptr; ptr = GLRenderer->mVBO->GetBuffer(); ptr->Set(0, 0, 0, 0, vb); @@ -364,7 +364,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb) int i, dy; bool done = false; - fb->wipestartscreen->Bind(0, 0, false, false); + fb->wipestartscreen->Bind(0, 0, false); // Copy the old screen in vertical strips on top of the new one. while (ticks--) { @@ -496,7 +496,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.ResetColor(); gl_RenderState.Apply(); - fb->wipestartscreen->Bind(0, 0, false, false); + fb->wipestartscreen->Bind(0, 0, false); FFlatVertex *ptr; unsigned int offset, count; ptr = GLRenderer->mVBO->GetBuffer(); @@ -516,9 +516,9 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) gl_RenderState.Apply(); // Burn the new screen on top of it. - fb->wipeendscreen->Bind(0, 0, false, false); + fb->wipeendscreen->Bind(0, 0, false); - BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0, false); + BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); gl_RenderState.SetEffect(EFF_NONE); diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp index 0c74c9ae7..a2319f67c 100644 --- a/src/gl/textures/gl_bitmap.cpp +++ b/src/gl/textures/gl_bitmap.cpp @@ -51,7 +51,7 @@ // //=========================================================================== template -void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, int count, int step) +void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step) { int i; @@ -69,7 +69,7 @@ void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, } } -typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, bool alphatex, int count, int step); +typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int count, int step); static CopyFunc copyfuncs[]={ iCopyColors, @@ -99,7 +99,7 @@ void FGLBitmap::CopyPixelDataRGB(int originx, int originy, BYTE *buffer = GetPixels() + 4*originx + Pitch*originy; for (int y=0;y 0) + if (translation > 0) { PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); if (ptrans) diff --git a/src/gl/textures/gl_bitmap.h b/src/gl/textures/gl_bitmap.h index 98addb51d..6aea6d008 100644 --- a/src/gl/textures/gl_bitmap.h +++ b/src/gl/textures/gl_bitmap.h @@ -7,34 +7,25 @@ class FGLBitmap : public FBitmap { - bool alphatex; int translation; public: FGLBitmap() { - alphatex = false; translation = 0; } FGLBitmap(BYTE *buffer, int pitch, int width, int height) : FBitmap(buffer, pitch, width, height) { - alphatex = false; translation = 0; } void SetTranslationInfo(int _trans) { - if (_trans == -1) alphatex = true; - else if (_trans != -1337) translation = _trans; + if (_trans != -1337) translation = _trans; } - void SetAlphaTex() - { - alphatex = true; - } - virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth, int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf = NULL); virtual void CopyPixelData(int originx, int originy, const BYTE * patch, int srcwidth, int srcheight, diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index f491169b4..c855ef285 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -184,18 +184,13 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un // //=========================================================================== -unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture) +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; - if (alphatexture) - { - texformat = GL_R8; - translation = TRANS_Alpha; - } - else if (forcenocompression) + if (forcenocompression) { texformat = GL_RGBA8; } @@ -245,11 +240,6 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int glTex->mipmapped = true; } - if (alphatexture) - { - static const GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } if (texunit != 0) glActiveTexture(GL_TEXTURE0); return glTex->glTexID; } @@ -362,9 +352,8 @@ FHardwareTexture::TranslatedTexture *FHardwareTexture::GetTexID(int translation) // Binds this patch // //=========================================================================== -unsigned int FHardwareTexture::Bind(int texunit, int translation, bool alphatexture, bool needmipmap) +unsigned int FHardwareTexture::Bind(int texunit, int translation, bool needmipmap) { - if (alphatexture) translation = TRANS_Alpha; TranslatedTexture *pTex = GetTexID(translation); if (pTex->glTexID != 0) diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index eabc7a6ef..7fa0f0580 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -20,11 +20,6 @@ enum EInvalid Invalid = 0 }; -enum ETranslation -{ - TRANS_Alpha = INT_MAX -}; - enum { GLT_CLAMPX=1, @@ -66,7 +61,6 @@ private: TArray glTex_Translated; unsigned int glDepthID; // only used by camera textures - void LoadImage(unsigned char * buffer,int w, int h, TranslatedTexture *glTex, bool mipmap, bool alphatexture, int texunit); TranslatedTexture * GetTexID(int translation); int GetDepthBuffer(); @@ -81,8 +75,8 @@ public: void BindToFrameBuffer(); - unsigned int Bind(int texunit, int translation, bool alphatexture, bool needmipmap); - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, bool alphatexture); + 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 063f948c0..6b22e0a5e 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -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, bool alphatexture) +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); - if (alphatexture) bmp.SetAlphaTex(); - int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); hirestexture->CheckTrans(buffer, w*h, trans); @@ -181,7 +179,7 @@ void FGLTexture::Clean(bool all) // //=========================================================================== -unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture) +unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck) { unsigned char * buffer; int W, H; @@ -191,7 +189,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F // by hires textures if (gl_texture_usehires && hirescheck != NULL) { - buffer = LoadHiresTexture (hirescheck, &w, &h, alphatexture); + buffer = LoadHiresTexture (hirescheck, &w, &h); if (buffer) { return buffer; @@ -207,7 +205,6 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F FGLBitmap bmp(buffer, W*4, W, H); bmp.SetTranslationInfo(translation); - if (alphatexture) bmp.SetAlphaTex(); if (tex->bComplex) { @@ -241,7 +238,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. // [BB] Potentially upsample the buffer. - return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || alphatexture); + return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, !!bIsTransparent); } @@ -267,7 +264,7 @@ FHardwareTexture *FGLTexture::CreateHwTexture() // //=========================================================================== -const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, bool alphatexture, FTexture *hirescheck) +const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck) { int usebright = false; @@ -288,7 +285,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla } // Bind it to the system. - if (!hwtex->Bind(texunit, translation, alphatexture, needmipmap)) + if (!hwtex->Bind(texunit, translation, needmipmap)) { int w=0, h=0; @@ -298,10 +295,10 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(translation, w, h, hirescheck, alphatexture); + buffer = CreateTexBuffer(translation, w, h, hirescheck); tex->ProcessData(buffer, w, h, false); } - if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, alphatexture)) + if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation)) { // could not create texture delete[] buffer; @@ -614,16 +611,14 @@ outl: static FMaterial *last; static int lastclamp; static int lasttrans; -static bool lastalpha; -void FMaterial::Bind(int clampmode, int translation, bool alphatexture) +void FMaterial::Bind(int clampmode, int translation) { // avoid rebinding the same texture multiple times. - if (this == last && lastclamp == clampmode && translation == lasttrans && lastalpha == alphatexture) return; + if (this == last && lastclamp == clampmode && translation == lasttrans) return; last = this; lastclamp = clampmode; - lastalpha = alphatexture; lasttrans = translation; int usebright = false; @@ -633,7 +628,7 @@ void FMaterial::Bind(int clampmode, int translation, bool alphatexture) if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, alphatexture, allowhires? tex:NULL); + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL); if (gltexture != NULL) { for(unsigned i=0;igl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, false, NULL); + layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, NULL); maxbound = i+1; } } @@ -669,7 +664,7 @@ void FMaterial::Bind(int clampmode, int translation, bool alphatexture) //=========================================================================== void FMaterial::Precache() { - Bind(0, 0, false); + Bind(0, 0); } //=========================================================================== @@ -749,7 +744,7 @@ void FMaterial::BindToFrameBuffer() if (mBaseLayer->mHwTexture == NULL) { // must create the hardware texture first - mBaseLayer->Bind(0, 0, 0, false, NULL); + mBaseLayer->Bind(0, 0, 0, NULL); FHardwareTexture::Unbind(0); ClearLastTexture(); } diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 6d3015a52..b5f055d24 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -67,18 +67,17 @@ private: bool bHasColorkey; // only for hires bool bExpand; - unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture); + unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height); FHardwareTexture *CreateHwTexture(); - const FHardwareTexture *Bind(int texunit, int clamp, int translation, bool alphatexture, FTexture *hirescheck); - const FHardwareTexture *BindPatch(int texunit, int translation, bool alphatexture); - + const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck); + public: FGLTexture(FTexture * tx, bool expandpatches); ~FGLTexture(); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool alphatexture); + unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck); void Clean(bool all); int Dump(int i); @@ -138,12 +137,11 @@ public: return mTextureLayers.Size() + 1; } - //void Bind(int clamp = 0, int translation = 0, int overrideshader = 0, bool alphatexture = false); - void Bind(int clamp, int translation, bool alphatexture); + 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, 0); + return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex : NULL); } void Clean(bool f) 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/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 532529f0b..c77a058c2 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -60,17 +60,21 @@ vec4 getTexel(vec2 st) // switch (uTextureMode) { - case 1: + case 1: // TM_MASK texel.rgb = vec3(1.0,1.0,1.0); break; - case 2: + case 2: // TM_OPAQUE texel.a = 1.0; break; - case 3: + 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; From ddf58b43c984384ff4284c8a63b9a9eeb3770c0a Mon Sep 17 00:00:00 2001 From: Ralgor Date: Sun, 14 Sep 2014 14:28:05 -0500 Subject: [PATCH 133/138] Fix compile errors on linux. --- src/gl/textures/gl_texture.cpp | 2 +- src/gl/utility/gl_clock.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index b737ced77..838510bcd 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -814,7 +814,7 @@ CCMD(textureinfo) 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, i, lump, Wads.GetLumpFullName(lump)); + Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", (const char*)(tex->Name), i, lump, Wads.GetLumpFullName(lump)); if (tex->gl_info.Material[0]) { Printf(PRINT_LOG, "in use (normal)\n"); diff --git a/src/gl/utility/gl_clock.h b/src/gl/utility/gl_clock.h index f12cf1ef9..46a01d1e4 100644 --- a/src/gl/utility/gl_clock.h +++ b/src/gl/utility/gl_clock.h @@ -5,12 +5,12 @@ #include "x86.h" #include "m_fixed.h" +extern bool gl_benching; + #ifdef _MSC_VER extern double gl_SecondsPerCycle; extern double gl_MillisecPerCycle; -extern bool gl_benching; - __forceinline long long GetClockCycle () { From 1a70a6aabcb6079a08222507515f3be3515e95e7 Mon Sep 17 00:00:00 2001 From: Ralgor Date: Sun, 14 Sep 2014 14:29:13 -0500 Subject: [PATCH 134/138] The light buffer should check for shader_storage_buffer_object rather than buffer_storage. --- src/gl/dynlights/gl_lightbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index 3031d3916..e8d2520da 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -54,7 +54,7 @@ FLightBuffer::FLightBuffer() mBufferSize = INITIAL_BUFFER_SIZE; mByteSize = mBufferSize * sizeof(float); - if (gl.flags & RFL_BUFFER_STORAGE) + if (gl.flags & RFL_SHADER_STORAGE_BUFFER) { mBufferType = GL_SHADER_STORAGE_BUFFER; mBlockAlign = -1; From cfc8f3dbbf7ed1938d2fb70a0d6c7d4718a89e93 Mon Sep 17 00:00:00 2001 From: Ralgor Date: Sun, 14 Sep 2014 14:42:14 -0500 Subject: [PATCH 135/138] Global GL render context shouldn't be initialized inside of gl_PrintStartupLog, since it's not compiled in non MSC builds. --- src/gl/system/gl_framebuffer.cpp | 9 +++++++++ src/gl/system/gl_interface.cpp | 3 --- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 54df9b851..2ddbf3439 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -126,6 +126,15 @@ void OpenGLFrameBuffer::InitializeState() gl_LoadExtensions(); Super::InitializeState(); + + 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; + if (first) { first=false; diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 95ab2e289..af03bf1d1 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -168,15 +168,12 @@ void gl_PrintStartupLog() Printf ("Max. texture units: %d\n", v); glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); Printf ("Max. fragment uniforms: %d\n", v); - 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); - gl.maxuniformblock = v; glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v); Printf ("Uniform block alignment: %d\n", v); - gl.uniformblockalignment = v; glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); From 5cc43137a12fa5868729b7c5616422401a6ec9bf Mon Sep 17 00:00:00 2001 From: Ralgor Date: Sun, 14 Sep 2014 14:43:42 -0500 Subject: [PATCH 136/138] Only require OpenGL 3.0 compatibility profile. --- src/gl/shaders/gl_shader.cpp | 2 +- src/gl/system/gl_interface.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 72815f2e2..3d4afdbcc 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -94,7 +94,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * if (lightbuffertype == GL_UNIFORM_BUFFER) { - vp_comb.Format("#version 330 core\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); + vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } else { diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index af03bf1d1..5d4e8efeb 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -117,9 +117,9 @@ void gl_LoadExtensions() else Printf("Emulating OpenGL v %s\n", version); // Don't even start if it's lower than 3.0 - if (strcmp(version, "3.3") < 0) + if (strcmp(version, "3.0") < 0) { - I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.3 is required to run " GAMENAME ".\n"); + I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.0 is required to run " GAMENAME ".\n"); } // add 0.01 to account for roundoff errors making the number a tad smaller than the actual version From 32f08adaf366a30d9bd091139211fc72555c11b3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Sep 2014 23:01:57 +0200 Subject: [PATCH 137/138] - moved some code to better places. - allow GL version 3.0 in Windows, too. --- src/gl/system/gl_framebuffer.cpp | 8 -------- src/gl/system/gl_interface.cpp | 8 ++++++++ src/gl/textures/gl_texture.cpp | 2 +- src/win32/win32gliface.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 2ddbf3439..d9f05bea6 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -127,14 +127,6 @@ void OpenGLFrameBuffer::InitializeState() gl_LoadExtensions(); Super::InitializeState(); - 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; - if (first) { first=false; diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 5d4e8efeb..be0beaf4e 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -137,6 +137,14 @@ void gl_LoadExtensions() 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); } diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index 838510bcd..53a07d437 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -814,7 +814,7 @@ CCMD(textureinfo) 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", (const char*)(tex->Name), i, lump, Wads.GetLumpFullName(lump)); + 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"); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 81b1d9418..59ce1e65e 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -775,8 +775,8 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) 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.3 is a requirement. - static int versions[] = { 45, 44, 43, 42, 41, 40, 33, -1 }; + // 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 }; for (int i = 0; versions[i] > 0; i++) { From 8e7e16f73a8f14945d8e4aacf28aa4c359eb2676 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 15 Sep 2014 10:27:09 +0200 Subject: [PATCH 138/138] - fixed: The light uniform buffer may not be mapped with GL_MAP_INVALIDATE_BUFFER_BIT, because it needs to be mapped for each portal in a scene but it must preserve the existing data for the remaining translucent objects. --- src/gl/dynlights/gl_lightbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/dynlights/gl_lightbuffer.cpp b/src/gl/dynlights/gl_lightbuffer.cpp index e8d2520da..7e96c43ce 100644 --- a/src/gl/dynlights/gl_lightbuffer.cpp +++ b/src/gl/dynlights/gl_lightbuffer.cpp @@ -190,7 +190,7 @@ void FLightBuffer::Begin() if (!(gl.flags & RFL_BUFFER_STORAGE)) { glBindBuffer(mBufferType, mBufferId); - mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT); + mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT); } }