mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-09 23:02:02 +00:00
GL1 unified draw calls, 7
Changed "buffer" functions (vertex, single/mtex, color) to macros. Macros eliminate the function call overhead, resulting in faster execution times. Depending of the hardware, there might be a performance increase of almost 10%. This forced the buffer to be exposed as global. Not worth doing this for 2D elements though.
This commit is contained in:
parent
826f4816f6
commit
94c4bf2df7
7 changed files with 118 additions and 142 deletions
|
@ -29,33 +29,20 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
#define MAX_VERTICES 16384
|
||||
#define MAX_INDICES (MAX_VERTICES * 4)
|
||||
#define GLBUFFER_RESET vtx_ptr = idx_ptr = 0; gl_buf.vt = gl_buf.tx = gl_buf.cl = 0;
|
||||
|
||||
typedef struct // 832k aprox.
|
||||
{
|
||||
buffered_draw_t type;
|
||||
glbuffer_t gl_buf; // our drawing buffer, used globally
|
||||
|
||||
GLfloat
|
||||
vtx[MAX_VERTICES * 3], // vertexes
|
||||
tex[MAX_TEXTURE_UNITS][MAX_VERTICES * 2], // texture coords
|
||||
clr[MAX_VERTICES * 4]; // color components
|
||||
|
||||
GLushort
|
||||
idx[MAX_INDICES], // indices
|
||||
vtx_ptr, idx_ptr; // pointers for array positions
|
||||
|
||||
int texture[MAX_TEXTURE_UNITS];
|
||||
int flags; // entity flags
|
||||
float alpha;
|
||||
} glbuffer_t;
|
||||
|
||||
glbuffer_t gl_buf;
|
||||
|
||||
GLuint vt, tx, cl; // indices for arrays in gl_buf
|
||||
static GLushort vtx_ptr, idx_ptr; // pointers for array positions in gl_buf
|
||||
|
||||
extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
|
||||
|
||||
void
|
||||
R_ResetGLBuffer(void)
|
||||
{
|
||||
GLBUFFER_RESET
|
||||
}
|
||||
|
||||
void
|
||||
R_ApplyGLBuffer(void)
|
||||
{
|
||||
|
@ -64,7 +51,7 @@ R_ApplyGLBuffer(void)
|
|||
qboolean texture, mtex, alpha, color, alias, texenv_set;
|
||||
float fovy, dist;
|
||||
|
||||
if (gl_buf.vtx_ptr == 0 || gl_buf.idx_ptr == 0)
|
||||
if (vtx_ptr == 0 || idx_ptr == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -224,7 +211,7 @@ R_ApplyGLBuffer(void)
|
|||
}
|
||||
|
||||
// All set, we can finally draw
|
||||
glDrawElements(GL_TRIANGLES, gl_buf.idx_ptr, GL_UNSIGNED_SHORT, gl_buf.idx);
|
||||
glDrawElements(GL_TRIANGLES, idx_ptr, GL_UNSIGNED_SHORT, gl_buf.idx);
|
||||
// ... and now, turn back everything as it was
|
||||
|
||||
if (color)
|
||||
|
@ -277,7 +264,7 @@ R_ApplyGLBuffer(void)
|
|||
}
|
||||
}
|
||||
|
||||
gl_buf.vtx_ptr = gl_buf.idx_ptr = 0;
|
||||
GLBUFFER_RESET
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -304,46 +291,46 @@ R_Buffer2DQuad(GLfloat ul_vx, GLfloat ul_vy, GLfloat dr_vx, GLfloat dr_vy,
|
|||
{
|
||||
static const GLushort idx_max = MAX_INDICES - 7;
|
||||
static const GLushort vtx_max = MAX_VERTICES - 5;
|
||||
unsigned int i;
|
||||
|
||||
if (gl_buf.idx_ptr > idx_max || gl_buf.vtx_ptr > vtx_max)
|
||||
if (idx_ptr > idx_max || vtx_ptr > vtx_max)
|
||||
{
|
||||
R_ApplyGLBuffer();
|
||||
}
|
||||
|
||||
i = gl_buf.vtx_ptr * 2; // vertex index
|
||||
|
||||
// "Quad" = 2-triangle GL_TRIANGLE_FAN
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+1;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+2;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+2;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+3;
|
||||
gl_buf.idx[idx_ptr] = vtx_ptr;
|
||||
gl_buf.idx[idx_ptr+1] = vtx_ptr+1;
|
||||
gl_buf.idx[idx_ptr+2] = vtx_ptr+2;
|
||||
gl_buf.idx[idx_ptr+3] = vtx_ptr;
|
||||
gl_buf.idx[idx_ptr+4] = vtx_ptr+2;
|
||||
gl_buf.idx[idx_ptr+5] = vtx_ptr+3;
|
||||
idx_ptr += 6;
|
||||
|
||||
// up left corner coords
|
||||
gl_buf.vtx[i] = ul_vx;
|
||||
gl_buf.vtx[i+1] = ul_vy;
|
||||
gl_buf.vtx[gl_buf.vt] = ul_vx;
|
||||
gl_buf.vtx[gl_buf.vt+1] = ul_vy;
|
||||
// up right
|
||||
gl_buf.vtx[i+2] = dr_vx;
|
||||
gl_buf.vtx[i+3] = ul_vy;
|
||||
gl_buf.vtx[gl_buf.vt+2] = dr_vx;
|
||||
gl_buf.vtx[gl_buf.vt+3] = ul_vy;
|
||||
// down right
|
||||
gl_buf.vtx[i+4] = dr_vx;
|
||||
gl_buf.vtx[i+5] = dr_vy;
|
||||
gl_buf.vtx[gl_buf.vt+4] = dr_vx;
|
||||
gl_buf.vtx[gl_buf.vt+5] = dr_vy;
|
||||
// and finally, down left
|
||||
gl_buf.vtx[i+6] = ul_vx;
|
||||
gl_buf.vtx[i+7] = dr_vy;
|
||||
gl_buf.vtx[gl_buf.vt+6] = ul_vx;
|
||||
gl_buf.vtx[gl_buf.vt+7] = dr_vy;
|
||||
|
||||
gl_buf.tex[0][i] = ul_tx;
|
||||
gl_buf.tex[0][i+1] = ul_ty;
|
||||
gl_buf.tex[0][i+2] = dr_tx;
|
||||
gl_buf.tex[0][i+3] = ul_ty;
|
||||
gl_buf.tex[0][i+4] = dr_tx;
|
||||
gl_buf.tex[0][i+5] = dr_ty;
|
||||
gl_buf.tex[0][i+6] = ul_tx;
|
||||
gl_buf.tex[0][i+7] = dr_ty;
|
||||
gl_buf.tex[0][gl_buf.tx] = ul_tx;
|
||||
gl_buf.tex[0][gl_buf.tx+1] = ul_ty;
|
||||
gl_buf.tex[0][gl_buf.tx+2] = dr_tx;
|
||||
gl_buf.tex[0][gl_buf.tx+3] = ul_ty;
|
||||
gl_buf.tex[0][gl_buf.tx+4] = dr_tx;
|
||||
gl_buf.tex[0][gl_buf.tx+5] = dr_ty;
|
||||
gl_buf.tex[0][gl_buf.tx+6] = ul_tx;
|
||||
gl_buf.tex[0][gl_buf.tx+7] = dr_ty;
|
||||
|
||||
gl_buf.vtx_ptr += 4;
|
||||
vtx_ptr += 4;
|
||||
gl_buf.vt += 8;
|
||||
gl_buf.tx += 8;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -354,8 +341,8 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
|
|||
{
|
||||
int i;
|
||||
|
||||
if ( gl_buf.vtx_ptr + vertices_num >= MAX_VERTICES ||
|
||||
gl_buf.idx_ptr + ( (vertices_num - 2) * 3 ) >= MAX_INDICES )
|
||||
if ( vtx_ptr + vertices_num >= MAX_VERTICES ||
|
||||
idx_ptr + ( (vertices_num - 2) * 3 ) >= MAX_INDICES )
|
||||
{
|
||||
R_ApplyGLBuffer();
|
||||
}
|
||||
|
@ -365,9 +352,10 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
|
|||
case GL_TRIANGLE_FAN:
|
||||
for (i = 0; i < vertices_num-2; i++)
|
||||
{
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
|
||||
gl_buf.idx[idx_ptr] = vtx_ptr;
|
||||
gl_buf.idx[idx_ptr+1] = vtx_ptr+i+1;
|
||||
gl_buf.idx[idx_ptr+2] = vtx_ptr+i+2;
|
||||
idx_ptr += 3;
|
||||
}
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
|
@ -375,16 +363,17 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
|
|||
{
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
|
||||
gl_buf.idx[idx_ptr] = vtx_ptr+i;
|
||||
gl_buf.idx[idx_ptr+1] = vtx_ptr+i+1;
|
||||
gl_buf.idx[idx_ptr+2] = vtx_ptr+i+2;
|
||||
}
|
||||
else // backwards order
|
||||
{
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1;
|
||||
gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i;
|
||||
gl_buf.idx[idx_ptr] = vtx_ptr+i+2;
|
||||
gl_buf.idx[idx_ptr+1] = vtx_ptr+i+1;
|
||||
gl_buf.idx[idx_ptr+2] = vtx_ptr+i;
|
||||
}
|
||||
idx_ptr += 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -392,58 +381,6 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num)
|
|||
return;
|
||||
}
|
||||
|
||||
// These affect the functions that follow in this file
|
||||
vt = gl_buf.vtx_ptr * 3; // vertex index
|
||||
tx = gl_buf.vtx_ptr * 2; // texcoord index
|
||||
cl = gl_buf.vtx_ptr * 4; // color index
|
||||
|
||||
// R_BufferVertex() must be called as many times as vertices_num
|
||||
gl_buf.vtx_ptr += vertices_num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a single vertex to buffer
|
||||
*/
|
||||
void
|
||||
R_BufferVertex(GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
gl_buf.vtx[vt++] = x;
|
||||
gl_buf.vtx[vt++] = y;
|
||||
gl_buf.vtx[vt++] = z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds texture coordinates for color texture (no lightmap coords)
|
||||
*/
|
||||
void
|
||||
R_BufferSingleTex(GLfloat s, GLfloat t)
|
||||
{
|
||||
// tx should be set before this is called, by R_SetBufferIndices
|
||||
gl_buf.tex[0][tx++] = s;
|
||||
gl_buf.tex[0][tx++] = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds texture coordinates for color and lightmap
|
||||
*/
|
||||
void
|
||||
R_BufferMultiTex(GLfloat cs, GLfloat ct, GLfloat ls, GLfloat lt)
|
||||
{
|
||||
gl_buf.tex[0][tx] = cs;
|
||||
gl_buf.tex[0][tx+1] = ct;
|
||||
gl_buf.tex[1][tx] = ls;
|
||||
gl_buf.tex[1][tx+1] = lt;
|
||||
tx += 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds color components of vertex
|
||||
*/
|
||||
void
|
||||
R_BufferColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
|
||||
{
|
||||
gl_buf.clr[cl++] = r;
|
||||
gl_buf.clr[cl++] = g;
|
||||
gl_buf.clr[cl++] = b;
|
||||
gl_buf.clr[cl++] = a;
|
||||
// GLBUFFER_VERTEX() must be called as many times as vertices_num
|
||||
vtx_ptr += vertices_num;
|
||||
}
|
||||
|
|
|
@ -46,9 +46,9 @@ R_RenderDlight(dlight_t *light)
|
|||
vtx [ i ] = light->origin [ i ] - vpn [ i ] * rad;
|
||||
}
|
||||
|
||||
R_BufferVertex( vtx[0], vtx[1], vtx[2] );
|
||||
R_BufferColor( light->color[0] * 0.2, light->color[1] * 0.2,
|
||||
light->color[2] * 0.2, 1 );
|
||||
GLBUFFER_VERTEX( vtx[0], vtx[1], vtx[2] )
|
||||
GLBUFFER_COLOR( light->color[0] * 0.2, light->color[1] * 0.2,
|
||||
light->color[2] * 0.2, 1 )
|
||||
|
||||
for ( i = 16; i >= 0; i-- )
|
||||
{
|
||||
|
@ -60,8 +60,8 @@ R_RenderDlight(dlight_t *light)
|
|||
+ vup [ j ] * sin( a ) * rad;
|
||||
}
|
||||
|
||||
R_BufferVertex( vtx[0], vtx[1], vtx[2] );
|
||||
R_BufferColor( 0, 0, 0, 1 );
|
||||
GLBUFFER_VERTEX( vtx[0], vtx[1], vtx[2] )
|
||||
GLBUFFER_COLOR( 0, 0, 0, 1 )
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,8 @@ void LM_FreeLightmapBuffers(void);
|
|||
void Scrap_Free(void);
|
||||
void Scrap_Init(void);
|
||||
|
||||
extern void R_ResetGLBuffer(void);
|
||||
|
||||
void
|
||||
R_RotateForEntity(entity_t *e)
|
||||
{
|
||||
|
@ -1641,6 +1643,7 @@ RI_Init(void)
|
|||
Mod_Init();
|
||||
R_InitParticleTexture();
|
||||
Draw_InitLocal();
|
||||
R_ResetGLBuffer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -169,11 +169,11 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
|||
index_xyz = order[2];
|
||||
order += 3;
|
||||
|
||||
R_BufferVertex(s_lerped[index_xyz][0],
|
||||
s_lerped[index_xyz][1], s_lerped[index_xyz][2]);
|
||||
GLBUFFER_VERTEX(s_lerped[index_xyz][0],
|
||||
s_lerped[index_xyz][1], s_lerped[index_xyz][2])
|
||||
|
||||
R_BufferColor(shadelight[0], shadelight[1],
|
||||
shadelight[2], alpha);
|
||||
GLBUFFER_COLOR(shadelight[0], shadelight[1],
|
||||
shadelight[2], alpha)
|
||||
}
|
||||
while (--count);
|
||||
}
|
||||
|
@ -191,13 +191,13 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
|
|||
/* normals and vertexes come from the frame list */
|
||||
l = shadedots[verts[index_xyz].lightnormalindex];
|
||||
|
||||
R_BufferVertex(s_lerped[index_xyz][0],
|
||||
s_lerped[index_xyz][1], s_lerped[index_xyz][2]);
|
||||
GLBUFFER_VERTEX(s_lerped[index_xyz][0],
|
||||
s_lerped[index_xyz][1], s_lerped[index_xyz][2])
|
||||
|
||||
R_BufferSingleTex(tex[0], tex[1]);
|
||||
GLBUFFER_SINGLETEX(tex[0], tex[1])
|
||||
|
||||
R_BufferColor(l * shadelight[0], l * shadelight[1],
|
||||
l * shadelight[2], alpha);
|
||||
GLBUFFER_COLOR(l * shadelight[0], l * shadelight[1],
|
||||
l * shadelight[2], alpha)
|
||||
}
|
||||
while (--count);
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ R_DrawAliasShadow(entity_t *currententity, dmdl_t *paliashdr, int posenum)
|
|||
point[1] -= shadevector[1] * (point[2] + lheight);
|
||||
point[2] = height;
|
||||
|
||||
R_BufferVertex( point[0], point[1], point[2] );
|
||||
GLBUFFER_VERTEX( point[0], point[1], point[2] )
|
||||
|
||||
order += 3;
|
||||
}
|
||||
|
|
|
@ -69,8 +69,8 @@ R_DrawGLPoly(msurface_t *fa)
|
|||
|
||||
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
|
||||
{
|
||||
R_BufferVertex(v[0], v[1], v[2]);
|
||||
R_BufferSingleTex(v[3] + scroll, v[4]);
|
||||
GLBUFFER_VERTEX( v[0], v[1], v[2] )
|
||||
GLBUFFER_SINGLETEX( v[3] + scroll, v[4] )
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,8 +594,8 @@ R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
|
|||
|
||||
for (i = 0; i < nv; i++, v += VERTEXSIZE)
|
||||
{
|
||||
R_BufferVertex( v[0], v[1], v[2] );
|
||||
R_BufferMultiTex( v[3] + scroll, v[4], v[5], v[6] );
|
||||
GLBUFFER_VERTEX( v[0], v[1], v[2] )
|
||||
GLBUFFER_MULTITEX( v[3] + scroll, v[4], v[5], v[6] )
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -310,8 +310,8 @@ R_EmitWaterPolys(msurface_t *fa)
|
|||
s = os + r_turbsin [ (int) ( ( ot * 0.125 + rdt ) * TURBSCALE ) & 255 ] + scroll;
|
||||
t = ot + r_turbsin [ (int) ( ( os * 0.125 + rdt ) * TURBSCALE ) & 255 ];
|
||||
|
||||
R_BufferVertex( v[0], v[1], v[2] );
|
||||
R_BufferSingleTex( s * ( 1.0 / 64 ), t * ( 1.0 / 64 ) );
|
||||
GLBUFFER_VERTEX( v[0], v[1], v[2] )
|
||||
GLBUFFER_SINGLETEX( s * ( 1.0 / 64 ), t * ( 1.0 / 64 ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
#define MAX_TEXTURE_UNITS 2
|
||||
#define GL_LIGHTMAP_FORMAT GL_RGBA
|
||||
|
||||
// GL buffer definitions
|
||||
#define MAX_VERTICES 16384
|
||||
#define MAX_INDICES (MAX_VERTICES * 4)
|
||||
|
||||
/* up / down */
|
||||
#define PITCH 0
|
||||
|
||||
|
@ -118,10 +122,29 @@ typedef enum
|
|||
buf_shadow
|
||||
} buffered_draw_t;
|
||||
|
||||
typedef struct // 832k aprox.
|
||||
{
|
||||
buffered_draw_t type;
|
||||
|
||||
GLfloat
|
||||
vtx[MAX_VERTICES * 3], // vertexes
|
||||
tex[MAX_TEXTURE_UNITS][MAX_VERTICES * 2], // texture coords
|
||||
clr[MAX_VERTICES * 4]; // color components
|
||||
|
||||
GLushort idx[MAX_INDICES]; // indices for the draw call
|
||||
|
||||
GLuint vt, tx, cl; // indices for GLfloat arrays above
|
||||
|
||||
int texture[MAX_TEXTURE_UNITS];
|
||||
int flags; // entity flags
|
||||
float alpha;
|
||||
} glbuffer_t;
|
||||
|
||||
#include "model.h"
|
||||
|
||||
void R_SetDefaultState(void);
|
||||
|
||||
extern glbuffer_t gl_buf;
|
||||
extern float gldepthmin, gldepthmax;
|
||||
|
||||
extern image_t gltextures[MAX_GLTEXTURES];
|
||||
|
@ -291,15 +314,28 @@ void R_TextureAlphaMode(char *string);
|
|||
void R_TextureSolidMode(char *string);
|
||||
int Scrap_AllocBlock(int w, int h, int *x, int *y);
|
||||
|
||||
// GL buffer operations
|
||||
|
||||
#define GLBUFFER_VERTEX(X, Y, Z) \
|
||||
gl_buf.vtx[gl_buf.vt] = X; gl_buf.vtx[gl_buf.vt+1] = Y; \
|
||||
gl_buf.vtx[gl_buf.vt+2] = Z; gl_buf.vt += 3;
|
||||
|
||||
#define GLBUFFER_SINGLETEX(S, T) \
|
||||
gl_buf.tex[0][gl_buf.tx] = S; gl_buf.tex[0][gl_buf.tx+1] = T; gl_buf.tx += 2;
|
||||
|
||||
#define GLBUFFER_MULTITEX(CS, CT, LS, LT) \
|
||||
gl_buf.tex[0][gl_buf.tx] = CS; gl_buf.tex[0][gl_buf.tx+1] = CT; \
|
||||
gl_buf.tex[1][gl_buf.tx] = LS; gl_buf.tex[1][gl_buf.tx+1] = LT; gl_buf.tx += 2;
|
||||
|
||||
#define GLBUFFER_COLOR(R, G, B, A) \
|
||||
gl_buf.clr[gl_buf.cl] = R; gl_buf.clr[gl_buf.cl+1] = G; \
|
||||
gl_buf.clr[gl_buf.cl+2] = B; gl_buf.clr[gl_buf.cl+3] = A; gl_buf.cl += 4;
|
||||
|
||||
void R_ApplyGLBuffer(void);
|
||||
void R_UpdateGLBuffer(buffered_draw_t type, int colortex, int lighttex, int flags, float alpha);
|
||||
void R_Buffer2DQuad(GLfloat ul_vx, GLfloat ul_vy, GLfloat dr_vx, GLfloat dr_vy,
|
||||
GLfloat ul_tx, GLfloat ul_ty, GLfloat dr_tx, GLfloat dr_ty);
|
||||
void R_SetBufferIndices(GLenum type, GLuint vertices_num);
|
||||
void R_BufferVertex(GLfloat x, GLfloat y, GLfloat z);
|
||||
void R_BufferSingleTex(GLfloat s, GLfloat t);
|
||||
void R_BufferMultiTex(GLfloat cs, GLfloat ct, GLfloat ls, GLfloat lt);
|
||||
void R_BufferColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
|
||||
#ifdef DEBUG
|
||||
void glCheckError_(const char *file, const char *function, int line);
|
||||
|
|
Loading…
Reference in a new issue