#include "quakedef.h"
#include "cl_collision.h"
-// on GLES we have to use some proper #define's
-#ifndef GL_FRAMEBUFFER
-#define GL_FRAMEBUFFER 0x8D40
-#define GL_DEPTH_ATTACHMENT 0x8D00
-#define GL_COLOR_ATTACHMENT0 0x8CE0
-#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
-#endif
-#ifndef GL_COLOR_ATTACHMENT1
-#define GL_COLOR_ATTACHMENT1 0x8CE1
-#define GL_COLOR_ATTACHMENT2 0x8CE2
-#define GL_COLOR_ATTACHMENT3 0x8CE3
-#define GL_COLOR_ATTACHMENT4 0x8CE4
-#define GL_COLOR_ATTACHMENT5 0x8CE5
-#define GL_COLOR_ATTACHMENT6 0x8CE6
-#define GL_COLOR_ATTACHMENT7 0x8CE7
-#define GL_COLOR_ATTACHMENT8 0x8CE8
-#define GL_COLOR_ATTACHMENT9 0x8CE9
-#define GL_COLOR_ATTACHMENT10 0x8CEA
-#define GL_COLOR_ATTACHMENT11 0x8CEB
-#define GL_COLOR_ATTACHMENT12 0x8CEC
-#define GL_COLOR_ATTACHMENT13 0x8CED
-#define GL_COLOR_ATTACHMENT14 0x8CEE
-#define GL_COLOR_ATTACHMENT15 0x8CEF
-#endif
-#ifndef GL_ARRAY_BUFFER
-#define GL_ARRAY_BUFFER 0x8892
-#define GL_ELEMENT_ARRAY_BUFFER 0x8893
-#endif
-#ifndef GL_TEXTURE0
-#define GL_TEXTURE0 0x84C0
-#define GL_TEXTURE1 0x84C1
-#define GL_TEXTURE2 0x84C2
-#define GL_TEXTURE3 0x84C3
-#define GL_TEXTURE4 0x84C4
-#define GL_TEXTURE5 0x84C5
-#define GL_TEXTURE6 0x84C6
-#define GL_TEXTURE7 0x84C7
-#define GL_TEXTURE8 0x84C8
-#define GL_TEXTURE9 0x84C9
-#define GL_TEXTURE10 0x84CA
-#define GL_TEXTURE11 0x84CB
-#define GL_TEXTURE12 0x84CC
-#define GL_TEXTURE13 0x84CD
-#define GL_TEXTURE14 0x84CE
-#define GL_TEXTURE15 0x84CF
-#define GL_TEXTURE16 0x84D0
-#define GL_TEXTURE17 0x84D1
-#define GL_TEXTURE18 0x84D2
-#define GL_TEXTURE19 0x84D3
-#define GL_TEXTURE20 0x84D4
-#define GL_TEXTURE21 0x84D5
-#define GL_TEXTURE22 0x84D6
-#define GL_TEXTURE23 0x84D7
-#define GL_TEXTURE24 0x84D8
-#define GL_TEXTURE25 0x84D9
-#define GL_TEXTURE26 0x84DA
-#define GL_TEXTURE27 0x84DB
-#define GL_TEXTURE28 0x84DC
-#define GL_TEXTURE29 0x84DD
-#define GL_TEXTURE30 0x84DE
-#define GL_TEXTURE31 0x84DF
-#endif
-
-#ifndef GL_TEXTURE_3D
-#define GL_TEXTURE_3D 0x806F
-#endif
-#ifndef GL_TEXTURE_CUBE_MAP
-#define GL_TEXTURE_CUBE_MAP 0x8513
-#endif
+#define MAX_RENDERTARGETS 4
+cvar_t gl_debug = {CVAR_CLIENT, "gl_debug", "0", "enables OpenGL debug output, 0 = off, 1 = HIGH severity only, 2 = also MEDIUM severity, 3 = also LOW severity messages. (note: enabling may not take effect until vid_restart on some drivers)"};
+cvar_t gl_paranoid = {CVAR_CLIENT, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
+cvar_t gl_printcheckerror = {CVAR_CLIENT, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
-#define MAX_RENDERTARGETS 4
+cvar_t r_render = {CVAR_CLIENT, "r_render", "1", "enables rendering 3D views (you want this on!)"};
+cvar_t r_renderview = {CVAR_CLIENT, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
+cvar_t r_waterwarp = {CVAR_CLIENT | CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
+cvar_t gl_polyblend = {CVAR_CLIENT | CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
-cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
-cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
-cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
-
-cvar_t r_render = {0, "r_render", "1", "enables rendering 3D views (you want this on!)"};
-cvar_t r_renderview = {0, "r_renderview", "1", "enables rendering 3D views (you want this on!)"};
-cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
-cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
-cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
-cvar_t gl_vbo = {CVAR_SAVE, "gl_vbo", "3", "make use of GL_ARB_vertex_buffer_object extension to store static geometry in video memory for faster rendering, 0 disables VBO allocation or use, 1 enables VBOs for vertex and triangle data, 2 only for vertex data, 3 for vertex data and triangle data of simple meshes (ones with only one surface)"};
-cvar_t gl_vbo_dynamicvertex = {CVAR_SAVE, "gl_vbo_dynamicvertex", "0", "make use of GL_ARB_vertex_buffer_object extension when rendering dynamic (animated/procedural) geometry such as text and particles"};
-cvar_t gl_vbo_dynamicindex = {CVAR_SAVE, "gl_vbo_dynamicindex", "0", "make use of GL_ARB_vertex_buffer_object extension when rendering dynamic (animated/procedural) geometry such as text and particles"};
-cvar_t gl_fbo = {CVAR_SAVE, "gl_fbo", "1", "make use of GL_ARB_framebuffer_object extension to enable shadowmaps and other features using pixel formats different from the framebuffer"};
-
-cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
+cvar_t v_flipped = {CVAR_CLIENT, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
qboolean v_flipped_state = false;
r_viewport_t gl_viewport;
float gl_modelviewprojection16f[16];
qboolean gl_modelmatrixchanged;
-int gl_maxdrawrangeelementsvertices;
-int gl_maxdrawrangeelementsindices;
-
#ifdef DEBUGGL
int gl_errornumber = 0;
break;
}
}
+
+static void GLAPIENTRY GL_DebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const GLvoid* userParam)
+{
+ const char *sev = "ENUM?", *typ = "ENUM?", *src = "ENUM?";
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_LOW_ARB: sev = "LOW"; break;
+ case GL_DEBUG_SEVERITY_MEDIUM_ARB: sev = "MED"; break;
+ case GL_DEBUG_SEVERITY_HIGH_ARB: sev = "HIGH"; break;
+ }
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR_ARB: typ = "ERROR"; break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: typ = "DEPRECATED"; break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: typ = "UNDEFINED"; break;
+ case GL_DEBUG_TYPE_PORTABILITY_ARB: typ = "PORTABILITY"; break;
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB: typ = "PERFORMANCE"; break;
+ case GL_DEBUG_TYPE_OTHER_ARB: typ = "OTHER"; break;
+ }
+ switch (source)
+ {
+ case GL_DEBUG_SOURCE_API_ARB: src = "API"; break;
+ case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: src = "SHADER"; break;
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: src = "WIN"; break;
+ case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: src = "THIRDPARTY"; break;
+ case GL_DEBUG_SOURCE_APPLICATION_ARB: src = "APP"; break;
+ case GL_DEBUG_SOURCE_OTHER_ARB: src = "OTHER"; break;
+ }
+ Con_Printf("GLDEBUG: %s %s %s: %u: %s\n", sev, typ, src, (unsigned int)id, message);
+}
#endif
#define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
-void SCR_ScreenShot_f (void);
+void SCR_ScreenShot_f(cmd_state_t *cmd);
typedef struct gltextureunit_s
{
rtexture_t *texture;
int t2d, t3d, tcubemap;
int arrayenabled;
- int rgbscale, alphascale;
- int combine;
- int combinergb, combinealpha;
- // texmatrixenabled exists only to avoid unnecessary texmatrix compares
- int texmatrixenabled;
- matrix4x4_t matrix;
}
gltextureunit_t;
int depthfunc;
float depthrange[2];
float polygonoffset[2];
- int alphatest;
- int alphafunc;
- float alphafuncvalue;
qboolean alphatocoverage;
int scissortest;
unsigned int unit;
- unsigned int clientunit;
gltextureunit_t units[MAX_TEXTUREUNITS];
float color4f[4];
int lockrange_first;
int defaultframebufferobject; // deal with platforms that use a non-zero default fbo
qboolean pointer_color_enabled;
+ // GL3.2 Core requires that we have a GL_VERTEX_ARRAY_OBJECT, but... just one.
+ unsigned int defaultvao;
+
int pointer_vertex_components;
int pointer_vertex_gltype;
size_t pointer_vertex_stride;
size_t preparevertices_tempdatamaxsize;
int preparevertices_numvertices;
- qboolean usevbo_staticvertex;
- qboolean usevbo_staticindex;
- qboolean usevbo_dynamicvertex;
- qboolean usevbo_dynamicindex;
-
memexpandablearray_t meshbufferarray;
qboolean active;
int quadelement3i[QUADELEMENTS_MAXQUADS*6];
unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
-static void GL_VBOStats_f(void)
+static void GL_VBOStats_f(cmd_state_t *cmd)
{
GL_Mesh_ListVBOs(true);
}
static void GL_Backend_ResetState(void);
-static void R_Mesh_SetUseVBO(void)
-{
- switch(vid.renderpath)
- {
- case RENDERPATH_GL20:
- case RENDERPATH_GLES2:
- gl_state.usevbo_staticvertex = (vid.support.arb_vertex_buffer_object && gl_vbo.integer) || vid.forcevbo;
- gl_state.usevbo_staticindex = (vid.support.arb_vertex_buffer_object && (gl_vbo.integer == 1 || gl_vbo.integer == 3)) || vid.forcevbo;
- gl_state.usevbo_dynamicvertex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicvertex.integer && gl_vbo.integer) || vid.forcevbo;
- gl_state.usevbo_dynamicindex = (vid.support.arb_vertex_buffer_object && gl_vbo_dynamicindex.integer && gl_vbo.integer) || vid.forcevbo;
- break;
- }
-}
-
static void gl_backend_start(void)
{
memset(&gl_state, 0, sizeof(gl_state));
- R_Mesh_SetUseVBO();
Mem_ExpandableArray_NewArray(&gl_state.meshbufferarray, r_main_mempool, sizeof(r_meshbuffer_t), 128);
Con_DPrintf("OpenGL backend started.\n");
CHECKGLERROR
- GL_Backend_ResetState();
-
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
+ // GL3.2 Core requires that we have a VAO bound - but using more than one has no performance benefit so this is just placeholder
+ qglGenVertexArrays(1, &gl_state.defaultvao);
+ qglBindVertexArray(gl_state.defaultvao);
+ // fall through
case RENDERPATH_GLES2:
// fetch current fbo here (default fbo is not 0 on some GLES devices)
- if (vid.support.ext_framebuffer_object)
- qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);
+ CHECKGLERROR
+ qglGetIntegerv(GL_FRAMEBUFFER_BINDING, &gl_state.defaultframebufferobject);CHECKGLERROR
break;
}
+
+ GL_Backend_ResetState();
}
static void gl_backend_shutdown(void)
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
break;
}
r_meshbuffer_t *buffer;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
break;
}
continue;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
break;
}
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
break;
}
Cvar_RegisterVariable(&r_waterwarp);
Cvar_RegisterVariable(&gl_polyblend);
Cvar_RegisterVariable(&v_flipped);
- Cvar_RegisterVariable(&gl_dither);
- Cvar_RegisterVariable(&gl_vbo);
- Cvar_RegisterVariable(&gl_vbo_dynamicvertex);
- Cvar_RegisterVariable(&gl_vbo_dynamicindex);
+ Cvar_RegisterVariable(&gl_debug);
Cvar_RegisterVariable(&gl_paranoid);
Cvar_RegisterVariable(&gl_printcheckerror);
- Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
-
- Cmd_AddCommand("gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
+ Cmd_AddCommand(&cmd_client, "gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap, gl_backend_devicelost, gl_backend_devicerestored);
}
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- qglFinish();
+ CHECKGLERROR
+ qglFinish();CHECKGLERROR
break;
}
}
// D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
break;
}
Matrix4x4_Transform3x3(&v->viewmatrix, normal, clipPlane);
VectorScale(normal, -dist, v3);
Matrix4x4_Transform(&v->viewmatrix, v3, v4);
- // FIXME: LordHavoc: I think this can be done more efficiently somehow but I can't remember the technique
+ // FIXME: LadyHavoc: I think this can be done more efficiently somehow but I can't remember the technique
clipPlane[3] = -DotProduct(v4, clipPlane);
-#if 0
-{
- // testing code for comparing results
- float clipPlane2[4];
- VectorCopy4(clipPlane, clipPlane2);
- R_EntityMatrix(&identitymatrix);
- VectorSet(q, normal[0], normal[1], normal[2], -dist);
- qglClipPlane(GL_CLIP_PLANE0, q);
- qglGetClipPlane(GL_CLIP_PLANE0, q);
- VectorCopy4(q, clipPlane);
-}
-#endif
-
// Calculate the clip-space corner point opposite the clipping plane
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
// transform it into camera space by multiplying it
m[15] = 1;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
break;
}
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
{
gl_state.vertexbufferobject = bufferobject;
CHECKGLERROR
- qglBindBufferARB(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
+ qglBindBuffer(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
}
}
{
gl_state.elementbufferobject = bufferobject;
CHECKGLERROR
- qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
+ qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
}
}
gl_state.uniformbufferobject = bufferobject;
#ifdef GL_UNIFORM_BUFFER
CHECKGLERROR
- qglBindBufferARB(GL_UNIFORM_BUFFER, bufferobject);CHECKGLERROR
+ qglBindBuffer(GL_UNIFORM_BUFFER, bufferobject);CHECKGLERROR
#endif
}
}
static const GLuint drawbuffers[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
{
+ int temp;
+ GLuint status;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- if (vid.support.arb_framebuffer_object)
- {
- int temp;
- GLuint status;
- qglGenFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
- R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
- // GL_ARB_framebuffer_object (GL3-class hardware) - depth stencil attachment
+ CHECKGLERROR
+ qglGenFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
+ R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
+ // GL_ARB_framebuffer_object (GL3-class hardware) - depth stencil attachment
#ifdef USE_GLES2
- // FIXME: separate stencil attachment on GLES
- if (depthtexture && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
- if (depthtexture && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
+ // FIXME: separate stencil attachment on GLES
+ if (depthtexture && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+ if (depthtexture && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
#else
- if (depthtexture && depthtexture->texnum )
- {
- qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
- if (depthtexture->glisdepthstencil) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
- }
- if (depthtexture && depthtexture->renderbuffernum )
- {
- qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
- if (depthtexture->glisdepthstencil) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
- }
+ if (depthtexture && depthtexture->texnum )
+ {
+ qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+ if (depthtexture->glisdepthstencil) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
+ }
+ if (depthtexture && depthtexture->renderbuffernum )
+ {
+ qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
+ if (depthtexture->glisdepthstencil) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
+ }
#endif
- if (colortexture && colortexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR
- if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR
- if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR
- if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR
- if (colortexture && colortexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR
- if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR
- if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR
- if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR
+ if (colortexture && colortexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR
+ if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR
+ if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR
+ if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR
+ if (colortexture && colortexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR
+ if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR
+ if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR
+ if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR
#ifndef USE_GLES2
- if (colortexture4 && qglDrawBuffersARB)
- {
- qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
- else if (colortexture3 && qglDrawBuffersARB)
- {
- qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
- else if (colortexture2 && qglDrawBuffersARB)
- {
- qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
- else if (colortexture && qglDrawBuffer)
- {
- qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
- qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
- }
- else if (qglDrawBuffer)
- {
- qglDrawBuffer(GL_NONE);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
-#endif
- status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
- if (status != GL_FRAMEBUFFER_COMPLETE)
- {
- Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
- gl_state.framebufferobject = 0; // GL unbinds it for us
- qglDeleteFramebuffers(1, (GLuint*)&temp);
- temp = 0;
- }
- return temp;
+ if (colortexture4)
+ {
+ qglDrawBuffers(4, drawbuffers);CHECKGLERROR
+ qglReadBuffer(GL_NONE);CHECKGLERROR
}
- else if (vid.support.ext_framebuffer_object)
+ else if (colortexture3)
{
- int temp;
- GLuint status;
- qglGenFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
- R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL);
- // GL_EXT_framebuffer_object (GL2-class hardware) - no depth stencil attachment, let it break stencil
- if (depthtexture && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR
- if (depthtexture && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR
- if (colortexture && colortexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR
- if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR
- if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR
- if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR
- if (colortexture && colortexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR
- if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR
- if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR
- if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR
-
-#ifndef USE_GLES2
- if (colortexture4 && qglDrawBuffersARB)
- {
- qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
- else if (colortexture3 && qglDrawBuffersARB)
- {
- qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
- else if (colortexture2 && qglDrawBuffersARB)
- {
- qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
- else if (colortexture && qglDrawBuffer)
- {
- qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
- qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
- }
- else if (qglDrawBuffer)
- {
- qglDrawBuffer(GL_NONE);CHECKGLERROR
- qglReadBuffer(GL_NONE);CHECKGLERROR
- }
+ qglDrawBuffers(3, drawbuffers);CHECKGLERROR
+ qglReadBuffer(GL_NONE);CHECKGLERROR
+ }
+ else if (colortexture2)
+ {
+ qglDrawBuffers(2, drawbuffers);CHECKGLERROR
+ qglReadBuffer(GL_NONE);CHECKGLERROR
+ }
+ else if (colortexture)
+ {
+ qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
+ qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR
+ }
+ else
+ {
+ qglDrawBuffer(GL_NONE);CHECKGLERROR
+ qglReadBuffer(GL_NONE);CHECKGLERROR
+ }
#endif
- status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
- if (status != GL_FRAMEBUFFER_COMPLETE)
- {
- Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
- gl_state.framebufferobject = 0; // GL unbinds it for us
- qglDeleteFramebuffers(1, (GLuint*)&temp);
- temp = 0;
- }
- return temp;
+ status = qglCheckFramebufferStatus(GL_FRAMEBUFFER);CHECKGLERROR
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatus returned %i\n", status);
+ gl_state.framebufferobject = 0; // GL unbinds it for us
+ qglDeleteFramebuffers(1, (GLuint*)&temp);CHECKGLERROR
+ temp = 0;
}
- return 0;
+ return temp;
}
return 0;
}
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
if (fbo)
{
// GL clears the binding if we delete something bound
if (gl_state.framebufferobject == fbo)
gl_state.framebufferobject = 0;
- qglDeleteFramebuffers(1, (GLuint*)&fbo);
+ qglDeleteFramebuffers(1, (GLuint*)&fbo);CHECKGLERROR
}
break;
}
// unbind any matching textures immediately, otherwise D3D will complain about a bound texture being used as a render target
for (j = 0;j < 5;j++)
if (textures[j])
- for (i = 0;i < vid.teximageunits;i++)
+ for (i = 0;i < MAX_TEXTUREUNITS;i++)
if (gl_state.units[i].texture == textures[j])
R_Mesh_TexBind(i, NULL);
// set up framebuffer object or render targets for the active rendering API
switch (vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
if (gl_state.framebufferobject != fbo)
{
gl_state.framebufferobject = fbo;
- qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);
+ qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.framebufferobject ? gl_state.framebufferobject : gl_state.defaultframebufferobject);CHECKGLERROR
}
break;
}
static void GL_Backend_ResetState(void)
{
- unsigned int i;
gl_state.active = true;
gl_state.depthtest = true;
- gl_state.alphatest = false;
- gl_state.alphafunc = GL_GEQUAL;
- gl_state.alphafuncvalue = 0.5f;
gl_state.alphatocoverage = false;
gl_state.blendfunc1 = GL_ONE;
gl_state.blendfunc2 = GL_ZERO;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
+ // set up debug output early
+ if (vid.support.arb_debug_output)
+ {
+ GLuint unused = 0;
+ CHECKGLERROR
+ if (gl_debug.integer >= 1)
+ qglEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ if (gl_debug.integer >= 3)
+ qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unused, gl_debug.integer >= 3 ? GL_TRUE : GL_FALSE);
+ else if (gl_debug.integer >= 1)
+ {
+ qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, &unused, gl_debug.integer >= 3 ? GL_TRUE : GL_FALSE);
+ qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM_ARB, 0, &unused, gl_debug.integer >= 2 ? GL_TRUE : GL_FALSE);
+ qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH_ARB, 0, &unused, gl_debug.integer >= 1 ? GL_TRUE : GL_FALSE);
+ }
+ else
+ qglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, &unused, GL_FALSE);
+ qglDebugMessageCallbackARB(GL_DebugOutputCallback, NULL);
+ }
CHECKGLERROR
qglColorMask(1, 1, 1, 1);CHECKGLERROR
qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR
qglEnable(GL_DEPTH_TEST);CHECKGLERROR
qglDepthMask(gl_state.depthmask);CHECKGLERROR
qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
- if (vid.support.arb_vertex_buffer_object)
- {
- qglBindBufferARB(GL_ARRAY_BUFFER, 0);
- qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- if (vid.support.ext_framebuffer_object)
- qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
+ qglBindBuffer(GL_ARRAY_BUFFER, 0);
+ qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ qglBindFramebuffer(GL_FRAMEBUFFER, gl_state.defaultframebufferobject);
qglEnableVertexAttribArray(GLSLATTRIB_POSITION);
- qglVertexAttribPointer(GLSLATTRIB_POSITION, 3, GL_FLOAT, false, sizeof(float[3]), NULL);CHECKGLERROR
qglDisableVertexAttribArray(GLSLATTRIB_COLOR);
- qglVertexAttribPointer(GLSLATTRIB_COLOR, 4, GL_FLOAT, false, sizeof(float[4]), NULL);CHECKGLERROR
qglVertexAttrib4f(GLSLATTRIB_COLOR, 1, 1, 1, 1);
gl_state.unit = MAX_TEXTUREUNITS;
- gl_state.clientunit = MAX_TEXTUREUNITS;
- for (i = 0;i < vid.teximageunits;i++)
- {
- GL_ActiveTexture(i);
- qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
- if (vid.support.ext_texture_3d)
- {
- qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
- }
- if (vid.support.arb_texture_cube_map)
- {
- qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHECKGLERROR
- }
- }
- for (i = 0;i < vid.texarrayunits;i++)
- {
- GL_BindVBO(0);
- qglVertexAttribPointer(i+GLSLATTRIB_TEXCOORD0, 2, GL_FLOAT, false, sizeof(float[2]), NULL);CHECKGLERROR
- qglDisableVertexAttribArray(i+GLSLATTRIB_TEXCOORD0);CHECKGLERROR
- }
CHECKGLERROR
break;
}
gl_state.unit = num;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
- qglActiveTexture(GL_TEXTURE0 + gl_state.unit);
- CHECKGLERROR
+ qglActiveTexture(GL_TEXTURE0 + gl_state.unit);CHECKGLERROR
break;
}
}
blendenable = (gl_state.blendfunc1 != GL_ONE || gl_state.blendfunc2 != GL_ZERO);
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if (qglBlendFuncSeparate)
gl_state.depthmask = state;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
qglDepthMask(gl_state.depthmask);CHECKGLERROR
gl_state.depthtest = state;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if (gl_state.depthtest)
gl_state.depthfunc = state;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
qglDepthFunc(gl_state.depthfunc);CHECKGLERROR
gl_state.depthrange[1] = farfrac;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
+ CHECKGLERROR
#ifdef USE_GLES2
- qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);
+ qglDepthRangef(gl_state.depthrange[0], gl_state.depthrange[1]);CHECKGLERROR
#else
- qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);
+ qglDepthRange(gl_state.depthrange[0], gl_state.depthrange[1]);CHECKGLERROR
#endif
break;
}
{
switch (vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if (enable)
gl_state.polygonoffset[1] = depthoffset;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
+ CHECKGLERROR
+ qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);CHECKGLERROR
break;
}
}
return;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
+ CHECKGLERROR
qglCullFace(gl_state.cullface);CHECKGLERROR
break;
}
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
{
case RENDERPATH_GLES2:
break;
- case RENDERPATH_GL20:
-#ifdef GL_SAMPLE_ALPHA_TO_COVERAGE_ARB
+ case RENDERPATH_GL32:
+#ifndef USE_GLES2
// alpha to coverage turns the alpha value of the pixel into 0%, 25%, 50%, 75% or 100% by masking the multisample fragments accordingly
CHECKGLERROR
if (gl_state.alphatocoverage)
{
- qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
-// qglEnable(GL_MULTISAMPLE_ARB);CHECKGLERROR
+ qglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);CHECKGLERROR
+// qglEnable(GL_MULTISAMPLE);CHECKGLERROR
}
else
{
- qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);CHECKGLERROR
-// qglDisable(GL_MULTISAMPLE_ARB);CHECKGLERROR
+ qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);CHECKGLERROR
+// qglDisable(GL_MULTISAMPLE);CHECKGLERROR
}
#endif
break;
gl_state.colormask = state;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
qglColorMask((GLboolean)r, (GLboolean)g, (GLboolean)b, (GLboolean)a);CHECKGLERROR
gl_state.color4f[3] = ca;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);
+ qglVertexAttrib4f(GLSLATTRIB_COLOR, cr, cg, cb, ca);CHECKGLERROR
break;
}
}
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
- qglScissor(x, y,width,height);
- CHECKGLERROR
+ qglScissor(x, y,width,height);CHECKGLERROR
break;
}
}
gl_state.scissortest = state;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if(gl_state.scissortest)
}
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if (mask & GL_COLOR_BUFFER_BIT)
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
#ifndef GL_BGRA
{
BACKENDACTIVECHECK
R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
- R_Mesh_SetUseVBO();
if (gl_printcheckerror.integer && !gl_paranoid.integer)
{
Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_SkeletalIndex");
qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_SkeletalWeight");
#ifndef USE_GLES2
- if(vid.support.gl20shaders130)
- qglBindFragDataLocation(programobject, 0, "dp_FragColor");
+ qglBindFragDataLocation(programobject, 0, "dp_FragColor");
#endif
+ CHECKGLERROR
if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list))
goto cleanup;
}
// renders triangles using vertices from the active arrays
-int paranoidblah = 0;
void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, int element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, int element3s_bufferoffset)
{
unsigned int numelements = numtriangles * 3;
element3s += firsttriangle * 3;
if (element3s_indexbuffer)
element3s_bufferoffset += firsttriangle * 3 * sizeof(*element3s);
- switch(vid.renderpath)
- {
- case RENDERPATH_GL20:
- case RENDERPATH_GLES2:
- // check if the user specified to ignore static index buffers
- if (!gl_state.usevbo_staticindex || (gl_vbo.integer == 3 && !vid.forcevbo && (element3i_bufferoffset || element3s_bufferoffset)))
- {
- element3i_indexbuffer = NULL;
- element3s_indexbuffer = NULL;
- }
- break;
- }
// upload a dynamic index buffer if needed
if (element3s)
{
- if (!element3s_indexbuffer && gl_state.usevbo_dynamicindex)
+ if (!element3s_indexbuffer)
element3s_indexbuffer = R_BufferData_Store(numelements * sizeof(*element3s), (void *)element3s, R_BUFFERDATA_INDEX16, &element3s_bufferoffset);
}
else if (element3i)
{
- if (!element3i_indexbuffer && gl_state.usevbo_dynamicindex)
+ if (!element3i_indexbuffer)
element3i_indexbuffer = R_BufferData_Store(numelements * sizeof(*element3i), (void *)element3i, R_BUFFERDATA_INDEX32, &element3i_bufferoffset);
}
bufferobject3i = element3i_indexbuffer ? element3i_indexbuffer->bufferobject : 0;
if (gl_paranoid.integer)
{
unsigned int i;
- // LordHavoc: disabled this - it needs to be updated to handle components and gltype and stride in each array
-#if 0
- unsigned int j, size;
- const int *p;
- // note: there's no validation done here on buffer objects because it
- // is somewhat difficult to get at the data, and gl_paranoid can be
- // used without buffer objects if the need arises
- // (the data could be gotten using glMapBuffer but it would be very
- // slow due to uncachable video memory reads)
- if (!qglIsEnabled(GL_VERTEX_ARRAY))
- Con_Print("R_Mesh_Draw: vertex array not enabled\n");
- CHECKGLERROR
- if (gl_state.pointer_vertex_pointer)
- for (j = 0, size = numvertices * 3, p = (int *)((float *)gl_state.pointer_vertex + firstvertex * 3);j < size;j++, p++)
- paranoidblah += *p;
- if (gl_state.pointer_color_enabled)
- {
- if (!qglIsEnabled(GL_COLOR_ARRAY))
- Con_Print("R_Mesh_Draw: color array set but not enabled\n");
- CHECKGLERROR
- if (gl_state.pointer_color && gl_state.pointer_color_enabled)
- for (j = 0, size = numvertices * 4, p = (int *)((float *)gl_state.pointer_color + firstvertex * 4);j < size;j++, p++)
- paranoidblah += *p;
- }
- for (i = 0;i < vid.texarrayunits;i++)
- {
- if (gl_state.units[i].arrayenabled)
- {
- GL_ClientActiveTexture(i);
- if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
- Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n");
- CHECKGLERROR
- if (gl_state.units[i].pointer_texcoord && gl_state.units[i].arrayenabled)
- for (j = 0, size = numvertices * gl_state.units[i].arraycomponents, p = (int *)((float *)gl_state.units[i].pointer_texcoord + firstvertex * gl_state.units[i].arraycomponents);j < size;j++, p++)
- paranoidblah += *p;
- }
- }
-#endif
if (element3i)
{
for (i = 0;i < (unsigned int) numtriangles * 3;i++)
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
- CHECKGLERROR
- if (bufferobject3s)
- {
- GL_BindEBO(bufferobject3s);
-#ifndef USE_GLES2
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
- {
- qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
- CHECKGLERROR
- }
- else
-#endif
- {
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
- CHECKGLERROR
- }
- }
- else if (bufferobject3i)
- {
- GL_BindEBO(bufferobject3i);
-#ifndef USE_GLES2
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
- {
- qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
- CHECKGLERROR
- }
- else
-#endif
- {
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
- CHECKGLERROR
- }
- }
- else if (element3s)
- {
- GL_BindEBO(0);
-#ifndef USE_GLES2
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
- {
- qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_SHORT, element3s);
- CHECKGLERROR
- }
- else
-#endif
- {
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
- CHECKGLERROR
- }
- }
- else if (element3i)
- {
- GL_BindEBO(0);
-#ifndef USE_GLES2
- if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
- {
- qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices - 1, numelements, GL_UNSIGNED_INT, element3i);
- CHECKGLERROR
- }
- else
-#endif
- {
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
- CHECKGLERROR
- }
- }
- else
- {
- qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
- CHECKGLERROR
- }
- break;
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- // GLES does not have glDrawRangeElements so this is a bit shorter than the GL20 path
+ CHECKGLERROR
if (bufferobject3s)
{
GL_BindEBO(bufferobject3s);
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);
- CHECKGLERROR
+ qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s);CHECKGLERROR
}
else if (bufferobject3i)
{
GL_BindEBO(bufferobject3i);
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);
- CHECKGLERROR
- }
- else if (element3s)
- {
- GL_BindEBO(0);
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
- CHECKGLERROR
- }
- else if (element3i)
- {
- GL_BindEBO(0);
- qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
- CHECKGLERROR
+ qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i);CHECKGLERROR
}
else
{
- qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);
- CHECKGLERROR
+ qglDrawArrays(GL_TRIANGLES, firstvertex, numvertices);CHECKGLERROR
}
break;
}
r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isuniformbuffer, qboolean isdynamic, qboolean isindex16)
{
r_meshbuffer_t *buffer;
- if (isuniformbuffer)
- {
- if (!vid.support.arb_uniform_buffer_object)
- return NULL;
- }
- else
- {
- if (!vid.support.arb_vertex_buffer_object)
- return NULL;
- if (!isdynamic && !(isindexbuffer ? gl_state.usevbo_staticindex : gl_state.usevbo_staticvertex))
- return NULL;
- }
buffer = (r_meshbuffer_t *)Mem_ExpandableArray_AllocRecord(&gl_state.meshbufferarray);
memset(buffer, 0, sizeof(*buffer));
buffer->bufferobject = 0;
buffer->size = size;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
if (!buffer->bufferobject)
- qglGenBuffersARB(1, (GLuint *)&buffer->bufferobject);
+ qglGenBuffers(1, (GLuint *)&buffer->bufferobject);
+ CHECKGLERROR
if (buffer->isuniformbuffer)
GL_BindUBO(buffer->bufferobject);
else if (buffer->isindexbuffer)
if (buffer->isuniformbuffer)
buffertype = GL_UNIFORM_BUFFER;
#endif
+ CHECKGLERROR
if (subdata)
- qglBufferSubDataARB(buffertype, offset, size, data);
+ qglBufferSubData(buffertype, offset, size, data);
else
- qglBufferDataARB(buffertype, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
+ qglBufferData(buffertype, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW);
+ CHECKGLERROR
}
if (buffer->isuniformbuffer)
GL_BindUBO(0);
return;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
// GL clears the binding if we delete something bound
if (gl_state.uniformbufferobject == buffer->bufferobject)
gl_state.vertexbufferobject = 0;
if (gl_state.elementbufferobject == buffer->bufferobject)
gl_state.elementbufferobject = 0;
- qglDeleteBuffersARB(1, (GLuint *)&buffer->bufferobject);
+ CHECKGLERROR
+ qglDeleteBuffers(1, (GLuint *)&buffer->bufferobject);CHECKGLERROR
break;
}
Mem_ExpandableArray_FreeRecord(&gl_state.meshbufferarray, (void *)buffer);
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
if (gl_state.pointer_vertex_components != components || gl_state.pointer_vertex_gltype != gltype || gl_state.pointer_vertex_stride != stride || gl_state.pointer_vertex_pointer != pointer || gl_state.pointer_vertex_vertexbuffer != vertexbuffer || gl_state.pointer_vertex_offset != bufferoffset)
{
int bufferobject = vertexbuffer ? vertexbuffer->bufferobject : 0;
+ if (!bufferobject && gl_paranoid.integer)
+ Con_DPrintf("Warning: no bufferobject in R_Mesh_VertexPointer(%i, %i, %i, %p, %p, %08x)", components, gltype, (int)stride, pointer, vertexbuffer, (unsigned int)bufferoffset);
gl_state.pointer_vertex_components = components;
gl_state.pointer_vertex_gltype = gltype;
gl_state.pointer_vertex_stride = stride;
gl_state.pointer_vertex_offset = bufferoffset;
CHECKGLERROR
GL_BindVBO(bufferobject);
- // LordHavoc: special flag added to gltype for unnormalized types
+ // LadyHavoc: special flag added to gltype for unnormalized types
qglVertexAttribPointer(GLSLATTRIB_POSITION, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, (GLsizei)stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
}
break;
// the pointer only.
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if (pointer)
gl_state.pointer_color_offset = bufferoffset;
CHECKGLERROR
GL_BindVBO(bufferobject);
- // LordHavoc: special flag added to gltype for unnormalized types
+ // LadyHavoc: special flag added to gltype for unnormalized types
qglVertexAttribPointer(GLSLATTRIB_COLOR, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, (GLsizei)stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
}
}
void R_Mesh_TexCoordPointer(unsigned int unitnum, int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
{
gltextureunit_t *unit = gl_state.units + unitnum;
+ if (unitnum >= MAX_TEXTUREUNITS)
+ Sys_Error("R_Mesh_TexCoordPointer: unitnum %i > max units %i\n", unitnum, MAX_TEXTUREUNITS);
// update array settings
// note: there is no need to check bufferobject here because all cases
// that involve a valid bufferobject also supply a texcoord array
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
CHECKGLERROR
if (pointer)
unit->pointer_texcoord_vertexbuffer = vertexbuffer;
unit->pointer_texcoord_offset = bufferoffset;
GL_BindVBO(bufferobject);
- // LordHavoc: special flag added to gltype for unnormalized types
+ // LadyHavoc: special flag added to gltype for unnormalized types
qglVertexAttribPointer(unitnum+GLSLATTRIB_TEXCOORD0, components, gltype & ~0x80000000, (gltype & 0x80000000) == 0, (GLsizei)stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR
}
}
int R_Mesh_TexBound(unsigned int unitnum, int id)
{
gltextureunit_t *unit = gl_state.units + unitnum;
- if (unitnum >= vid.teximageunits)
- return 0;
+ if (unitnum >= MAX_TEXTUREUNITS)
+ Sys_Error("R_Mesh_TexCoordPointer: unitnum %i > max units %i\n", unitnum, MAX_TEXTUREUNITS);
if (id == GL_TEXTURE_2D)
return unit->t2d;
if (id == GL_TEXTURE_3D)
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
R_Mesh_TexBind(0, tex);
GL_ActiveTexture(0);CHECKGLERROR
{
gltextureunit_t *unit;
unsigned int unitnum;
- // this doesn't really unbind the texture, but it does prevent a mistaken "do nothing" behavior on the next time this same texnum is bound on the same unit as the same type (this mainly affects r_shadow_bouncegrid because 3D textures are so rarely used)
- for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
+ // unbind the texture from any units it is bound on - this prevents accidental reuse of certain textures whose bindings can linger far too long otherwise (e.g. bouncegrid which is a 3D texture) and confuse the driver later.
+ for (unitnum = 0; unitnum < MAX_TEXTUREUNITS; unitnum++)
{
unit = gl_state.units + unitnum;
- if (unit->t2d == texnum)
- unit->t2d = -1;
- if (unit->t3d == texnum)
- unit->t3d = -1;
- if (unit->tcubemap == texnum)
- unit->tcubemap = -1;
+ if (unit->texture && unit->texture->texnum == texnum)
+ R_Mesh_TexBind(unitnum, NULL);
}
}
{
gltextureunit_t *unit = gl_state.units + unitnum;
int texnum;
- if (unitnum >= vid.teximageunits)
- return;
- if (unit->texture == tex)
- return;
+ if (unitnum >= MAX_TEXTUREUNITS)
+ Sys_Error("R_Mesh_TexBind: unitnum %i > max units %i\n", unitnum, MAX_TEXTUREUNITS);
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- if (!tex)
+ if (tex)
{
- tex = r_texture_white;
- // not initialized enough yet...
- if (!tex)
- return;
+ texnum = R_GetTexture(tex);
+ switch (tex->gltexturetypeenum)
+ {
+ case GL_TEXTURE_2D:
+ if (unit->t2d != texnum) { GL_ActiveTexture(unitnum);qglBindTexture(GL_TEXTURE_2D, texnum); CHECKGLERROR unit->t2d = texnum; }
+ if (unit->t3d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, 0); CHECKGLERROR unit->t3d = 0; }
+ if (unit->tcubemap) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECKGLERROR unit->tcubemap = 0; }
+ break;
+ case GL_TEXTURE_3D:
+ if (unit->t2d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_2D, 0); CHECKGLERROR unit->t2d = 0; }
+ if (unit->t3d != texnum) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, texnum); CHECKGLERROR unit->t3d = texnum; }
+ if (unit->tcubemap) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECKGLERROR unit->tcubemap = 0; }
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ if (unit->t2d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_2D, 0); CHECKGLERROR unit->t2d = 0; }
+ if (unit->t3d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, 0); CHECKGLERROR unit->t3d = 0; }
+ if (unit->tcubemap != texnum) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, texnum); CHECKGLERROR unit->tcubemap = texnum; }
+ break;
+ }
}
- unit->texture = tex;
- texnum = R_GetTexture(tex);
- switch(tex->gltexturetypeenum)
+ else
{
- case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
- case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
- case GL_TEXTURE_CUBE_MAP: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR}break;
+ if (unit->t2d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_2D, 0); CHECKGLERROR unit->t2d = 0; }
+ if (unit->t3d) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_3D, 0); CHECKGLERROR unit->t3d = 0; }
+ if (unit->tcubemap) { GL_ActiveTexture(unitnum); qglBindTexture(GL_TEXTURE_CUBE_MAP, 0); CHECKGLERROR unit->tcubemap = 0; }
}
- break;
}
+ unit->texture = tex;
}
void R_Mesh_ResetTextureState(void)
{
+#if 0
unsigned int unitnum;
-
+
BACKENDACTIVECHECK
- for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
+ for (unitnum = 0;unitnum < MAX_TEXTUREUNITS;unitnum++)
R_Mesh_TexBind(unitnum, NULL);
- for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
- R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+#endif
}
void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer, int bufferoffset)
{
// upload temporary vertexbuffer for this rendering
- if (!gl_state.usevbo_staticvertex)
- vertexbuffer = NULL;
- if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
+ if (!vertexbuffer)
vertexbuffer = R_BufferData_Store(numvertices * sizeof(float[3]), (void *)vertex3f, R_BUFFERDATA_VERTEX, &bufferoffset);
- if (vertexbuffer)
- {
- R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, bufferoffset);
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- }
- else
- {
- R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- }
+ R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(float[3]) , vertex3f , vertexbuffer , bufferoffset );
+ R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(float[4]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(5, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
}
void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
{
- if (gl_state.usevbo_dynamicvertex)
- {
- r_meshbuffer_t *buffer_vertex3f = NULL;
- r_meshbuffer_t *buffer_color4f = NULL;
- r_meshbuffer_t *buffer_texcoord2f = NULL;
- int bufferoffset_vertex3f = 0;
- int bufferoffset_color4f = 0;
- int bufferoffset_texcoord2f = 0;
+ r_meshbuffer_t *buffer_vertex3f = NULL;
+ r_meshbuffer_t *buffer_color4f = NULL;
+ r_meshbuffer_t *buffer_texcoord2f = NULL;
+ int bufferoffset_vertex3f = 0;
+ int bufferoffset_color4f = 0;
+ int bufferoffset_texcoord2f = 0;
+ if (color4f)
buffer_color4f = R_BufferData_Store(numvertices * sizeof(float[4]), color4f , R_BUFFERDATA_VERTEX, &bufferoffset_color4f );
+ if (vertex3f)
buffer_vertex3f = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f );
+ if (texcoord2f)
buffer_texcoord2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoord2f, R_BUFFERDATA_VERTEX, &bufferoffset_texcoord2f);
- R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(float[3]) , vertex3f , buffer_vertex3f , bufferoffset_vertex3f );
- R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(float[4]) , color4f , buffer_color4f , bufferoffset_color4f );
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(float[2]) , texcoord2f , buffer_texcoord2f , bufferoffset_texcoord2f );
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
- }
- else
- {
- R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoord2f, NULL, 0);
- R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- }
+ R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(float[3]) , vertex3f , buffer_vertex3f , bufferoffset_vertex3f );
+ R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(float[4]) , color4f , buffer_color4f , bufferoffset_color4f );
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(float[2]) , texcoord2f , buffer_texcoord2f , bufferoffset_texcoord2f );
+ R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(float[3]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(5, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
}
void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *color4f, const float *texcoordtexture2f, const float *texcoordlightmap2f)
{
- if (gl_state.usevbo_dynamicvertex)
- {
- r_meshbuffer_t *buffer_vertex3f = NULL;
- r_meshbuffer_t *buffer_color4f = NULL;
- r_meshbuffer_t *buffer_texcoordtexture2f = NULL;
- r_meshbuffer_t *buffer_svector3f = NULL;
- r_meshbuffer_t *buffer_tvector3f = NULL;
- r_meshbuffer_t *buffer_normal3f = NULL;
- r_meshbuffer_t *buffer_texcoordlightmap2f = NULL;
- int bufferoffset_vertex3f = 0;
- int bufferoffset_color4f = 0;
- int bufferoffset_texcoordtexture2f = 0;
- int bufferoffset_svector3f = 0;
- int bufferoffset_tvector3f = 0;
- int bufferoffset_normal3f = 0;
- int bufferoffset_texcoordlightmap2f = 0;
+ r_meshbuffer_t *buffer_vertex3f = NULL;
+ r_meshbuffer_t *buffer_color4f = NULL;
+ r_meshbuffer_t *buffer_texcoordtexture2f = NULL;
+ r_meshbuffer_t *buffer_svector3f = NULL;
+ r_meshbuffer_t *buffer_tvector3f = NULL;
+ r_meshbuffer_t *buffer_normal3f = NULL;
+ r_meshbuffer_t *buffer_texcoordlightmap2f = NULL;
+ int bufferoffset_vertex3f = 0;
+ int bufferoffset_color4f = 0;
+ int bufferoffset_texcoordtexture2f = 0;
+ int bufferoffset_svector3f = 0;
+ int bufferoffset_tvector3f = 0;
+ int bufferoffset_normal3f = 0;
+ int bufferoffset_texcoordlightmap2f = 0;
+ if (color4f)
buffer_color4f = R_BufferData_Store(numvertices * sizeof(float[4]), color4f , R_BUFFERDATA_VERTEX, &bufferoffset_color4f );
+ if (vertex3f)
buffer_vertex3f = R_BufferData_Store(numvertices * sizeof(float[3]), vertex3f , R_BUFFERDATA_VERTEX, &bufferoffset_vertex3f );
+ if (svector3f)
buffer_svector3f = R_BufferData_Store(numvertices * sizeof(float[3]), svector3f , R_BUFFERDATA_VERTEX, &bufferoffset_svector3f );
+ if (tvector3f)
buffer_tvector3f = R_BufferData_Store(numvertices * sizeof(float[3]), tvector3f , R_BUFFERDATA_VERTEX, &bufferoffset_tvector3f );
+ if (normal3f)
buffer_normal3f = R_BufferData_Store(numvertices * sizeof(float[3]), normal3f , R_BUFFERDATA_VERTEX, &bufferoffset_normal3f );
+ if (texcoordtexture2f)
buffer_texcoordtexture2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordtexture2f , R_BUFFERDATA_VERTEX, &bufferoffset_texcoordtexture2f );
+ if (texcoordlightmap2f)
buffer_texcoordlightmap2f = R_BufferData_Store(numvertices * sizeof(float[2]), texcoordlightmap2f, R_BUFFERDATA_VERTEX, &bufferoffset_texcoordlightmap2f);
- R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(float[3]) , vertex3f , buffer_vertex3f , bufferoffset_vertex3f );
- R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(float[4]) , color4f , buffer_color4f , bufferoffset_color4f );
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(float[2]) , texcoordtexture2f , buffer_texcoordtexture2f , bufferoffset_texcoordtexture2f );
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(float[3]) , svector3f , buffer_svector3f , bufferoffset_svector3f );
- R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(float[3]) , tvector3f , buffer_tvector3f , bufferoffset_tvector3f );
- R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(float[3]) , normal3f , buffer_normal3f , bufferoffset_normal3f );
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(float[2]) , texcoordlightmap2f, buffer_texcoordlightmap2f, bufferoffset_texcoordlightmap2f);
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
- }
- else
- {
- R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, NULL, 0);
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), color4f, NULL, 0);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), texcoordtexture2f, NULL, 0);
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), svector3f, NULL, 0);
- R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), tvector3f, NULL, 0);
- R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), normal3f, NULL, 0);
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), texcoordlightmap2f, NULL, 0);
- R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
- }
+ R_Mesh_VertexPointer( 3, GL_FLOAT , sizeof(float[3]) , vertex3f , buffer_vertex3f , bufferoffset_vertex3f );
+ R_Mesh_ColorPointer( 4, GL_FLOAT , sizeof(float[4]) , color4f , buffer_color4f , bufferoffset_color4f );
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT , sizeof(float[2]) , texcoordtexture2f , buffer_texcoordtexture2f , bufferoffset_texcoordtexture2f );
+ R_Mesh_TexCoordPointer(1, 3, GL_FLOAT , sizeof(float[3]) , svector3f , buffer_svector3f , bufferoffset_svector3f );
+ R_Mesh_TexCoordPointer(2, 3, GL_FLOAT , sizeof(float[3]) , tvector3f , buffer_tvector3f , bufferoffset_tvector3f );
+ R_Mesh_TexCoordPointer(3, 3, GL_FLOAT , sizeof(float[3]) , normal3f , buffer_normal3f , bufferoffset_normal3f );
+ R_Mesh_TexCoordPointer(4, 2, GL_FLOAT , sizeof(float[2]) , texcoordlightmap2f, buffer_texcoordlightmap2f, bufferoffset_texcoordlightmap2f);
+ R_Mesh_TexCoordPointer(5, 2, GL_FLOAT , sizeof(float[2]) , NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
+ R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL , NULL , 0 );
}
void GL_BlendEquationSubtract(qboolean negated)
{
+ CHECKGLERROR
if(negated)
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT);
+ qglBlendEquation(GL_FUNC_REVERSE_SUBTRACT);CHECKGLERROR
break;
}
}
{
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
+ case RENDERPATH_GL32:
case RENDERPATH_GLES2:
- qglBlendEquationEXT(GL_FUNC_ADD);
+ qglBlendEquation(GL_FUNC_ADD);CHECKGLERROR
break;
}
}