- for (i = 0;i < backendunits;i++)
- {
- GL_ActiveTexture(i);
- qglDisable(GL_TEXTURE_1D);CHECKGLERROR
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- if (gl_texture3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- if (gl_texturecubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- qglMatrixMode(GL_TEXTURE);CHECKGLERROR
- qglLoadIdentity();CHECKGLERROR
- qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
- if (gl_combine.integer)
- {
- qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
- }
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
+}
+
+void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, const float *nearplane)
+{
+ matrix4x4_t tempmatrix, basematrix;
+ const float nudge = 1.0 - 1.0 / (1<<23);
+ float m[16];
+ memset(v, 0, sizeof(*v));
+
+ v->type = R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP;
+ v->cameramatrix = *cameramatrix;
+ v->x = x;
+ v->y = y;
+ v->z = 0;
+ v->width = width;
+ v->height = height;
+ v->depth = 1;
+ memset(m, 0, sizeof(m));
+ m[ 0] = 1.0 / frustumx;
+ m[ 5] = 1.0 / frustumy;
+ m[10] = -nudge;
+ m[11] = -1;
+ m[14] = -2 * nearclip * nudge;
+ v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
+ v->screentodepth[1] = m[14] * -0.5;
+
+ Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
+ Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
+ Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
+ Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
+
+ if (nearplane)
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ if(v_flipped.integer)
+ {
+ m[0] = -m[0];
+ m[4] = -m[4];
+ m[8] = -m[8];
+ m[12] = -m[12];
+ }
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
+}
+
+float cubeviewmatrix[6][16] =
+{
+ // standard cubemap projections
+ { // +X
+ 0, 0,-1, 0,
+ 0,-1, 0, 0,
+ -1, 0, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // -X
+ 0, 0, 1, 0,
+ 0,-1, 0, 0,
+ 1, 0, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // +Y
+ 1, 0, 0, 0,
+ 0, 0,-1, 0,
+ 0, 1, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // -Y
+ 1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0,-1, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // +Z
+ 1, 0, 0, 0,
+ 0,-1, 0, 0,
+ 0, 0,-1, 0,
+ 0, 0, 0, 1,
+ },
+ { // -Z
+ -1, 0, 0, 0,
+ 0,-1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1,
+ },
+};
+float rectviewmatrix[6][16] =
+{
+ // sign-preserving cubemap projections
+ { // +X
+ 0, 0,-1, 0,
+ 0, 1, 0, 0,
+ 1, 0, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // -X
+ 0, 0, 1, 0,
+ 0, 1, 0, 0,
+ 1, 0, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // +Y
+ 1, 0, 0, 0,
+ 0, 0,-1, 0,
+ 0, 1, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // -Y
+ 1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, 1, 0, 0,
+ 0, 0, 0, 1,
+ },
+ { // +Z
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0,-1, 0,
+ 0, 0, 0, 1,
+ },
+ { // -Z
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1,
+ },
+};
+
+void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
+{
+ matrix4x4_t tempmatrix, basematrix;
+ float m[16];
+ memset(v, 0, sizeof(*v));
+ v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
+ v->cameramatrix = *cameramatrix;
+ v->width = size;
+ v->height = size;
+ v->depth = 1;
+ memset(m, 0, sizeof(m));
+ m[0] = m[5] = 1.0f;
+ m[10] = -(farclip + nearclip) / (farclip - nearclip);
+ m[11] = -1;
+ m[14] = -2 * nearclip * farclip / (farclip - nearclip);
+
+ Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
+ Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
+ Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
+
+ if (nearplane)
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
+}
+
+void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, int border, float nearclip, float farclip, const float *nearplane, int offsetx, int offsety)
+{
+ matrix4x4_t tempmatrix, basematrix;
+ float m[16];
+ memset(v, 0, sizeof(*v));
+ v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
+ v->cameramatrix = *cameramatrix;
+ v->x = offsetx + (side & 1) * size;
+ v->y = offsety + (side >> 1) * size;
+ v->width = size;
+ v->height = size;
+ v->depth = 1;
+ memset(m, 0, sizeof(m));
+ m[0] = m[5] = 1.0f * ((float)size - border) / size;
+ m[10] = -(farclip + nearclip) / (farclip - nearclip);
+ m[11] = -1;
+ m[14] = -2 * nearclip * farclip / (farclip - nearclip);
+
+ Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
+ Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
+ Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
+
+ if (nearplane)
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
+}
+
+void R_SetViewport(const r_viewport_t *v)
+{
+ gl_viewport = *v;
+
+ // FIXME: v_flipped_state is evil, this probably breaks somewhere
+ GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
+
+ // copy over the matrices to our state
+ gl_viewmatrix = v->viewmatrix;
+ gl_projectionmatrix = v->projectmatrix;
+
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL32:
+ case RENDERPATH_GLES2:
+ CHECKGLERROR
+ qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
+ break;
+ }
+
+ // force an update of the derived matrices
+ gl_modelmatrixchanged = true;
+ R_EntityMatrix(&gl_modelmatrix);
+}
+
+void R_GetViewport(r_viewport_t *v)
+{
+ *v = gl_viewport;
+}
+
+static void GL_BindVBO(int bufferobject)
+{
+ if (gl_state.vertexbufferobject != bufferobject)
+ {
+ gl_state.vertexbufferobject = bufferobject;
+ CHECKGLERROR
+ qglBindBuffer(GL_ARRAY_BUFFER, bufferobject);CHECKGLERROR
+ }
+}
+
+static void GL_BindEBO(int bufferobject)
+{
+ if (gl_state.elementbufferobject != bufferobject)
+ {
+ gl_state.elementbufferobject = bufferobject;
+ CHECKGLERROR
+ qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferobject);CHECKGLERROR
+ }
+}
+
+static void GL_BindUBO(int bufferobject)
+{
+ if (gl_state.uniformbufferobject != bufferobject)
+ {
+ gl_state.uniformbufferobject = bufferobject;
+#ifdef GL_UNIFORM_BUFFER
+ 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_GL32:
+ case RENDERPATH_GLES2:
+ 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
+#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
+ }
+#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
+
+#ifndef USE_GLES2
+ if (colortexture4)
+ {
+ qglDrawBuffers(4, drawbuffers);CHECKGLERROR
+ qglReadBuffer(GL_NONE);CHECKGLERROR
+ }
+ else if (colortexture3)
+ {
+ 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
+ }