X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=gl_backend.c;h=8dc6d2366a40328372738de1932296c80cafcb81;hb=90d40131f6af428615cd0c0531c3e94f3c1cb792;hp=81e71c3b2ab7c273ba30e64575a0cb15a3bbe892;hpb=36dc9ea8b11d602992f66aeec3750b819dfdb43b;p=xonotic%2Fdarkplaces.git diff --git a/gl_backend.c b/gl_backend.c index 81e71c3b..8dc6d236 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1156,7 +1156,6 @@ void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatri void R_SetViewport(const r_viewport_t *v) { - float m[16]; gl_viewport = *v; // FIXME: v_flipped_state is evil, this probably breaks somewhere @@ -1171,14 +1170,17 @@ void R_SetViewport(const r_viewport_t *v) case RENDERPATH_GL13: case RENDERPATH_GL11: case RENDERPATH_GLES1: -#ifdef GL_PROJECTION - CHECKGLERROR - qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR - // Load the projection matrix into OpenGL - qglMatrixMode(GL_PROJECTION);CHECKGLERROR - Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m); - qglLoadMatrixf(m);CHECKGLERROR - qglMatrixMode(GL_MODELVIEW);CHECKGLERROR +#ifndef USE_GLES2 + { + float m[16]; + CHECKGLERROR + qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR + // Load the projection matrix into OpenGL + qglMatrixMode(GL_PROJECTION);CHECKGLERROR + Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m); + qglLoadMatrixf(m);CHECKGLERROR + qglMatrixMode(GL_MODELVIEW);CHECKGLERROR + } #endif break; case RENDERPATH_D3D9: @@ -1246,8 +1248,10 @@ static void GL_BindUBO(int bufferobject) if (gl_state.uniformbufferobject != bufferobject) { gl_state.uniformbufferobject = bufferobject; +#ifdef GL_UNIFORM_BUFFER CHECKGLERROR qglBindBufferARB(GL_UNIFORM_BUFFER, bufferobject);CHECKGLERROR +#endif } } @@ -1271,10 +1275,11 @@ int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colorte #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 #else if (depthtexture && depthtexture->texnum ) qglFramebufferTexture2D(GL_FRAMEBUFFER, depthtexture->glisdepthstencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR -#endif if (depthtexture && depthtexture->renderbuffernum ) qglFramebufferRenderbuffer(GL_FRAMEBUFFER, depthtexture->glisdepthstencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_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 @@ -1602,13 +1607,20 @@ static void GL_Backend_ResetState(void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: -#ifdef GL_ALPHA_TEST +#ifndef USE_GLES2 CHECKGLERROR qglColorMask(1, 1, 1, 1);CHECKGLERROR qglAlphaFunc(gl_state.alphafunc, gl_state.alphafuncvalue);CHECKGLERROR qglDisable(GL_ALPHA_TEST);CHECKGLERROR - qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR + if (qglBlendFuncSeparate) + { + qglBlendFuncSeparate(gl_state.blendfunc1, gl_state.blendfunc2, GL_ZERO, GL_ONE);CHECKGLERROR // ELUAN: Adreno 225 (and others) compositing workaround + } + else + { + qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR + } qglDisable(GL_BLEND);CHECKGLERROR qglCullFace(gl_state.cullface);CHECKGLERROR qglDisable(GL_CULL_FACE);CHECKGLERROR @@ -1767,12 +1779,14 @@ void GL_ClientActiveTexture(unsigned int num) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: +#ifndef USE_GLES2 if (qglActiveTexture) { CHECKGLERROR qglClientActiveTexture(GL_TEXTURE0 + gl_state.clientunit); CHECKGLERROR } +#endif break; case RENDERPATH_D3D9: case RENDERPATH_D3D10: @@ -1803,7 +1817,14 @@ void GL_BlendFunc(int blendfunc1, int blendfunc2) case RENDERPATH_GLES1: case RENDERPATH_GLES2: CHECKGLERROR - qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR + if (qglBlendFuncSeparate) + { + qglBlendFuncSeparate(gl_state.blendfunc1, gl_state.blendfunc2, GL_ZERO, GL_ONE);CHECKGLERROR // ELUAN: Adreno 225 (and others) compositing workaround + } + else + { + qglBlendFunc(gl_state.blendfunc1, gl_state.blendfunc2);CHECKGLERROR + } if (gl_state.blend != blendenable) { gl_state.blend = blendenable; @@ -2044,7 +2065,7 @@ void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int fro } else if (vid.support.ext_stencil_two_side) { -#ifdef GL_STENCIL_TEST_TWO_SIDE_EXT +#if defined(GL_STENCIL_TEST_TWO_SIDE_EXT) && !defined(USE_GLES2) qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR qglActiveStencilFaceEXT(GL_FRONT);CHECKGLERROR qglStencilMask(writemask);CHECKGLERROR @@ -2412,9 +2433,11 @@ void GL_Color(float cr, float cg, float cb, float ca) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: +#ifndef USE_GLES2 CHECKGLERROR qglColor4f(gl_state.color4f[0], gl_state.color4f[1], gl_state.color4f[2], gl_state.color4f[3]); CHECKGLERROR +#endif break; case RENDERPATH_D3D9: case RENDERPATH_D3D10: @@ -2508,7 +2531,8 @@ void GL_ScissorTest(int state) void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue) { - static const float blackcolor[4] = {0, 0, 0, 0}; + // opaque black - if you want transparent black, you'll need to pass in a colorvalue + static const float blackcolor[4] = {0.0f, 0.0f, 0.0f, 1.0f}; // prevent warnings when trying to clear a buffer that does not exist if (!colorvalue) colorvalue = blackcolor; @@ -2573,8 +2597,30 @@ void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpi case RENDERPATH_GLES1: case RENDERPATH_GLES2: CHECKGLERROR +#ifndef GL_BGRA + { + int i; + int r; + // int g; + int b; + // int a; + qglReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR + for (i = 0;i < width * height * 4;i += 4) + { + r = outpixels[i+0]; + // g = outpixels[i+1]; + b = outpixels[i+2]; + // a = outpixels[i+3]; + outpixels[i+0] = b; + // outpixels[i+1] = g; + outpixels[i+2] = r; + // outpixels[i+3] = a; + } + } +#else qglReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, outpixels);CHECKGLERROR - break; +#endif + break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D { @@ -2696,7 +2742,7 @@ unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **ver if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list)) goto cleanup; -#ifdef GL_GEOMETRY_SHADER +#if defined(GL_GEOMETRY_SHADER) && !defined(USE_GLES2) if (geometrystrings_count && !GL_Backend_CompileShader(programobject, GL_GEOMETRY_SHADER, "geometry", geometrystrings_count, geometrystrings_list)) goto cleanup; #endif @@ -2707,10 +2753,13 @@ unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **ver qglLinkProgram(programobject);CHECKGLERROR qglGetProgramiv(programobject, GL_LINK_STATUS, &programlinked);CHECKGLERROR qglGetProgramInfoLog(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR + if (linklog[0]) { + if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning") || developer_extra.integer) Con_DPrintf("program link log:\n%s\n", linklog); + // software vertex shader is ok but software fragment shader is WAY // too slow, fail program if so. // NOTE: this string might be ATI specific, but that's ok because the @@ -2720,8 +2769,10 @@ unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **ver if (strstr(linklog, "fragment shader will run in software")) programlinked = false; } + if (!programlinked) goto cleanup; + return programobject; cleanup: qglDeleteProgram(programobject);CHECKGLERROR @@ -3112,7 +3163,7 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri else #endif { - qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3]))); + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s); CHECKGLERROR } } @@ -3128,7 +3179,7 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri else #endif { - qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3]))); + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)bufferoffset3i); CHECKGLERROR } } @@ -3209,44 +3260,28 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtri break; case RENDERPATH_GLES1: case RENDERPATH_GLES2: - // GLES does not have glDrawRangeElements, and generally - // underperforms with index buffers, so this code path is - // relatively straightforward... -#if 0 - if (gl_paranoid.integer) + // GLES does not have glDrawRangeElements so this is a bit shorter than the GL20 path + if (bufferobject3s) { - int r, prog, enabled, i; - GLsizei attriblength; - GLint attribsize; - GLenum attribtype; - GLchar attribname[1024]; - r = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (r != GL_FRAMEBUFFER_COMPLETE) - Con_DPrintf("fbo %i not complete (default %i)\n", gl_state.framebufferobject, gl_state.defaultframebufferobject); -#ifndef GL_CURRENT_PROGRAM -#define GL_CURRENT_PROGRAM 0x8B8D -#endif - qglGetIntegerv(GL_CURRENT_PROGRAM, &r);CHECKGLERROR - if (r < 0 || r > 10000) - Con_DPrintf("GL_CURRENT_PROGRAM = %i\n", r); - prog = r; - for (i = 0;i < 8;i++) - { - qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &r);CHECKGLERROR - if (!r) - continue; - qglGetActiveAttrib(prog, i, sizeof(attribname), &attriblength, &attribsize, &attribtype, attribname);CHECKGLERROR - Con_DPrintf("prog %i position %i length %i size %04X type %i name \"%s\"\n", prog, i, (int)attriblength, (int)attribsize, (int)attribtype, (char *)attribname); - } + GL_BindEBO(bufferobject3s); + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)bufferoffset3s); + CHECKGLERROR } -#endif - if (element3s) + 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 } @@ -3326,10 +3361,19 @@ void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t si GL_BindEBO(buffer->bufferobject); else GL_BindVBO(buffer->bufferobject); - if (subdata) - qglBufferSubDataARB(buffer->isuniformbuffer ? GL_UNIFORM_BUFFER : (buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER), offset, size, data); - else - qglBufferDataARB(buffer->isuniformbuffer ? GL_UNIFORM_BUFFER : (buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER), size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW); + + { + int buffertype; + buffertype = buffer->isindexbuffer ? GL_ELEMENT_ARRAY_BUFFER : GL_ARRAY_BUFFER; +#ifdef GL_UNIFORM_BUFFER + if (buffer->isuniformbuffer) + buffertype = GL_UNIFORM_BUFFER; +#endif + if (subdata) + qglBufferSubDataARB(buffertype, offset, size, data); + else + qglBufferDataARB(buffertype, size, data, buffer->isdynamic ? GL_STREAM_DRAW : GL_STATIC_DRAW); + } if (buffer->isuniformbuffer) GL_BindUBO(0); break; @@ -3498,6 +3542,7 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: +#ifndef USE_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; @@ -3511,6 +3556,7 @@ void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void GL_BindVBO(bufferobject); qglVertexPointer(components, gltype, stride, bufferobject ? (void *)bufferoffset : pointer);CHECKGLERROR } +#endif break; case RENDERPATH_GL20: case RENDERPATH_GLES2: @@ -3546,7 +3592,7 @@ void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void * case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: -#ifdef GL_MODELVIEW +#ifndef USE_GLES2 CHECKGLERROR if (pointer) { @@ -3644,7 +3690,7 @@ void R_Mesh_TexCoordPointer(unsigned int unitnum, int components, int gltype, si case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: -#ifdef GL_MODELVIEW +#ifndef USE_GLES2 CHECKGLERROR if (pointer) { @@ -3984,7 +4030,6 @@ void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex) void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix) { - gltextureunit_t *unit = gl_state.units + unitnum; switch(vid.renderpath) { case RENDERPATH_GL11: @@ -3995,6 +4040,7 @@ void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix) #ifdef GL_MODELVIEW if (matrix && matrix->m[3][3]) { + gltextureunit_t *unit = gl_state.units + unitnum; // texmatrix specified, check if it is different if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t))) { @@ -4012,6 +4058,7 @@ void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix) else { // no texmatrix specified, revert to identity + gltextureunit_t *unit = gl_state.units + unitnum; if (unit->texmatrixenabled) { unit->texmatrixenabled = false; @@ -4036,6 +4083,7 @@ void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix) void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale) { +#if defined(GL_TEXTURE_ENV) && !defined(USE_GLES2) gltextureunit_t *unit = gl_state.units + unitnum; CHECKGLERROR switch(vid.renderpath) @@ -4046,7 +4094,6 @@ void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, i break; case RENDERPATH_GL13: case RENDERPATH_GLES1: -#ifdef GL_TEXTURE_ENV // GL_ARB_texture_env_combine if (!combinergb) combinergb = GL_MODULATE; @@ -4101,11 +4148,9 @@ void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, i qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR } } -#endif break; case RENDERPATH_GL11: // normal GL texenv -#ifdef GL_TEXTURE_ENV if (!combinergb) combinergb = GL_MODULATE; if (unit->combine != combinergb) @@ -4114,7 +4159,6 @@ void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, i GL_ActiveTexture(unitnum); qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR } -#endif break; case RENDERPATH_D3D9: case RENDERPATH_D3D10: @@ -4123,6 +4167,7 @@ void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, i case RENDERPATH_SOFT: break; } +#endif } void R_Mesh_ResetTextureState(void)