From 13d224cfc60c06a1219bcbba0b2e0295300b129f Mon Sep 17 00:00:00 2001 From: James Canete Date: Mon, 16 Apr 2012 09:04:26 +0000 Subject: [PATCH] Use GL_EXT_draw_range_elements --- reaction/Reaction-ChangeLog | 1 + reaction/code/renderergl2/qgl.h | 3 +++ reaction/code/renderergl2/tr_extensions.c | 23 ++++++++++++++++++++- reaction/code/renderergl2/tr_init.c | 4 +++- reaction/code/renderergl2/tr_local.h | 3 +++ reaction/code/renderergl2/tr_shade.c | 25 ++++++++++++++++------- reaction/code/renderergl2/tr_surface.c | 9 +++++--- 7 files changed, 56 insertions(+), 12 deletions(-) diff --git a/reaction/Reaction-ChangeLog b/reaction/Reaction-ChangeLog index 57122b59..dd3fcf46 100644 --- a/reaction/Reaction-ChangeLog +++ b/reaction/Reaction-ChangeLog @@ -1,3 +1,4 @@ +- Use GL_ext_draw_range_elements - Reserve FBOs before shaders, as recommended in nvidia docs - Minor tweak in VBO allocation. - Update tr_font.c to ioq3 latest (r2232) diff --git a/reaction/code/renderergl2/qgl.h b/reaction/code/renderergl2/qgl.h index 5c7e9190..298e9669 100644 --- a/reaction/code/renderergl2/qgl.h +++ b/reaction/code/renderergl2/qgl.h @@ -39,6 +39,9 @@ extern void (APIENTRYP qglMultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat extern void (APIENTRYP qglLockArraysEXT) (GLint first, GLsizei count); extern void (APIENTRYP qglUnlockArraysEXT) (void); +// GL_EXT_draw_range_elements +extern void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + // GL_EXT_multi_draw_arrays extern void (APIENTRY * qglMultiDrawArraysEXT) (GLenum, GLint *, GLsizei *, GLsizei); extern void (APIENTRY * qglMultiDrawElementsEXT) (GLenum, const GLsizei *, GLenum, const GLvoid **, GLsizei); diff --git a/reaction/code/renderergl2/tr_extensions.c b/reaction/code/renderergl2/tr_extensions.c index a36d3019..5b34026c 100644 --- a/reaction/code/renderergl2/tr_extensions.c +++ b/reaction/code/renderergl2/tr_extensions.c @@ -29,7 +29,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" - +// GL_EXT_draw_range_elements +void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + // GL_EXT_multi_draw_arrays void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); @@ -187,6 +189,25 @@ void GLimp_InitExtraExtensions() char *extension; const char* result[3] = { "...ignoring %s\n", "...using %s\n", "...%s not found\n" }; + // GL_EXT_draw_range_elements + extension = "GL_EXT_draw_range_elements"; + glRefConfig.drawRangeElements = qfalse; + qglMultiDrawArraysEXT = NULL; + qglMultiDrawElementsEXT = NULL; + if( GLimp_HaveExtension( extension ) ) + { + qglDrawRangeElementsEXT = (PFNGLMULTIDRAWARRAYSEXTPROC) SDL_GL_GetProcAddress("glDrawRangeElementsEXT"); + + if ( r_ext_draw_range_elements->integer) + glRefConfig.drawRangeElements = qtrue; + + ri.Printf(PRINT_ALL, result[glRefConfig.drawRangeElements], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } + // GL_EXT_multi_draw_arrays extension = "GL_EXT_multi_draw_arrays"; glRefConfig.multiDrawArrays = qfalse; diff --git a/reaction/code/renderergl2/tr_init.c b/reaction/code/renderergl2/tr_init.c index a2f8cccd..464bd067 100644 --- a/reaction/code/renderergl2/tr_init.c +++ b/reaction/code/renderergl2/tr_init.c @@ -96,6 +96,7 @@ cvar_t *r_ext_texture_env_add; cvar_t *r_ext_texture_filter_anisotropic; cvar_t *r_ext_max_anisotropy; +cvar_t *r_ext_draw_range_elements; cvar_t *r_ext_multi_draw_arrays; cvar_t *r_ext_framebuffer_object; cvar_t *r_ext_texture_float; @@ -893,7 +894,7 @@ void GL_SetDefaultState( void ) GL_TextureMode( r_textureMode->string ); GL_TexEnv( GL_MODULATE ); - qglShadeModel( GL_SMOOTH ); + //qglShadeModel( GL_SMOOTH ); qglDepthFunc( GL_LEQUAL ); // @@ -1088,6 +1089,7 @@ void R_Register( void ) r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH); + r_ext_draw_range_elements = ri.Cvar_Get( "r_ext_draw_range_elements", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_multi_draw_arrays = ri.Cvar_Get( "r_ext_multi_draw_arrays", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH); diff --git a/reaction/code/renderergl2/tr_local.h b/reaction/code/renderergl2/tr_local.h index aff39319..381baca0 100644 --- a/reaction/code/renderergl2/tr_local.h +++ b/reaction/code/renderergl2/tr_local.h @@ -1602,6 +1602,7 @@ typedef enum { // We can't change glConfig_t without breaking DLL/vms compatibility, so // store extensions we have here. typedef struct { + qboolean drawRangeElements; qboolean multiDrawArrays; qboolean occlusionQuery; @@ -1930,6 +1931,7 @@ extern cvar_t *r_ext_texture_env_add; extern cvar_t *r_ext_texture_filter_anisotropic; extern cvar_t *r_ext_max_anisotropy; +extern cvar_t *r_ext_draw_range_elements; extern cvar_t *r_ext_multi_draw_arrays; extern cvar_t *r_ext_framebuffer_object; extern cvar_t *r_ext_texture_float; @@ -2268,6 +2270,7 @@ void RB_EndSurface(void); void RB_CheckOverflow( int verts, int indexes ); #define RB_CHECKOVERFLOW(v,i) if (tess.numVertexes + (v) >= SHADER_MAX_VERTEXES || tess.numIndexes + (i) >= SHADER_MAX_INDEXES ) {RB_CheckOverflow(v,i);} +void R_DrawElementsVBO( int numIndexes, int firstIndex ); void RB_StageIteratorGeneric( void ); void RB_StageIteratorSky( void ); void RB_StageIteratorVertexLitTexture( void ); diff --git a/reaction/code/renderergl2/tr_shade.c b/reaction/code/renderergl2/tr_shade.c index ef339d20..94c076f5 100644 --- a/reaction/code/renderergl2/tr_shade.c +++ b/reaction/code/renderergl2/tr_shade.c @@ -38,15 +38,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ================== R_DrawElements -Optionally performs our own glDrawElements that looks for strip conditions -instead of using the single glDrawElements call that may be inefficient -without compiled vertex arrays. ================== */ -static void R_DrawElementsVBO( int numIndexes, int firstIndex ) +void R_DrawElementsVBO( int numIndexes, int firstIndex ) { - qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); + if (glRefConfig.drawRangeElements) + qglDrawRangeElementsEXT(GL_TRIANGLES, 0, numIndexes, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); + else + qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(GL_INDEX_TYPE))); + } @@ -60,9 +61,19 @@ static void R_DrawMultiElementsVBO( int multiDrawPrimitives, const GLvoid **mult { int i; - for (i = 0; i < multiDrawPrimitives; i++) + if (glRefConfig.drawRangeElements) { - qglDrawElements(GL_TRIANGLES, multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]); + for (i = 0; i < multiDrawPrimitives; i++) + { + qglDrawRangeElementsEXT(GL_TRIANGLES, 0, multiDrawNumIndexes[i], multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]); + } + } + else + { + for (i = 0; i < multiDrawPrimitives; i++) + { + qglDrawElements(GL_TRIANGLES, multiDrawNumIndexes[i], GL_INDEX_TYPE, multiDrawFirstIndex[i]); + } } } } diff --git a/reaction/code/renderergl2/tr_surface.c b/reaction/code/renderergl2/tr_surface.c index c9cc7b09..538c4218 100644 --- a/reaction/code/renderergl2/tr_surface.c +++ b/reaction/code/renderergl2/tr_surface.c @@ -77,7 +77,8 @@ void RB_CheckVBOandIBO(VBO_t *vbo, IBO_t *ibo) R_BindIBO(ibo); } - tess.useInternalVBO = qfalse; + if (vbo != tess.vbo && ibo != tess.ibo) + tess.useInternalVBO = qfalse; } @@ -224,7 +225,7 @@ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4], vec4_t color, sha GLSL_SetUniformVec2(sp, TEXTURECOLOR_UNIFORM_INVTEXRES, invTexRes); GLSL_SetUniformVec2(sp, TEXTURECOLOR_UNIFORM_AUTOEXPOSUREMINMAX, tr.autoExposureMinMax); - qglDrawElements(GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(0)); + R_DrawElementsVBO(tess.numIndexes, tess.firstIndex); tess.numIndexes = 0; tess.numVertexes = 0; @@ -363,6 +364,8 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles, glIndex_t *index; float *color; + RB_CheckVBOandIBO(tess.vbo, tess.ibo); + RB_CHECKOVERFLOW( numVerts, numTriangles * 3 ); tri = triangles; @@ -647,7 +650,7 @@ static void RB_SurfaceBeam( void ) GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color); } - qglDrawElements(GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(tess.firstIndex)); + R_DrawElementsVBO(tess.numIndexes, tess.firstIndex); tess.numIndexes = 0; tess.numVertexes = 0;