Skip to content

Commit

Permalink
OpenGL1: Use vertex arrays instead of glBegin
Browse files Browse the repository at this point in the history
This is loosely based on the OpenPandora OpenGL ES port by ptitSeb.
Some of the changes were backported from the opengl2 renderer.

It runs faster, at least on modern hardware, and is requires for
OpenGL ES support.

r_primatives cvar values 1 and 3 still use glBegin as they have to use
it by definition.
  • Loading branch information
zturtleman committed Nov 9, 2019
1 parent dc0c3e7 commit 1a7ad9d
Show file tree
Hide file tree
Showing 13 changed files with 418 additions and 164 deletions.
5 changes: 5 additions & 0 deletions code/qcommon/q_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,11 @@ typedef struct {
#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0)
#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z))

#define Vector2Set(v, x, y) ((v)[0]=(x), (v)[1]=(y))
#define Vector2Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1])

#define Vector4Set(v, x, y, z, w) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z), (v)[3]=(w))
#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])

#define Byte4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
Expand Down
80 changes: 60 additions & 20 deletions code/renderergl1/tr_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,45 @@ void RB_SetGL2D (void) {
backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
}

/*
================
RB_InstantQuad2
================
*/
void RB_InstantQuad2( vec4_t quadVerts[4], vec2_t texCoords[2] ) {
glIndex_t indexes[6];

qglDisableClientState( GL_COLOR_ARRAY );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );

qglTexCoordPointer( 2, GL_FLOAT, 0, texCoords );
qglVertexPointer( 3, GL_FLOAT, 16, quadVerts );

indexes[0] = 0;
indexes[1] = 1;
indexes[2] = 2;
indexes[3] = 0;
indexes[4] = 2;
indexes[5] = 3;

R_DrawElements( 6, indexes );
}

/*
================
RB_InstantQuad
===============-
*/
void RB_InstantQuad( vec4_t quadVerts[4] ) {
vec2_t texCoords[4] = {
{ 0, 0 },
{ 1, 0 },
{ 1, 1 },
{ 0, 1 }
};

RB_InstantQuad2( quadVerts, texCoords );
}

/*
=============
Expand All @@ -732,6 +771,8 @@ Used for cinematics.
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
int i, j;
int start, end;
vec4_t quadVerts[4];
vec2_t texCoords[4];

if ( !tr.registered ) {
return;
Expand Down Expand Up @@ -771,16 +812,17 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *

qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );

qglBegin (GL_QUADS);
qglTexCoord2f ( 0.5f / cols, 0.5f / rows );
qglVertex2f (x, y);
qglTexCoord2f ( ( cols - 0.5f ) / cols , 0.5f / rows );
qglVertex2f (x+w, y);
qglTexCoord2f ( ( cols - 0.5f ) / cols, ( rows - 0.5f ) / rows );
qglVertex2f (x+w, y+h);
qglTexCoord2f ( 0.5f / cols, ( rows - 0.5f ) / rows );
qglVertex2f (x, y+h);
qglEnd ();
Vector4Set( quadVerts[0], x, y, 0.0f, 1.0f );
Vector4Set( quadVerts[1], x + w, y, 0.0f, 1.0f );
Vector4Set( quadVerts[2], x + w, y + h, 0.0f, 1.0f );
Vector4Set( quadVerts[3], x, y + h, 0.0f, 1.0f );

Vector2Set( texCoords[0], 0.5f / cols, 0.5f / rows );
Vector2Set( texCoords[1], (cols - 0.5f) / cols, 0.5f / rows );
Vector2Set( texCoords[2], (cols - 0.5f) / cols, (rows - 0.5f) / rows );
Vector2Set( texCoords[3], 0.5f / cols, (rows - 0.5f) / rows );

RB_InstantQuad2( quadVerts, texCoords );
}

void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
Expand Down Expand Up @@ -963,6 +1005,7 @@ void RB_ShowImages( void ) {
image_t *image;
float x, y, w, h;
int start, end;
vec4_t quadVerts[4];

if ( !backEnd.projection2D ) {
RB_SetGL2D();
Expand All @@ -989,16 +1032,13 @@ void RB_ShowImages( void ) {
}

GL_Bind( image );
qglBegin (GL_QUADS);
qglTexCoord2f( 0, 0 );
qglVertex2f( x, y );
qglTexCoord2f( 1, 0 );
qglVertex2f( x + w, y );
qglTexCoord2f( 1, 1 );
qglVertex2f( x + w, y + h );
qglTexCoord2f( 0, 1 );
qglVertex2f( x, y + h );
qglEnd();

Vector4Set( quadVerts[0], x, y, 0, 1 );
Vector4Set( quadVerts[1], x + w, y, 0, 1 );
Vector4Set( quadVerts[2], x + w, y + h, 0, 1 );
Vector4Set( quadVerts[3], x, y + h, 0, 1 );

RB_InstantQuad( quadVerts );
}

qglFinish();
Expand Down
6 changes: 5 additions & 1 deletion code/renderergl1/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -1224,10 +1224,12 @@ typedef struct stageVars
} stageVars_t;


// xyz index SHADER_MAX_VERTEXES-1 is used to check for overflow
// xyz index >= SHADER_MAX_VERTEXES are used for DrawNormals() and RB_ShadowTessEnd()
typedef struct shaderCommands_s
{
glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16);
vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16);
vec4_t xyz[SHADER_MAX_VERTEXES*2] QALIGN(16);
vec4_t normal[SHADER_MAX_VERTEXES] QALIGN(16);
vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16);
color4ub_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16);
Expand Down Expand Up @@ -1266,6 +1268,8 @@ void RB_StageIteratorLightmappedMultitexture( void );

void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color );
void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, float s1, float t1, float s2, float t2 );
void RB_InstantQuad( vec4_t quadVerts[4] );
void RB_InstantQuad2( vec4_t quadVerts[4], vec2_t texCoords[4] );

void RB_ShowImages( void );

Expand Down
33 changes: 20 additions & 13 deletions code/renderergl1/tr_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1299,29 +1299,36 @@ R_DebugPolygon
================
*/
void R_DebugPolygon( int color, int numPoints, float *points ) {
int i;
if ( numPoints < 3 ) {
ri.Printf( PRINT_WARNING, "Debug polygon with color 0x%08X only has %d points (must have at least 3)\n", color, numPoints );
return;
}

GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
qglDisableClientState( GL_COLOR_ARRAY );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

// draw solid shade
qglVertexPointer( 3, GL_FLOAT, 0, points );

qglColor3f( color&1, (color>>1)&1, (color>>2)&1 );
qglBegin( GL_POLYGON );
for ( i = 0 ; i < numPoints ; i++ ) {
qglVertex3fv( points + i * 3 );
if (qglLockArraysEXT) {
qglLockArraysEXT(0, numPoints);
GLimp_LogComment( "glLockArraysEXT\n" );
}
qglEnd();

// draw solid shade
qglColor3f( color&1, (color>>1)&1, (color>>2)&1 );
qglDrawArrays( GL_TRIANGLE_FAN, 0, numPoints );

// draw wireframe outline
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
qglDepthRange( 0, 0 );
qglColor3f( 1, 1, 1 );
qglBegin( GL_POLYGON );
for ( i = 0 ; i < numPoints ; i++ ) {
qglVertex3fv( points + i * 3 );
}
qglEnd();
qglDrawArrays( GL_LINE_LOOP, 0, numPoints );
qglDepthRange( 0, 1 );

if (qglUnlockArraysEXT) {
qglUnlockArraysEXT();
GLimp_LogComment( "glUnlockArraysEXT\n" );
}
}

/*
Expand Down
52 changes: 43 additions & 9 deletions code/renderergl1/tr_shade.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,23 +254,39 @@ Draws triangle outlines for debugging
================
*/
static void DrawTris (shaderCommands_t *input) {
glIndex_t lineIndexes[SHADER_MAX_INDEXES*2];
int i, numTris;

GL_Bind( tr.whiteImage );
qglColor3f (1,1,1);

GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
GL_State( GLS_DEPTHMASK_TRUE );
qglDepthRange( 0, 0 );

qglDisableClientState (GL_COLOR_ARRAY);
qglDisableClientState (GL_TEXTURE_COORD_ARRAY);

// convert triangles to lines
numTris = tess.numIndexes / 3;
for (i = 0 ; i < numTris; i++) {
lineIndexes[i*6+0] = input->indexes[i*3+0];
lineIndexes[i*6+1] = input->indexes[i*3+1];

lineIndexes[i*6+2] = input->indexes[i*3+1];
lineIndexes[i*6+3] = input->indexes[i*3+2];

lineIndexes[i*6+4] = input->indexes[i*3+2];
lineIndexes[i*6+5] = input->indexes[i*3+0];
}

qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD

if (qglLockArraysEXT) {
qglLockArraysEXT(0, input->numVertexes);
GLimp_LogComment( "glLockArraysEXT\n" );
}

R_DrawElements( input->numIndexes, input->indexes );
qglDrawElements( GL_LINES, numTris*6, GL_INDEX_TYPE, lineIndexes );

if (qglUnlockArraysEXT) {
qglUnlockArraysEXT();
Expand All @@ -288,23 +304,41 @@ Draws vertex normals for debugging
================
*/
static void DrawNormals (shaderCommands_t *input) {
glIndex_t lineIndexes[SHADER_MAX_INDEXES*2];
int i;
vec3_t temp;

GL_Bind( tr.whiteImage );
qglColor3f (1,1,1);
qglDepthRange( 0, 0 ); // never occluded
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
GL_State( GLS_DEPTHMASK_TRUE );

qglDisableClientState (GL_COLOR_ARRAY);
qglDisableClientState (GL_TEXTURE_COORD_ARRAY);

qglBegin (GL_LINES);
for (i = 0 ; i < input->numVertexes ; i++) {
qglVertex3fv (input->xyz[i]);
VectorMA (input->xyz[i], 2, input->normal[i], temp);
qglVertex3fv (temp);
VectorMA( input->xyz[i], 2, input->normal[i], input->xyz[i + input->numVertexes] );

lineIndexes[i*2] = i;
lineIndexes[i*2+1] = i + input->numVertexes;
}

qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD

if (qglLockArraysEXT) {
qglLockArraysEXT(0, input->numVertexes * 2);
GLimp_LogComment( "glLockArraysEXT\n" );
}
qglEnd ();

qglDrawElements( GL_LINES, input->numVertexes * 2, GL_INDEX_TYPE, lineIndexes );

if (qglUnlockArraysEXT) {
qglUnlockArraysEXT();
GLimp_LogComment( "glUnlockArraysEXT\n" );
}
qglDepthRange( 0, 1 );

// FIXME: kind of ugly to have to clear this to avoid overflow detection.
memset( input->xyz[SHADER_MAX_VERTEXES-1], 0, sizeof ( input->xyz[0] ) );
}

/*
Expand Down
Loading

0 comments on commit 1a7ad9d

Please sign in to comment.