- added quad drawer interface so that this part can be done without altering a vertex buffer.

So far it's only the framework, the new code is not active yet.
This commit is contained in:
Christoph Oelckers 2016-08-22 14:00:25 +02:00
parent 302f59ea33
commit 7ba5acfb35
13 changed files with 216 additions and 67 deletions

View File

@ -1061,6 +1061,7 @@ set( FASTMATH_SOURCES
gl/utility/gl_cycler.cpp gl/utility/gl_cycler.cpp
gl/utility/gl_geometric.cpp gl/utility/gl_geometric.cpp
gl/renderer/gl_2ddrawer.cpp gl/renderer/gl_2ddrawer.cpp
gl/renderer/gl_quaddrawer.cpp
gl/renderer/gl_renderer.cpp gl/renderer/gl_renderer.cpp
gl/renderer/gl_renderstate.cpp gl/renderer/gl_renderstate.cpp
gl/renderer/gl_renderbuffers.cpp gl/renderer/gl_renderbuffers.cpp

View File

@ -97,9 +97,17 @@ public:
{ {
return &map[mCurIndex]; return &map[mCurIndex];
} }
FFlatVertex *Alloc(int num, int *poffset)
{
FFlatVertex *p = GetBuffer();
*poffset = mCurIndex;
mCurIndex += num;
if (mCurIndex >= BUFFER_SIZE_TO_USE) mCurIndex = mIndex;
return p;
}
unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset) 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; unsigned int diff = newofs - mCurIndex;
*poffset = mCurIndex; *poffset = mCurIndex;

View File

@ -0,0 +1,85 @@
/*
** gl_quaddrawer.h
**
**---------------------------------------------------------------------------
** Copyright 2016 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/shaders/gl_shader.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_quaddrawer.h"
#include "gl/data/gl_matrix.h"
/*
** For handling of dynamically created quads when no persistently mapped
** buffer or client array is available (i.e. GL 3.x core profiles)
**
** In this situation the 4 vertices of a quad primitive are being passed
** as a matrix uniform because that is a lot faster than any kind of
** temporary buffer change.
*/
FFlatVertex FQuadDrawer::buffer[4];
//==========================================================================
//
//
//
//==========================================================================
void FQuadDrawer::DoRender(int type)
{
// When this gets called, the render state must already be applied so we can just
// send our vertices to the current shader.
float matV[16], matT[16];
for(int i=0;i<4;i++)
{
matV[i*4+0] = buffer[i].x;
matV[i*4+1] = buffer[i].z;
matV[i*4+2] = buffer[i].y;
matT[i*4+0] = buffer[i].u;
matT[i*4+1] = buffer[i].v;
matV[i*4+3] = matT[i*4+2] = matT[i*4+3] = 0;
}
FShader *shader = GLRenderer->mShaderManager->GetActiveShader();
glUniformMatrix4fv(shader->vertexmatrix_index, 1, false, matV);
glUniformMatrix4fv(shader->texcoordmatrix_index, 1, false, matT);
glUniform1i(shader->quadmode_index, 1);
GLRenderer->mVBO->RenderArray(type, 0, 4);
glUniform1i(shader->quadmode_index, 0);
}

View File

@ -0,0 +1,44 @@
#ifndef __QDRAWER_H
#define __QDRAWER_H
#include "gl/data/gl_vertexbuffer.h"
class FQuadDrawer
{
FFlatVertex *p;
int ndx;
static FFlatVertex buffer[4];
void DoRender(int type);
public:
FQuadDrawer()
{
if (gl.flags & RFL_QUADHACK)
{
p = buffer;
}
else
{
p = GLRenderer->mVBO->Alloc(4, &ndx);
}
}
void Set(int ndx, float x, float y, float z, float s, float t)
{
p[ndx].Set(x, y, z, s, t);
}
void Render(int type)
{
if (gl.flags & RFL_QUADHACK)
{
DoRender(type);
}
else
{
GLRenderer->mVBO->RenderArray(type, ndx, 4);
}
}
};
#endif

View File

@ -54,6 +54,7 @@
#include "gl/textures/gl_texture.h" #include "gl/textures/gl_texture.h"
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h" #include "gl/utility/gl_clock.h"
#include "gl/renderer/gl_quaddrawer.h"
struct DecalVertex struct DecalVertex
{ {
@ -328,22 +329,19 @@ void GLWall::DrawDecal(DBaseDecal *decal)
gl_RenderState.SetFog(0,-1); gl_RenderState.SetFog(0,-1);
} }
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); FQuadDrawer qd;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v); qd.Set(i, dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v);
ptr++;
} }
if (lightlist == NULL) if (lightlist == NULL)
{ {
gl_RenderState.Apply(); gl_RenderState.Apply();
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN); qd.Render(GL_TRIANGLE_FAN);
} }
else else
{ {
unsigned int offset;
unsigned int count = GLRenderer->mVBO->GetCount(ptr, &offset);
for (unsigned k = 0; k < lightlist->Size(); k++) for (unsigned k = 0; k < lightlist->Size(); k++)
{ {
secplane_t &lowplane = k == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[k + 1].plane; secplane_t &lowplane = k == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[k + 1].plane;
@ -363,7 +361,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
gl_RenderState.SetSplitPlanes((*lightlist)[k].plane, lowplane); gl_RenderState.SetSplitPlanes((*lightlist)[k].plane, lowplane);
gl_RenderState.Apply(); gl_RenderState.Apply();
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count); qd.Render(GL_TRIANGLE_FAN);
} }
if (low1 <= dv[0].z && low2 <= dv[3].z) break; if (low1 <= dv[0].z && low2 <= dv[3].z) break;
} }

View File

@ -57,6 +57,7 @@
#include "gl/utility/gl_templates.h" #include "gl/utility/gl_templates.h"
#include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_shader.h"
#include "gl/stereo3d/scoped_color_mask.h" #include "gl/stereo3d/scoped_color_mask.h"
#include "gl/renderer/gl_quaddrawer.h"
FDrawInfo * gl_drawinfo; FDrawInfo * gl_drawinfo;
@ -1079,17 +1080,12 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws)
glDepthMask(true); glDepthMask(true);
gl_RenderState.Apply(); gl_RenderState.Apply();
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); FQuadDrawer qd;
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0); qd.Set(0, ws->x1, ws->z1, ws->y1, 0, 0);
ptr++; qd.Set(1, ws->x1, ws->z2, ws->y1, 0, 0);
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0); qd.Set(2, ws->x2, ws->z2, ws->y2, 0, 0);
ptr++; qd.Set(3, ws->x2, ws->z1, ws->y2, 0, 0);
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0); qd.Render(GL_TRIANGLE_FAN);
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 glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil
@ -1112,16 +1108,12 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws)
gl_RenderState.ResetColor(); gl_RenderState.ResetColor();
gl_RenderState.Apply(); gl_RenderState.Apply();
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); FQuadDrawer qd;
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0); qd.Set(0, ws->x1, ws->z1, ws->y1, 0, 0);
ptr++; qd.Set(1, ws->x1, ws->z2, ws->y1, 0, 0);
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0); qd.Set(2, ws->x2, ws->z2, ws->y2, 0, 0);
ptr++; qd.Set(3, ws->x2, ws->z1, ws->y2, 0, 0);
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0); qd.Render(GL_TRIANGLE_FAN);
ptr++;
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
// restore old stencil op. // restore old stencil op.
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@ -1192,16 +1184,12 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
float px4 = fviewx + prj_fac1 * (ws->x2-fviewx); float px4 = fviewx + prj_fac1 * (ws->x2-fviewx);
float py4 = fviewy + prj_fac1 * (ws->y2-fviewy); float py4 = fviewy + prj_fac1 * (ws->y2-fviewy);
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); FQuadDrawer qd;
ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64); qd.Set(0, px1, planez, py1, px1 / 64, -py1 / 64);
ptr++; qd.Set(1, px2, planez, py2, px2 / 64, -py2 / 64);
ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64); qd.Set(2, px3, planez, py3, px3 / 64, -py3 / 64);
ptr++; qd.Set(3, px4, planez, py4, px4 / 64, -py4 / 64);
ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64); qd.Render(GL_TRIANGLE_FAN);
ptr++;
ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
gl_RenderState.EnableTextureMatrix(false); gl_RenderState.EnableTextureMatrix(false);
} }

View File

@ -64,6 +64,7 @@
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h" #include "gl/utility/gl_clock.h"
#include "gl/data/gl_vertexbuffer.h" #include "gl/data/gl_vertexbuffer.h"
#include "gl/renderer/gl_quaddrawer.h"
CVAR(Bool, gl_usecolorblending, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, gl_usecolorblending, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Bool, gl_spritebrightfog, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); CVAR(Bool, gl_spritebrightfog, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
@ -400,17 +401,12 @@ void GLSprite::Draw(int pass)
} }
FFlatVertex *ptr; FFlatVertex *ptr;
unsigned int offset, count; FQuadDrawer qd;
ptr = GLRenderer->mVBO->GetBuffer(); qd.Set(0, v1[0], v1[1], v1[2], ul, vt);
ptr->Set(v1[0], v1[1], v1[2], ul, vt); qd.Set(1, v2[0], v2[1], v2[2], ur, vt);
ptr++; qd.Set(2, v3[0], v3[1], v3[2], ul, vb);
ptr->Set(v2[0], v2[1], v2[2], ur, vt); qd.Set(3, v4[0], v4[1], v4[2], ur, vb);
ptr++; qd.Render(GL_TRIANGLE_STRIP);
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) if (foglayer)
{ {
@ -420,7 +416,7 @@ void GLSprite::Draw(int pass)
gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.Apply(); gl_RenderState.Apply();
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count); qd.Render(GL_TRIANGLE_STRIP);
gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetFixedColormap(CM_DEFAULT);
} }
} }

View File

@ -57,6 +57,7 @@
#include "gl/models/gl_models.h" #include "gl/models/gl_models.h"
#include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
#include "gl/renderer/gl_quaddrawer.h"
EXTERN_CVAR (Bool, r_drawplayersprites) EXTERN_CVAR (Bool, r_drawplayersprites)
EXTERN_CVAR(Float, transsouls) EXTERN_CVAR(Float, transsouls)
@ -161,16 +162,12 @@ void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
} }
gl_RenderState.Apply(); gl_RenderState.Apply();
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); FQuadDrawer qd;
ptr->Set(x1, y1, 0, fU1, fV1); qd.Set(0, x1, y1, 0, fU1, fV1);
ptr++; qd.Set(1, x1, y2, 0, fU1, fV2);
ptr->Set(x1, y2, 0, fU1, fV2); qd.Set(2, x2, y1, 0, fU2, fV1);
ptr++; qd.Set(3, x2, y2, 0, fU2, fV2);
ptr->Set(x2, y1, 0, fU2, fV1); qd.Render(GL_TRIANGLE_STRIP);
ptr++;
ptr->Set(x2, y2, 0, fU2, fV2);
ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
} }

View File

@ -265,6 +265,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix"); viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix");
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix"); modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");
texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix"); texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix");
vertexmatrix_index = glGetUniformLocation(hShader, "uQuadVertices");
texcoordmatrix_index = glGetUniformLocation(hShader, "uQuadTexCoords");
quadmode_index = glGetUniformLocation(hShader, "uQuadMode");
if (LM_SOFTWARE != gl.lightmethod && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) if (LM_SOFTWARE != gl.lightmethod && !(gl.flags & RFL_SHADER_STORAGE_BUFFER))
{ {

View File

@ -244,6 +244,9 @@ class FShader
int modelmatrix_index; int modelmatrix_index;
int texturematrix_index; int texturematrix_index;
public: public:
int vertexmatrix_index;
int texcoordmatrix_index;
int quadmode_index;
int fakevb_index; int fakevb_index;
private: private:
int currentglowstate = 0; int currentglowstate = 0;

View File

@ -25,7 +25,8 @@ enum RenderFlags
RFL_NO_DEPTHSTENCIL = 64, RFL_NO_DEPTHSTENCIL = 64,
RFL_NO_CLIP_PLANES = 128, RFL_NO_CLIP_PLANES = 128,
RFL_INVALIDATE_BUFFER = 256 RFL_INVALIDATE_BUFFER = 256,
RFL_QUADHACK = 512
}; };
enum TexMode enum TexMode

View File

@ -13,10 +13,28 @@ out vec4 vColor;
void main() void main()
{ {
#ifndef SIMPLE vec2 parmTexCoord;
vec4 worldcoord = ModelMatrix * mix(aPosition, aVertex2, uInterpolationFactor); vec4 parmPosition;
#ifndef USE_QUAD_DRAWER
parmTexCoord = aTexCoord;
parmPosition = aPosition;
#else #else
vec4 worldcoord = ModelMatrix * aPosition; if (uQuadMode == 0)
{
parmTexCoord = aTexCoord;
parmPosition = aPosition;
}
else
{
parmPosition = uQuadVertices[int(aPosition.x)].st;
parmTexCoord = uQuadTexCoords[int(aPosition.x)];
}
#endif
#ifndef SIMPLE
vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor);
#else
vec4 worldcoord = ModelMatrix * parmPosition;
#endif #endif
vec4 eyeCoordPos = ViewMatrix * worldcoord; vec4 eyeCoordPos = ViewMatrix * worldcoord;
@ -39,13 +57,13 @@ void main()
#ifdef SPHEREMAP #ifdef SPHEREMAP
vec3 u = normalize(eyeCoordPos.xyz); vec3 u = normalize(eyeCoordPos.xyz);
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. vec4 n = normalize(TextureMatrix * vec4(parmTexCoord.x, 0.0, parmTexCoord.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); 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) ); 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); vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5);
vTexCoord.xy = sst; vTexCoord.xy = sst;
#else #else
vTexCoord = TextureMatrix * vec4(aTexCoord, 0.0, 1.0); vTexCoord = TextureMatrix * vec4(parmTexCoord, 0.0, 1.0);
#endif #endif
gl_Position = ProjectionMatrix * eyeCoordPos; gl_Position = ProjectionMatrix * eyeCoordPos;

View File

@ -45,6 +45,13 @@ uniform int uFogEnabled;
// dynamic lights // dynamic lights
uniform int uLightIndex; uniform int uLightIndex;
// quad drawer stuff
#ifdef USE_QUAD_DRAWER
uniform mat4 uQuadVertices;
uniform mat4 uQuadTexCoords;
uniform int uQuadMode;
#endif
// matrices // matrices
uniform mat4 ProjectionMatrix; uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix; uniform mat4 ViewMatrix;