diff --git a/src.cmake b/src.cmake index e5e4f4974b..0e0c13bf36 100644 --- a/src.cmake +++ b/src.cmake @@ -99,6 +99,7 @@ set(RENDERERLIST ${ENGINE_DIR}/renderer/GeometryOptimiser.h ${ENGINE_DIR}/renderer/GLMemory.cpp ${ENGINE_DIR}/renderer/GLMemory.h + ${ENGINE_DIR}/renderer/GLUtils.h ${ENGINE_DIR}/renderer/InternalImage.cpp ${ENGINE_DIR}/renderer/InternalImage.h ${ENGINE_DIR}/renderer/Material.cpp @@ -137,6 +138,8 @@ set(RENDERERLIST ${ENGINE_DIR}/renderer/tr_surface.cpp ${ENGINE_DIR}/renderer/tr_types.h ${ENGINE_DIR}/renderer/tr_vbo.cpp + ${ENGINE_DIR}/renderer/VBO.h + ${ENGINE_DIR}/renderer/VertexSpecification.h ${ENGINE_DIR}/renderer/tr_video.cpp ${ENGINE_DIR}/renderer/tr_world.cpp ${ENGINE_DIR}/sys/sdl_glimp.cpp diff --git a/src/engine/renderer/GLMemory.h b/src/engine/renderer/GLMemory.h index a6634da138..c454fbe230 100644 --- a/src/engine/renderer/GLMemory.h +++ b/src/engine/renderer/GLMemory.h @@ -43,8 +43,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #include -#include "tr_local.h" #include "BufferBind.h" +#include "GLUtils.h" +#include "VertexSpecification.h" class GLBuffer { public: @@ -222,14 +223,14 @@ class GLVAO { vboAttributeLayout_t attrs[ATTR_INDEX_MAX]; uint32_t enabledAttrs; - GLVAO( const GLuint newVBOBindingPoint ) : + GLVAO( const GLuint newVBOBindingPoint = 0 ) : VBOBindingPoint( newVBOBindingPoint ) { } ~GLVAO() = default; void Bind() { - glBindVertexArray( id ); + GL_BindVAO( id ); } void SetAttrs( const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd ) { @@ -274,6 +275,11 @@ class GLVAO { glVertexArrayElementBuffer( id, buffer.id ); } + // For compatibility with IBO_t + void SetIndexBuffer( const GLuint bufferID ) { + glVertexArrayElementBuffer( id, bufferID ); + } + void GenVAO() { glGenVertexArrays( 1, &id ); } @@ -284,7 +290,7 @@ class GLVAO { private: GLuint id; - const GLuint VBOBindingPoint; + GLuint VBOBindingPoint; GLuint stride; }; diff --git a/src/engine/renderer/GLUtils.h b/src/engine/renderer/GLUtils.h new file mode 100644 index 0000000000..0e37a3c003 --- /dev/null +++ b/src/engine/renderer/GLUtils.h @@ -0,0 +1,43 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2006-2011 Robert Beckebans + +This file is part of Daemon source code. + +Daemon source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Daemon source code 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Daemon source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// GLUtils.h + +#ifndef GLUTILS_H +#define GLUTILS_H + +#include "common/Common.h" +#include "GL/glew.h" + +#include "tr_public.h" +#include "tr_types.h" + +extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init +extern glconfig2_t glConfig2; + +void GL_CheckErrors_( const char *filename, int line ); + +void GL_BindVAO( const GLuint id ); + +#define GL_CheckErrors() do { if ( !glConfig.smpActive ) GL_CheckErrors_( __FILE__, __LINE__ ); } while ( false ) + +#endif // GLUTILS_H diff --git a/src/engine/renderer/GeometryCache.cpp b/src/engine/renderer/GeometryCache.cpp index 085011a33a..a0a20e4d4a 100644 --- a/src/engine/renderer/GeometryCache.cpp +++ b/src/engine/renderer/GeometryCache.cpp @@ -92,5 +92,5 @@ void GeometryCache::AddMapGeometry( const uint32_t verticesNumber, const uint32_ stagingBuffer.FlushAll(); - glBindVertexArray( backEnd.currentVAO ); + GL_BindVAO( backEnd.defaultVAO ); } diff --git a/src/engine/renderer/InternalImage.cpp b/src/engine/renderer/InternalImage.cpp index d0c870b059..0332a5e279 100644 --- a/src/engine/renderer/InternalImage.cpp +++ b/src/engine/renderer/InternalImage.cpp @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // InternalImage.cpp #include "tr_local.h" +#include "GLUtils.h" // Comments may include short quotes from other authors. diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index a15a545ef1..ea4f3dc76d 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1887,7 +1887,7 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS } } - glBindVertexArray( backEnd.currentVAO ); + GL_BindVAO( backEnd.defaultVAO ); // Draw the skybox here because we skipped R_AddWorldSurfaces() const bool environmentFogDraw = ( fromSort <= shaderSort_t::SS_ENVIRONMENT_FOG ) && ( toSort >= shaderSort_t::SS_ENVIRONMENT_FOG ); diff --git a/src/engine/renderer/TextureManager.cpp b/src/engine/renderer/TextureManager.cpp index 992453aed8..b3736f28e4 100644 --- a/src/engine/renderer/TextureManager.cpp +++ b/src/engine/renderer/TextureManager.cpp @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // TextureManager.cpp #include "tr_local.h" +#include "GLUtils.h" Texture::Texture() { } diff --git a/src/engine/renderer/VBO.h b/src/engine/renderer/VBO.h new file mode 100644 index 0000000000..783d9cfba0 --- /dev/null +++ b/src/engine/renderer/VBO.h @@ -0,0 +1,86 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2006-2011 Robert Beckebans + +This file is part of Daemon source code. + +Daemon source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Daemon source code 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Daemon source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// VBO.h + +#ifndef VBO_H +#define VBO_H + +#include "common/Common.h" +#include "GL/glew.h" + +#include "GLMemory.h" +#include "VertexSpecification.h" +#include "tr_types.h" + +struct VBO_t +{ + char name[96]; // only for debugging with /listVBOs + + uint32_t vertexesVBO; + + uint32_t vertexesSize; // total amount of memory data allocated for this vbo + + uint32_t vertexesNum; + uint32_t framesNum; // number of frames for vertex animation + + std::array attribs; // info for buffer manipulation + + vboLayout_t layout; + uint32_t attribBits; // Which attributes it has. Mostly for detecting errors + GLenum usage; + + GLVAO VAO; + bool dynamicVAO = false; +}; + +struct IBO_t +{ + char name[96]; // only for debugging with /listVBOs + + uint32_t indexesVBO; + uint32_t indexesSize; // amount of memory data allocated for all triangles in bytes + uint32_t indexesNum; +}; + +void R_CopyVertexAttribute( const vboAttributeLayout_t& attrib, const vertexAttributeSpec_t& spec, + uint32_t count, byte* interleavedData ); + +VBO_t* R_CreateStaticVBO( + Str::StringRef name, const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd, + uint32_t numVerts, uint32_t numFrames = 0 ); + +IBO_t* R_CreateStaticIBO( const char* name, glIndex_t* indexes, int numIndexes ); + +void SetupVAOBuffers( VBO_t* VBO, const IBO_t* IBO, const uint32_t stateBits, + GLVAO* VAO ); + +void R_BindVBO( VBO_t* vbo ); +void R_BindNullVBO(); + +void R_BindIBO( IBO_t* ibo ); +void R_BindNullIBO(); + +void R_InitVBOs(); +void R_ShutdownVBOs(); + +#endif // GLMEMORY_H diff --git a/src/engine/renderer/VertexSpecification.h b/src/engine/renderer/VertexSpecification.h new file mode 100644 index 0000000000..9c06d264a3 --- /dev/null +++ b/src/engine/renderer/VertexSpecification.h @@ -0,0 +1,110 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2006-2011 Robert Beckebans + +This file is part of Daemon source code. + +Daemon source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Daemon source code 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Daemon source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// VertexSpecification.h + +#ifndef VERTEX_SPECIFICATION_H +#define VERTEX_SPECIFICATION_H + +#include "common/Common.h" +#include "GL/glew.h" + +enum +{ + ATTR_INDEX_POSITION = 0, + ATTR_INDEX_TEXCOORD, // TODO split into 2-element texcoords and 4-element tex + lm coords + ATTR_INDEX_QTANGENT, + ATTR_INDEX_COLOR, + + // GPU vertex skinning + ATTR_INDEX_BONE_FACTORS, + + // GPU vertex animations + ATTR_INDEX_POSITION2, + ATTR_INDEX_QTANGENT2, + ATTR_INDEX_MAX +}; + +// must match order of ATTR_INDEX enums +static const char* const attributeNames[] = +{ + "attr_Position", + "attr_TexCoord0", + "attr_QTangent", + "attr_Color", + "attr_BoneFactors", + "attr_Position2", + "attr_QTangent2" +}; + +enum +{ + ATTR_POSITION = BIT( ATTR_INDEX_POSITION ), + ATTR_TEXCOORD = BIT( ATTR_INDEX_TEXCOORD ), + ATTR_QTANGENT = BIT( ATTR_INDEX_QTANGENT ), + ATTR_COLOR = BIT( ATTR_INDEX_COLOR ), + + ATTR_BONE_FACTORS = BIT( ATTR_INDEX_BONE_FACTORS ), + + // for .md3 interpolation + ATTR_POSITION2 = BIT( ATTR_INDEX_POSITION2 ), + ATTR_QTANGENT2 = BIT( ATTR_INDEX_QTANGENT2 ), + + ATTR_INTERP_BITS = ATTR_POSITION2 | ATTR_QTANGENT2, +}; + +struct vboAttributeLayout_t +{ + GLint numComponents; // how many components in a single attribute for a single vertex + GLenum componentType; // the input type for a single component + GLboolean normalize; // convert signed integers to the floating point range [-1, 1], and unsigned integers to the range [0, 1] + GLsizei stride; + GLsizei ofs; + GLsizei frameOffset; // for vertex animation, real offset computed as ofs + frame * frameOffset +}; + +enum class vboLayout_t +{ + VBO_LAYOUT_CUSTOM, + VBO_LAYOUT_STATIC, +}; + +enum +{ + ATTR_OPTION_NORMALIZE = BIT( 0 ), + ATTR_OPTION_HAS_FRAMES = BIT( 1 ), +}; + +struct vertexAttributeSpec_t +{ + int attrIndex; + GLenum componentInputType; + GLenum componentStorageType; + const void* begin; + uint32_t numComponents; + uint32_t stride; + int attrOptions; +}; + +uint32_t R_ComponentSize( GLenum type ); + +#endif // VERTEX_SPECIFICATION_H diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index c21904f91a..a6ed7b14b9 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" #include "BufferBind.h" +#include "GLUtils.h" #include #define USE_UNIFORM_FIREWALL 1 diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 30bf342412..49155776b7 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -144,6 +144,13 @@ void GL_BindNullProgram() } } +void GL_BindVAO( const GLuint id ) { + if ( backEnd.currentVAO != id ) { + glBindVertexArray( id ); + backEnd.currentVAO = id; + } +} + void GL_SelectTexture( int unit ) { if ( glState.currenttmu == unit ) @@ -608,51 +615,7 @@ void GL_State( uint32_t stateBits ) glState.glStateBits ^= diff; } -void GL_VertexAttribsState( uint32_t stateBits ) -{ - uint32_t diff; - uint32_t i; - - if ( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ) - { - stateBits |= ATTR_BONE_FACTORS; - } - - GL_VertexAttribPointers( stateBits ); - - diff = stateBits ^ glState.vertexAttribsState; - - if ( !diff ) - { - return; - } - - for ( i = 0; i < ATTR_INDEX_MAX; i++ ) - { - uint32_t bit = BIT( i ); - - if ( ( diff & bit ) ) - { - if ( ( stateBits & bit ) ) - { - GLIMP_LOGCOMMENT( "glEnableVertexAttribArray( %s )", attributeNames[ i ] ); - - glEnableVertexAttribArray( i ); - } - else - { - GLIMP_LOGCOMMENT( "glDisableVertexAttribArray( %s )", attributeNames[ i ] ); - - glDisableVertexAttribArray( i ); - } - } - } - - glState.vertexAttribsState = stateBits; -} - -void GL_VertexAttribPointers( uint32_t attribBits ) -{ +static void GL_VertexAttribPointers( uint32_t attribBits, const bool settingUpVAO ) { uint32_t i; if ( !glState.currentVBO ) @@ -680,7 +643,7 @@ void GL_VertexAttribPointers( uint32_t attribBits ) if ( ( attribBits & bit ) != 0 && ( !( glState.vertexAttribPointersSet & bit ) || tess.vboVertexAnimation || - glState.currentVBO == tess.vbo ) ) + glState.currentVBO == tess.vbo || settingUpVAO || glState.currentVBO->dynamicVAO ) ) { const vboAttributeLayout_t *layout = &glState.currentVBO->attribs[ i ]; @@ -707,6 +670,64 @@ void GL_VertexAttribPointers( uint32_t attribBits ) } } +void GL_VertexAttribsState( uint32_t stateBits, const bool settingUpVAO ) +{ + uint32_t diff; + uint32_t i; + + if ( !settingUpVAO && glState.currentVBO && !glState.currentVBO->dynamicVAO ) { + glState.currentVBO->VAO.Bind(); + return; + } + + if ( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ) + { + stateBits |= ATTR_BONE_FACTORS; + } + + GL_VertexAttribPointers( stateBits, settingUpVAO ); + + if ( !settingUpVAO && backEnd.currentVAO != backEnd.defaultVAO ) { + return; + } + + diff = stateBits; + + if ( backEnd.currentVAO == backEnd.defaultVAO ) { + diff ^= glState.vertexAttribsState; + } + + if ( !diff ) + { + return; + } + + for ( i = 0; i < ATTR_INDEX_MAX; i++ ) + { + uint32_t bit = BIT( i ); + + if ( ( diff & bit ) ) + { + if ( ( stateBits & bit ) ) + { + GLIMP_LOGCOMMENT( "glEnableVertexAttribArray( %s )", attributeNames[ i ] ); + + glEnableVertexAttribArray( i ); + } + else + { + GLIMP_LOGCOMMENT( "glDisableVertexAttribArray( %s )", attributeNames[ i ] ); + + glDisableVertexAttribArray( i ); + } + } + } + + if ( backEnd.currentVAO == backEnd.defaultVAO ) { + glState.vertexAttribsState = stateBits; + } +} + static GLint GL_ToSRGB( GLint internalFormat, bool isSRGB ) { if ( !isSRGB ) diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 13d7774e5f..5a4079173d 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -851,6 +851,11 @@ static void FinishSkybox() { 3, 4, 7, 3, 0, 4 }; // Back surface->ibo = R_CreateStaticIBO( "skybox_IBO", indexes, surface->numTriangles * 3 ); + + SetupVAOBuffers( surface->vbo, surface->ibo, + ATTR_POSITION, + &surface->vbo->VAO ); + skybox->surface = ( surfaceType_t* ) surface; tr.skybox = skybox; @@ -2768,7 +2773,12 @@ static void R_CreateWorldVBO() { s_worldData.vbo = R_CreateStaticVBO( "staticWorld_VBO", std::begin( attrs ), std::end( attrs ), numVerts ); - s_worldData.ibo = R_CreateStaticIBO2( "staticWorld_IBO", numTriangles, vboIdxs ); + s_worldData.ibo = R_CreateStaticIBO( "staticWorld_IBO", vboIdxs, numTriangles * 3 ); + + SetupVAOBuffers( s_worldData.vbo, s_worldData.ibo, + ATTR_POSITION | ATTR_COLOR + | ATTR_QTANGENT | ATTR_TEXCOORD, + &s_worldData.vbo->VAO ); ri.Hunk_FreeTempMemory( vboIdxs ); ri.Hunk_FreeTempMemory( vboVerts ); diff --git a/src/engine/renderer/tr_cmds.cpp b/src/engine/renderer/tr_cmds.cpp index ab9d8a9370..d97badb484 100644 --- a/src/engine/renderer/tr_cmds.cpp +++ b/src/engine/renderer/tr_cmds.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // tr_cmds.c #include "tr_local.h" +#include "GLUtils.h" volatile bool renderThreadActive; diff --git a/src/engine/renderer/tr_fbo.cpp b/src/engine/renderer/tr_fbo.cpp index 37833e7e42..82e057c18e 100644 --- a/src/engine/renderer/tr_fbo.cpp +++ b/src/engine/renderer/tr_fbo.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // tr_fbo.c #include "tr_local.h" +#include "GLUtils.h" /* ============= diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 987780380d..84ebca0a37 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -374,8 +374,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA } if ( glConfig2.glCoreProfile ) { - glGenVertexArrays( 1, &backEnd.currentVAO ); - glBindVertexArray( backEnd.currentVAO ); + glGenVertexArrays( 1, &backEnd.defaultVAO ); + GL_BindVAO( backEnd.defaultVAO ); } GL_CheckErrors(); @@ -1473,7 +1473,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p GLSL_ShutdownGPUShaders(); if( glConfig2.glCoreProfile ) { glBindVertexArray( 0 ); - glDeleteVertexArrays( 1, &backEnd.currentVAO ); + glDeleteVertexArrays( 1, &backEnd.defaultVAO ); } GLimp_Shutdown(); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4b649e13de..c8d8759c90 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_public.h" #include "iqm.h" #include "TextureManager.h" +#include "VBO.h" #define DYN_BUFFER_SIZE ( 4 * 1024 * 1024 ) #define DYN_BUFFER_SEGMENTS 4 @@ -585,110 +586,6 @@ enum class ssaoMode { int height; }; - enum - { - ATTR_INDEX_POSITION = 0, - ATTR_INDEX_TEXCOORD, // TODO split into 2-element texcoords and 4-element tex + lm coords - ATTR_INDEX_QTANGENT, - ATTR_INDEX_COLOR, - - // GPU vertex skinning - ATTR_INDEX_BONE_FACTORS, - - // GPU vertex animations - ATTR_INDEX_POSITION2, - ATTR_INDEX_QTANGENT2, - ATTR_INDEX_MAX - }; - - // must match order of ATTR_INDEX enums - static const char *const attributeNames[] = - { - "attr_Position", - "attr_TexCoord0", - "attr_QTangent", - "attr_Color", - "attr_BoneFactors", - "attr_Position2", - "attr_QTangent2" - }; - - enum - { - ATTR_POSITION = BIT( ATTR_INDEX_POSITION ), - ATTR_TEXCOORD = BIT( ATTR_INDEX_TEXCOORD ), - ATTR_QTANGENT = BIT( ATTR_INDEX_QTANGENT ), - ATTR_COLOR = BIT( ATTR_INDEX_COLOR ), - - ATTR_BONE_FACTORS = BIT( ATTR_INDEX_BONE_FACTORS ), - - // for .md3 interpolation - ATTR_POSITION2 = BIT( ATTR_INDEX_POSITION2 ), - ATTR_QTANGENT2 = BIT( ATTR_INDEX_QTANGENT2 ), - - ATTR_INTERP_BITS = ATTR_POSITION2 | ATTR_QTANGENT2, - }; - - struct vboAttributeLayout_t - { - GLint numComponents; // how many components in a single attribute for a single vertex - GLenum componentType; // the input type for a single component - GLboolean normalize; // convert signed integers to the floating point range [-1, 1], and unsigned integers to the range [0, 1] - GLsizei stride; - GLsizei ofs; - GLsizei frameOffset; // for vertex animation, real offset computed as ofs + frame * frameOffset - }; - - enum class vboLayout_t - { - VBO_LAYOUT_CUSTOM, - VBO_LAYOUT_STATIC, - }; - - enum - { - ATTR_OPTION_NORMALIZE = BIT( 0 ), - ATTR_OPTION_HAS_FRAMES = BIT( 1 ), - }; - - struct vertexAttributeSpec_t - { - int attrIndex; - GLenum componentInputType; - GLenum componentStorageType; - const void *begin; - uint32_t numComponents; - uint32_t stride; - int attrOptions; - }; - - struct VBO_t - { - char name[ 96 ]; // only for debugging with /listVBOs - - uint32_t vertexesVBO; - - uint32_t vertexesSize; // total amount of memory data allocated for this vbo - - uint32_t vertexesNum; - uint32_t framesNum; // number of frames for vertex animation - - std::array attribs; // info for buffer manipulation - - vboLayout_t layout; - uint32_t attribBits; // Which attributes it has. Mostly for detecting errors - GLenum usage; - }; - - struct IBO_t - { - char name[ 96 ]; // only for debugging with /listVBOs - - uint32_t indexesVBO; - uint32_t indexesSize; // amount of memory data allocated for all triangles in bytes - uint32_t indexesNum; - }; - //=============================================================================== // Sorts commented "keyword only" will never be used unless the shader text has a `sort` keyword specifying it. @@ -2303,7 +2200,8 @@ enum Color::Color32Bit color2D; trRefEntity_t entity2D; // currentEntity will point at this when doing 2D rendering int currentMainFBO; - GLuint currentVAO; + GLuint currentVAO; + GLuint defaultVAO; }; struct visTest_t @@ -2702,8 +2600,6 @@ enum extern backEndState_t backEnd; extern trGlobals_t tr; - extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init - extern glconfig2_t glConfig2; extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init @@ -3026,13 +2922,8 @@ inline bool checkGLErrors() void GL_Viewport( GLint x, GLint y, GLsizei width, GLsizei height ); void GL_PolygonOffset( float factor, float units ); - void GL_CheckErrors_( const char *filename, int line ); - -#define GL_CheckErrors() do { if (!glConfig.smpActive) GL_CheckErrors_(__FILE__, __LINE__); } while (false) - void GL_State( uint32_t stateVector ); - void GL_VertexAttribsState( uint32_t stateBits ); - void GL_VertexAttribPointers( uint32_t attribBits ); + void GL_VertexAttribsState( uint32_t stateBits, const bool settingUpVAO = false ); void GL_Cull( cullType_t cullType ); void GL_TexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *data, bool isSRGB ); void GL_TexImage3D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *data, bool isSRGB ); @@ -3420,33 +3311,6 @@ void GLimp_LogComment_( std::string comment ); /* ============================================================ - VERTEX BUFFER OBJECTS, tr_vbo.c - - ============================================================ - */ - uint32_t R_ComponentSize( GLenum type ); - void R_CopyVertexAttribute( const vboAttributeLayout_t& attrib, const vertexAttributeSpec_t& spec, - uint32_t count, byte* interleavedData ); - - VBO_t *R_CreateStaticVBO( - Str::StringRef name, const vertexAttributeSpec_t *attrBegin, const vertexAttributeSpec_t *attrEnd, - uint32_t numVerts, uint32_t numFrames = 0 ); - - IBO_t *R_CreateStaticIBO( const char *name, glIndex_t *indexes, int numIndexes ); - IBO_t *R_CreateStaticIBO2( const char *name, int numTriangles, glIndex_t *indexes ); - - void R_BindVBO( VBO_t *vbo ); - void R_BindNullVBO(); - - void R_BindIBO( IBO_t *ibo ); - void R_BindNullIBO(); - - void R_InitVBOs(); - void R_ShutdownVBOs(); - - /* - ============================================================ - SCENE GENERATION, tr_scene.c ============================================================ diff --git a/src/engine/renderer/tr_model.cpp b/src/engine/renderer/tr_model.cpp index 2f80a8e487..c0bb2d21b7 100644 --- a/src/engine/renderer/tr_model.cpp +++ b/src/engine/renderer/tr_model.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // tr_models.c -- model loading and caching #include "tr_local.h" +#include "GLUtils.h" #define LL(x) x = LittleLong(x) #define LF(x) x = LittleFloat(x) diff --git a/src/engine/renderer/tr_model_iqm.cpp b/src/engine/renderer/tr_model_iqm.cpp index a3176a20c8..5fdc97e7e4 100644 --- a/src/engine/renderer/tr_model_iqm.cpp +++ b/src/engine/renderer/tr_model_iqm.cpp @@ -858,6 +858,11 @@ bool R_LoadIQModel( model_t *mod, const void *buffer, int filesize, // create IBO ibo = R_CreateStaticIBO( ( "IQM surface IBO " + name ).c_str(), ( glIndex_t* )IQModel->triangles, IQModel->num_triangles * 3 ); + + SetupVAOBuffers( vbo, ibo, + ATTR_BONE_FACTORS | ATTR_POSITION | ATTR_QTANGENT | ATTR_TEXCOORD + | ATTR_COLOR, + &vbo->VAO ); } else { vbo = nullptr; ibo = nullptr; diff --git a/src/engine/renderer/tr_model_md3.cpp b/src/engine/renderer/tr_model_md3.cpp index 728de4abe7..f66dd7c921 100644 --- a/src/engine/renderer/tr_model_md3.cpp +++ b/src/engine/renderer/tr_model_md3.cpp @@ -359,7 +359,13 @@ bool R_LoadMD3( model_t *mod, int lod, const void *buffer, const char *modName ) indexes[ f++ ] = surf->triangles[ j ].indexes[ k ]; } } - vboSurf->ibo = R_CreateStaticIBO2( ( "MD3 surface IBO " + name ).c_str(), surf->numTriangles, indexes ); + vboSurf->ibo = R_CreateStaticIBO( ( "MD3 surface IBO " + name ).c_str(), indexes, surf->numTriangles * 3 ); + + SetupVAOBuffers( vboSurf->vbo, vboSurf->ibo, + ATTR_TEXCOORD | ATTR_COLOR | ATTR_QTANGENT | ATTR_POSITION + | ATTR_POSITION2 | ATTR_QTANGENT2, + &vboSurf->vbo->VAO ); + vboSurf->vbo->dynamicVAO = true; ri.Hunk_FreeTempMemory(indexes); } diff --git a/src/engine/renderer/tr_model_skel.cpp b/src/engine/renderer/tr_model_skel.cpp index c38090cc8d..fce07e3e8e 100644 --- a/src/engine/renderer/tr_model_skel.cpp +++ b/src/engine/renderer/tr_model_skel.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // tr_models.c -- model loading and caching #include "tr_local.h" +#include "GLUtils.h" bool R_AddTriangleToVBOTriangleList( const skelTriangle_t *tri, int *numBoneReferences, int boneReferences[ MAX_BONES ] ) @@ -191,6 +192,10 @@ srfVBOMD5Mesh_t *R_GenerateMD5VBOSurface( vboSurf->ibo = R_CreateStaticIBO( ( "MD5 surface IBO " + surfName ).c_str(), indexes, indexesNum ); + SetupVAOBuffers( vboSurf->vbo, vboSurf->ibo, + ATTR_BONE_FACTORS | ATTR_POSITION | ATTR_QTANGENT | ATTR_TEXCOORD | ATTR_COLOR, + &vboSurf->vbo->VAO ); + ri.Hunk_FreeTempMemory( indexes ); ri.Hunk_FreeTempMemory( boneFactors ); ri.Hunk_FreeTempMemory( qtangents ); diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 14c46c5580..b7cdd8240b 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "gl_shader.h" #include "Material.h" #include "ShadeCommon.h" +#include "GLUtils.h" /* ================================================================================= @@ -2028,6 +2029,7 @@ void Tess_Clear() { tess.vboVertexSkinning = false; tess.vboVertexAnimation = false; + GL_BindVAO( backEnd.defaultVAO ); // clear shader so we can tell we don't have any unclosed surfaces tess.multiDrawPrimitives = 0; diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index a452b1a788..54327de8ee 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -20,7 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // tr_vbo.c -#include "tr_local.h" +#include "VBO.h" + #include "Material.h" #include "GeometryCache.h" #include "GLMemory.h" @@ -409,7 +410,7 @@ R_CreateIBO2 */ IBO_t *R_CreateStaticIBO( const char *name, glIndex_t *indexes, int numIndexes ) { - IBO_t *ibo; + IBO_t *ibo; if ( !numIndexes ) { @@ -444,39 +445,21 @@ IBO_t *R_CreateStaticIBO( const char *name, glIndex_t *indexes, int numIndexes ) return ibo; } -IBO_t *R_CreateStaticIBO2( const char *name, int numTriangles, glIndex_t *indexes ) -{ - IBO_t *ibo; - - if ( !numTriangles ) - { - return nullptr; - } +void SetupVAOBuffers( VBO_t* VBO, const IBO_t* IBO, const uint32_t stateBits, + GLVAO* VAO ) { + VAO->GenVAO(); - // make sure the render thread is stopped - R_SyncRenderThread(); - - ibo = ( IBO_t * ) ri.Hunk_Alloc( sizeof( *ibo ), ha_pref::h_low ); - tr.ibos.push_back( ibo ); + VAO->Bind(); - Q_strncpyz( ibo->name, name, sizeof( ibo->name ) ); - ibo->indexesNum = numTriangles * 3; - ibo->indexesSize = ibo->indexesNum * sizeof( glIndex_t ); + R_BindVBO( VBO ); - glGenBuffers( 1, &ibo->indexesVBO ); - R_BindIBO( ibo ); + GL_VertexAttribsState( stateBits, true ); - if( glConfig2.bufferStorageAvailable ) { - glBufferStorage( GL_ELEMENT_ARRAY_BUFFER, ibo->indexesSize, - indexes, 0 ); - } else { - glBufferData( GL_ELEMENT_ARRAY_BUFFER, ibo->indexesSize, - indexes, GL_STATIC_DRAW ); + if ( IBO ) { + VAO->SetIndexBuffer( IBO->indexesVBO ); } - R_BindNullIBO(); - - return ibo; + GL_BindVAO( backEnd.defaultVAO ); } /* @@ -632,6 +615,10 @@ static void R_InitGenericVBOs() { surface->ibo = R_CreateStaticIBO( "genericQuad_IBO", indexes, surface->numTriangles * 3 ); genericQuad->surface = ( surfaceType_t* ) surface; + SetupVAOBuffers( surface->vbo, surface->ibo, + ATTR_POSITION | ATTR_COLOR | ATTR_TEXCOORD, + &surface->vbo->VAO ); + tr.genericQuad = genericQuad; } @@ -690,6 +677,10 @@ static void R_InitTileVBO() tr.lighttileVBO = R_CreateStaticVBO( "lighttile_VBO", std::begin( attrs ), std::end( attrs ), w * h ); + SetupVAOBuffers( tr.lighttileVBO, nullptr, + ATTR_POSITION | ATTR_TEXCOORD, + &tr.lighttileVBO->VAO ); + ri.Hunk_FreeTempMemory( stf ); ri.Hunk_FreeTempMemory( xy ); } @@ -740,6 +731,9 @@ void R_InitVBOs() tess.ibo = R_CreateDynamicIBO( "tessVertexArray_IBO", SHADER_MAX_INDEXES ); } + SetupVAOBuffers( tess.vbo, tess.ibo, attribs, &tess.vbo->VAO ); + tess.vbo->dynamicVAO = true; + R_InitGenericVBOs(); R_InitTileVBO(); @@ -808,6 +802,7 @@ void R_ShutdownVBOs() if ( vbo->vertexesVBO ) { glDeleteBuffers( 1, &vbo->vertexesVBO ); + vbo->VAO.DelVAO(); } } diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 431dd48710..747ba2d470 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "renderer/tr_local.h" #include "renderer/DetectGLVendors.h" +#include "renderer/GLUtils.h" #pragma warning(push) #pragma warning(disable : 4125) // "decimal digit terminates octal escape sequence"