/* ================ RB_SetGL2D ================ */ void RB_SetGL2D (void) { backEnd.projection2D = qtrue; // set 2D virtual screen size qglViewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); qglOrtho (0, glConfig.vidWidth, glConfig.vidHeight, 0, 0, 1); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); qglGetFloatv(GL_PROJECTION_MATRIX, glState.currentProjectionMatrix); qglGetFloatv(GL_MODELVIEW_MATRIX, glState.currentModelViewMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); qglDisable( GL_CULL_FACE ); qglDisable( GL_CLIP_PLANE0 ); // set time for 2D shaders backEnd.refdef.time = ri.Milliseconds(); backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f; }
//============================================================================= // XYZ軸回転マトリックス生成 //============================================================================= void MATRIX4::Matrix4Rotation(MATRIX4 * MtxOut, float x, float y, float z) { MATRIX4 mtxRotX, mtxRotY, mtxRotZ; float sinx, cosx, siny, cosy, sinz, cosz; sinx = sinf(x); cosx = cosf(x); siny = sinf(y); cosy = cosf(y); sinz = sinf(z); cosz = cosf(z); // 単位行列作成 Matrix4Identity(MtxOut); Matrix4Identity(&mtxRotX); Matrix4Identity(&mtxRotY); Matrix4Identity(&mtxRotZ); // XYZ回転行列作成 mtxRotX.m22 = cosx; mtxRotX.m23 = sinx; mtxRotX.m32 = -sinx; mtxRotX.m33 = cosx; mtxRotY.m11 = cosy; mtxRotY.m13 = -siny; mtxRotY.m31 = siny; mtxRotY.m33 = cosy; mtxRotZ.m11 = cosz; mtxRotZ.m12 = sinz; mtxRotZ.m21 = -sinz; mtxRotZ.m22 = cosz; // XYZ回転行列の作成 Matrix4Multiply(MtxOut, &mtxRotX, &mtxRotY); Matrix4Multiply(MtxOut, MtxOut, &mtxRotZ); }
static void SetViewportAndScissor( void ) { qglMatrixMode(GL_PROJECTION); qglLoadMatrixf( backEnd.viewParms.projectionMatrix ); qglMatrixMode(GL_MODELVIEW); // set the window clipping qglViewport( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight ); qglScissor( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight ); Matrix4Copy(backEnd.viewParms.projectionMatrix, glState.currentProjectionMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); }
Matrix4 Matrix4::operator*(const spades::Matrix4 &other) const { Matrix4 out; Matrix4Multiply(m, other.m, out.m); return Matrix4(out); }
/* ================== RB_RenderDrawSurfList ================== */ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { shader_t *shader, *oldShader; int fogNum, oldFogNum; int entityNum, oldEntityNum; int dlighted, oldDlighted; qboolean depthRange, oldDepthRange, isCrosshair, wasCrosshair; int i; drawSurf_t *drawSurf; int oldSort; float originalTime; // save original time for entity shader offsets originalTime = backEnd.refdef.floatTime; // clear the z buffer, set the modelview, etc RB_BeginDrawingView (); // draw everything oldEntityNum = -1; backEnd.currentEntity = &tr.worldEntity; oldShader = NULL; oldFogNum = -1; oldDepthRange = qfalse; wasCrosshair = qfalse; oldDlighted = qfalse; oldSort = -1; depthRange = qfalse; backEnd.pc.c_surfaces += numDrawSurfs; for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) { if ( drawSurf->sort == oldSort ) { // fast path, same as previous sort rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface ); continue; } oldSort = drawSurf->sort; R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted ); // // change the tess parameters if needed // a "entityMergable" shader is a shader that can have surfaces from seperate // entities merged into a single batch, like smoke and blood puff sprites if (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted || ( entityNum != oldEntityNum && !shader->entityMergable ) ) { if (oldShader != NULL) { RB_EndSurface(); } RB_BeginSurface( shader, fogNum ); oldShader = shader; oldFogNum = fogNum; oldDlighted = dlighted; } // // change the modelview matrix if needed // if ( entityNum != oldEntityNum ) { depthRange = isCrosshair = qfalse; if ( entityNum != REFENTITYNUM_WORLD ) { backEnd.currentEntity = &backEnd.refdef.entities[entityNum]; backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime; // we have to reset the shaderTime as well otherwise image animations start // from the wrong frame tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset; // set up the transformation matrix R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or ); // set up the dynamic lighting if needed if ( backEnd.currentEntity->needDlights ) { R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or ); } if(backEnd.currentEntity->e.renderfx & RF_DEPTHHACK) { // hack the depth range to prevent view model from poking into walls depthRange = qtrue; if(backEnd.currentEntity->e.renderfx & RF_CROSSHAIR) isCrosshair = qtrue; } } else { backEnd.currentEntity = &tr.worldEntity; backEnd.refdef.floatTime = originalTime; backEnd.or = backEnd.viewParms.world; // we have to reset the shaderTime as well otherwise image animations on // the world (like water) continue with the wrong frame tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset; R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or ); } qglLoadMatrixf( backEnd.or.modelMatrix ); Matrix4Copy(backEnd.or.modelMatrix, glState.currentModelViewMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); // // change depthrange. Also change projection matrix so first person weapon does not look like coming // out of the screen. // if (oldDepthRange != depthRange || wasCrosshair != isCrosshair) { if (depthRange) { if(backEnd.viewParms.stereoFrame != STEREO_CENTER) { if(isCrosshair) { if(oldDepthRange) { // was not a crosshair but now is, change back proj matrix qglMatrixMode(GL_PROJECTION); qglLoadMatrixf(backEnd.viewParms.projectionMatrix); qglMatrixMode(GL_MODELVIEW); Matrix4Copy(backEnd.viewParms.projectionMatrix, glState.currentProjectionMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); } } else { viewParms_t temp = backEnd.viewParms; R_SetupProjection(&temp, r_znear->value, qfalse); qglMatrixMode(GL_PROJECTION); qglLoadMatrixf(temp.projectionMatrix); qglMatrixMode(GL_MODELVIEW); Matrix4Copy(temp.projectionMatrix, glState.currentProjectionMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); } } if(!oldDepthRange) qglDepthRange (0, 0.3); } else { if(!wasCrosshair && backEnd.viewParms.stereoFrame != STEREO_CENTER) { qglMatrixMode(GL_PROJECTION); qglLoadMatrixf(backEnd.viewParms.projectionMatrix); qglMatrixMode(GL_MODELVIEW); Matrix4Copy(backEnd.viewParms.projectionMatrix, glState.currentProjectionMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); } qglDepthRange (0, 1); } oldDepthRange = depthRange; wasCrosshair = isCrosshair; } oldEntityNum = entityNum; } // add the triangles for this surface rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface ); } backEnd.refdef.floatTime = originalTime; // draw the contents of the last shader batch if (oldShader != NULL) { RB_EndSurface(); } // go back to the world modelview matrix qglLoadMatrixf( backEnd.viewParms.world.modelMatrix ); Matrix4Copy(backEnd.viewParms.world.modelMatrix, glState.currentModelViewMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); if ( depthRange ) { qglDepthRange (0, 1); } #if 0 RB_DrawSun(); #endif // darken down any stencil shadows RB_ShadowFinish(); // add light flares on lights that aren't obscured RB_RenderFlares(); }
/* ================= RB_BeginDrawingView Any mirrored or portaled views have already been drawn, so prepare to actually render the visible surfaces for this view ================= */ void RB_BeginDrawingView (void) { int clearBits = 0; // sync with gl if needed if ( r_finish->integer == 1 && !glState.finishCalled ) { qglFinish (); glState.finishCalled = qtrue; } if ( r_finish->integer == 0 ) { glState.finishCalled = qtrue; } // we will need to change the projection matrix before drawing // 2D images again backEnd.projection2D = qfalse; // ensures that depth writes are enabled for the depth clear GL_State( GLS_DEFAULT ); // clear relevant buffers clearBits = GL_DEPTH_BUFFER_BIT; if ( r_measureOverdraw->integer || r_shadows->integer == 2 ) { clearBits |= GL_STENCIL_BUFFER_BIT; } if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used #ifdef _DEBUG qglClearColor( 0.8f, 0.7f, 0.4f, 1.0f ); // FIXME: get color of sky #else qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky #endif } qglClear( clearBits ); // // set the modelview matrix for the viewer // SetViewportAndScissor(); if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) ) { RB_Hyperspace(); return; } else { backEnd.isHyperspace = qfalse; } glState.faceCulling = -1; // force face culling to set next time // we will only draw a sun if there was sky rendered in this view backEnd.skyRenderedThisView = qfalse; // clip to the plane of the portal if ( backEnd.viewParms.isPortal ) { float plane[4]; double plane2[4]; plane[0] = backEnd.viewParms.portalPlane.normal[0]; plane[1] = backEnd.viewParms.portalPlane.normal[1]; plane[2] = backEnd.viewParms.portalPlane.normal[2]; plane[3] = backEnd.viewParms.portalPlane.dist; plane2[0] = DotProduct (backEnd.viewParms.or.axis[0], plane); plane2[1] = DotProduct (backEnd.viewParms.or.axis[1], plane); plane2[2] = DotProduct (backEnd.viewParms.or.axis[2], plane); plane2[3] = DotProduct (plane, backEnd.viewParms.or.origin) - plane[3]; qglLoadMatrixf( s_flipMatrix ); Matrix4Copy(s_flipMatrix, glState.currentModelViewMatrix); Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix); qglClipPlane (GL_CLIP_PLANE0, plane2); qglEnable (GL_CLIP_PLANE0); } else { qglDisable (GL_CLIP_PLANE0); } }