void Pass2D::setup(GLRenderer *r) { Pass::setup(r); GL_Enable(GL_SCISSOR_TEST); GL_Disable(GL_LIGHTING); GL_Disable(GL_DEPTH_TEST); GL_Disable(GL_CULL_FACE); GL_Enable(GL_BLEND); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glAlphaFunc(GL_GREATER, 0.01f); Cvar_SetVarValue(&gfx_GLSLPass, 0); GL_TexModulate(1.0); GL_UseProgram(0); GL_MatrixMode(GL_PROJECTION); GL_PushMatrix(); glLoadIdentity(); glOrtho(0, Vid_GetScreenW(), Vid_GetScreenH(), 0, -1.0, 1.0); GL_MatrixMode(GL_MODELVIEW); GL_PushMatrix(); glLoadIdentity(); #ifdef DEBUG GLSL_catchLastError("Pass2D::setup(): "); #endif }
void GLRenderListWaterItem::renderPass(GLRenderer *r, bool renderPass, bool loadMatrix, unsigned int materialPass) { sceneobj_t obj; float waterlevel = gfx_waterlevel.value*world_waterlevel.value; if(!gfx_water.integer) return; CLEAR_SCENEOBJ(obj); SET_VEC3(obj.pos, world.gridwidth*WORLD_BASE_SIZE*0.5f, world.gridheight*WORLD_BASE_SIZE*0.5f, waterlevel); SET_VEC4(obj.color, gfx_waterr.value, gfx_waterg.value, gfx_waterb.value, gfx_wateralpha.value); //decide on flags meshFlags = watermat->generateMeshFlags(); obj.flags |= SCENEOBJ_SOLID_COLOR | SCENEOBJ_SINGLE_SHADER; GL_MatrixMode(GL_MODELVIEW); GL_PushMatrix(); GL_LoadObjectMatrix(&obj); watermat->construct(r->getCurrentPass()); for(int pass=0;pass<watermat->countMaterialPasses();pass++) { watermat->renderMaterialPass(pass, &obj); GL_DrawMesh(&obj, &water_model->meshes[0], meshFlags, true); } GL_PopMatrix(); }
/* ============== R_ShadowBlend Draws projection shadow(s) from stenciled volume ============== */ void R_ShadowBlend (float shadowalpha) { const vec4_t color[4] = { {0, 0, 0, shadowalpha}, {0, 0, 0, shadowalpha}, {0, 0, 0, shadowalpha}, {0, 0, 0, shadowalpha} }; static const vec3_t verts[4] = { {10, 100, 100}, {10, -100, 100}, {10, -100, -100}, {10, 100, -100} }; static const uint32_t indices[6] = { 0, 1, 2, 0, 2, 3 }; if (r_shadows->value != 3) return; GL_PushMatrix(GL_MODELVIEW); GL_LoadMatrix(GL_MODELVIEW, glState.axisRotation); GL_Disable (GL_ALPHA_TEST); GL_Enable (GL_BLEND); GL_Disable (GL_DEPTH_TEST); GL_DisableTexture(0); GL_StencilFunc(GL_NOTEQUAL, 0, 255); glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); GL_Enable(GL_STENCIL_TEST); rb_vertex = rb_index = 0; memcpy(indexArray, indices, sizeof(indices)); memcpy(vertexArray, verts, sizeof(vec3_t) * 4); memcpy(colorArray, color, sizeof(vec4_t) * 4); rb_index += 6; rb_vertex += 4; RB_RenderMeshGeneric (false); GL_PopMatrix(GL_MODELVIEW); GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_Disable (GL_BLEND); GL_EnableTexture(0); GL_Enable (GL_DEPTH_TEST); GL_Disable(GL_STENCIL_TEST); //GL_Enable (GL_ALPHA_TEST); glColor4f(1,1,1,1); }
//// HELPER FUNCTIONS //// void GL_PushCamera(camera_t *camera) { if(camera->use_viewport) { glViewport(camera->x, camera->y, camera->width, camera->height); glScissor(camera->x, camera->y, camera->width, camera->height); } GL_MatrixMode(GL_PROJECTION); GL_PushMatrix(); glLoadIdentity(); camera->aspect = (float)camera->width / (float)camera->height; gluPerspective(camera->fovy, camera->aspect, camera->nearclip, /*camera->fog_far ? camera->fog_far+200 :*/ camera->farclip); #ifdef DEBUG GLSL_catchLastError("GL_PushCamera :: PROJECTION"); #endif GL_MatrixMode(GL_MODELVIEW); GL_PushMatrix(); //set up the inverse of the camera's matrix (axis and position) Cam_ConstructOpenGLMat44(camera, ¤tTransformMatrix); glLoadMatrixf(currentTransformMatrix.matrix); //glLoadIdentity(); //glRotatef(-90, 1, 0, 0); //rotate around the x axis so viewaxis[Z] points UP from our viewpoint //glMultMatrixf(currentTransformMatrix.matrix); //glTranslatef(tr[AXIS_RIGHT],tr[AXIS_FORWARD],tr[AXIS_UP]); #ifdef DEBUG //float mat[16]; //glGetFloatv(GL_PROJECTION_MATRIX, mat); GLSL_catchLastError("GL_PushCamera :: MODELVIEW"); #endif rot_tm[0] = currentTransformMatrix.matrix[0]; rot_tm[1] = currentTransformMatrix.matrix[1]; rot_tm[2] = currentTransformMatrix.matrix[2]; rot_tm[3] = currentTransformMatrix.matrix[4]; rot_tm[4] = currentTransformMatrix.matrix[5]; rot_tm[5] = currentTransformMatrix.matrix[6]; rot_tm[6] = currentTransformMatrix.matrix[8]; rot_tm[7] = currentTransformMatrix.matrix[9]; rot_tm[8] = currentTransformMatrix.matrix[10]; }
void GL_PushCSMCamera(camera_t *light, camera_t *viewer, int split) { Cam_ConstructOpenGLMat44(light, &lightView); updateFrustumPoints(shadowFrusta[split], viewer); /*float minZ =*/ applyCropMatrix(shadowFrusta[split], lightView, split); GL_MatrixMode(GL_MODELVIEW); GL_PushMatrix(); glLoadIdentity(); glMultMatrixf(lightView.matrix); }
/* ** RB_DrawSun */ void RB_DrawSun( void ) { #if 0 float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; matrix_t transformMatrix; matrix_t modelViewMatrix; if ( !backEnd.skyRenderedThisView ) { return; } if ( !r_drawSun->integer ) { return; } GL_PushMatrix(); GL_BindProgram( &tr.genericShader ); // set uniforms GLSL_SetUniform_TCGen_Environment( &tr.genericShader, qfalse ); GLSL_SetUniform_InverseVertexColor( &tr.genericShader, qfalse ); if ( glConfig2.vboVertexSkinningAvailable ) { GLSL_SetUniform_VertexSkinning( &tr.genericShader, qfalse ); } GLSL_SetUniform_DeformGen( &tr.genericShader, DGEN_NONE ); GLSL_SetUniform_AlphaTest( &tr.genericShader, -1.0 ); MatrixSetupTranslation( transformMatrix, backEnd.viewParms.orientation.origin[ 0 ], backEnd.viewParms.orientation.origin[ 1 ], backEnd.viewParms.orientation.origin[ 2 ] ); MatrixMultiply( backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix ); GL_LoadProjectionMatrix( backEnd.viewParms.projectionMatrix ); GL_LoadModelViewMatrix( modelViewMatrix ); GLSL_SetUniform_ModelMatrix( &tr.genericShader, backEnd.orientation.transformMatrix ); GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] ); GLSL_SetUniform_PortalClipping( &tr.genericShader, backEnd.viewParms.isPortal ); if ( backEnd.viewParms.isPortal ) { float plane[ 4 ]; // clipping plane in world space 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; GLSL_SetUniform_PortalPlane( &tr.genericShader, plane ); } dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3) size = dist * 0.4; VectorScale( tr.sunDirection, dist, origin ); PerpendicularVector( vec1, tr.sunDirection ); CrossProduct( tr.sunDirection, vec1, vec2 ); VectorScale( vec1, size, vec1 ); VectorScale( vec2, size, vec2 ); // farthest depth range glDepthRange( 1.0, 1.0 ); // FIXME: use quad stamp Tess_Begin( Tess_StageIteratorGeneric, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum ); VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0; tess.texCoords[ tess.numVertexes ][ 1 ] = 0; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorSubtract( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 0; tess.texCoords[ tess.numVertexes ][ 1 ] = 1; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorAdd( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 1; tess.texCoords[ tess.numVertexes ][ 1 ] = 1; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; VectorCopy( origin, temp ); VectorSubtract( temp, vec1, temp ); VectorAdd( temp, vec2, temp ); VectorCopy( temp, tess.xyz[ tess.numVertexes ] ); tess.xyz[ tess.numVertexes ][ 3 ] = 1; tess.texCoords[ tess.numVertexes ][ 0 ] = 1; tess.texCoords[ tess.numVertexes ][ 1 ] = 0; tess.texCoords[ tess.numVertexes ][ 2 ] = 0; tess.texCoords[ tess.numVertexes ][ 3 ] = 1; tess.colors[ tess.numVertexes ][ 0 ] = 1; tess.colors[ tess.numVertexes ][ 1 ] = 1; tess.colors[ tess.numVertexes ][ 2 ] = 1; tess.numVertexes++; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 1; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 3; Tess_End(); // back to standard depth range glDepthRange( 0.0, 1.0 ); GL_PopMatrix(); #endif }
/* ================== RB_RenderFlares Because flares are simulating an occular effect, they should be drawn after everything (all views) in the entire frame has been drawn. Because of the way portals use the depth buffer to mark off areas, the needed information would be lost after each view, so we are forced to draw flares after each view. The resulting artifact is that flares in mirrors or portals don't dim properly when occluded by something in the main view, and portal flares that should extend past the portal edge will be overwritten. ================== */ void RB_RenderFlares(void) { flare_t *f; flare_t **prev; qboolean draw; matrix_t ortho; if(!r_flares->integer) return; #if 0 if(r_flareCoeff->modified) { if(r_flareCoeff->value == 0.0f) flareCoeff = atof("150"); else flareCoeff = r_flareCoeff->value; r_flareCoeff->modified = qfalse; } #endif // reset currentEntity to world so that any previously referenced entities don't have influence // on the rendering of these flares (i.e. RF_ renderer flags). backEnd.currentEntity = &tr.worldEntity; backEnd.orientation = backEnd.viewParms.world; GL_LoadModelViewMatrix(backEnd.viewParms.world.modelViewMatrix); if(tr.world != NULL) // thx Thilo { RB_AddLightFlares(); } // perform z buffer readback on each flare in this view draw = qfalse; prev = &r_activeFlares; while((f = *prev) != NULL) { // throw out any flares that weren't added last frame if(f->addedFrame < backEnd.viewParms.frameCount - 1) { *prev = f->next; f->next = r_inactiveFlares; r_inactiveFlares = f; continue; } // don't draw any here that aren't from this scene / portal f->drawIntensity = 0; if(f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal) { RB_TestFlare(f); if(f->drawIntensity) { draw = qtrue; } else { // this flare has completely faded out, so remove it from the chain *prev = f->next; f->next = r_inactiveFlares; r_inactiveFlares = f; continue; } } prev = &f->next; } if(!draw) { // none visible return; } if(backEnd.viewParms.isPortal) { qglDisable(GL_CLIP_PLANE0); } GL_CheckErrors(); GL_PushMatrix(); MatrixOrthogonalProjection(ortho, backEnd.viewParms.viewportX, backEnd.viewParms.viewportX + backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportY, backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight, -99999, 99999); GL_LoadProjectionMatrix(ortho); GL_LoadModelViewMatrix(matrixIdentity); for(f = r_activeFlares; f; f = f->next) { if(f->frameSceneNum == backEnd.viewParms.frameSceneNum && f->inPortal == backEnd.viewParms.isPortal && f->drawIntensity) RB_RenderFlare(f); } GL_PopMatrix(); GL_CheckErrors(); }
float applyCropMatrix(frustum_t &f, matrix44_t &mv, int split) { matrix44_t shadowMVP, shadowProj, tween; vec3_t bmin, bmax, extents[5]; vec4_t trans; SET_VEC4(trans, f.point[0][0], f.point[0][1], f.point[0][2], 1); M_VectorMatrixMult4(trans, &mv, trans); SET_VEC3(bmin, 100000, 100000, trans[AXIS_Z]); SET_VEC3(bmax, -100000, -100000, trans[AXIS_Z]); for(int i=1;i<8;i++) { SET_VEC4(trans, f.point[i][0], f.point[i][1], f.point[i][2], 1); M_VectorMatrixMult4(trans, &mv, trans); bmax[AXIS_Z] = MAX(bmax[AXIS_Z], trans[AXIS_Z]); bmin[AXIS_Z] = MIN(bmin[AXIS_Z], trans[AXIS_Z]); } //make sure all casters are included in depth (this makes things a bit crappy sometimes but whatever) World_GetExtents(extents); for(int i=0;i<5;i++) { SET_VEC4(trans, extents[i][0], extents[i][2], extents[i][1], 1); M_VectorMatrixMult4(trans, &mv, trans); bmax[AXIS_Z] = MAX(bmax[AXIS_Z], trans[AXIS_Z]); bmin[AXIS_Z] = MIN(bmin[AXIS_Z], trans[AXIS_Z]); } bmin[AXIS_Z]-=1050; //oh, the fudge! //an orthogonal projection matrix M_OrthogonalProjection(&shadowProj, -1.0, 1.0, -1.0, 1.0, -bmax[AXIS_Z], -bmin[AXIS_Z]); M_MultiplyMatrix44(&shadowProj, &mv, &shadowMVP); for(int i=0; i<8; i++) { SET_VEC4(trans, f.point[i][0], f.point[i][1], f.point[i][2], 1); M_VectorMatrixMult4(trans, &shadowMVP, trans); trans[AXIS_X] /= trans[3]; trans[AXIS_Y] /= trans[3]; bmin[AXIS_X] = MIN(bmin[AXIS_X], trans[AXIS_X]); bmax[AXIS_X] = MAX(bmax[AXIS_X], trans[AXIS_X]); bmin[AXIS_Y] = MIN(bmin[AXIS_Y], trans[AXIS_Y]); bmax[AXIS_Y] = MAX(bmax[AXIS_Y], trans[AXIS_Y]); } float scaleX = 2.0f/(bmax[AXIS_X]-bmin[AXIS_X]); float scaleY = 2.0f/(bmax[AXIS_Y]-bmin[AXIS_Y]); float offsetX = -0.5f*(bmax[AXIS_X]+bmin[AXIS_X])*scaleX; float offsetY = -0.5f*(bmax[AXIS_Y]+bmin[AXIS_Y])*scaleY; M_Identity44(&shadowMVP); shadowMVP.f.f00 = scaleX; shadowMVP.f.f11 = scaleY; shadowMVP.f.f03 = offsetX*0.05f; shadowMVP.f.f13 = offsetY*0.05f; M_TransposeMat4x4(shadowMVP); GL_MatrixMode(GL_PROJECTION); GL_PushMatrix(); glLoadMatrixf(shadowMVP.matrix); glMultMatrixf(shadowProj.matrix); M_MultiplyMatrix44(&shadowMVP, &shadowProj, &tween); M_MultiplyMatrix44(&tween, &mv, &lightPerspective[split]); return bmin[AXIS_Z]; }
/* ** RB_DrawSun */ void RB_DrawSun(void) { float size; float dist; vec3_t origin, vec1, vec2; vec3_t temp; matrix_t transformMatrix; matrix_t modelViewMatrix; if (!backEnd.skyRenderedThisView) { return; } if (!r_drawSun->integer) { return; } #if defined(USE_D3D10) //TODO #else GL_PushMatrix(); gl_genericShader->DisableAlphaTesting(); gl_genericShader->DisablePortalClipping(); gl_genericShader->DisableVertexSkinning(); gl_genericShader->DisableVertexAnimation(); gl_genericShader->DisableDeformVertexes(); gl_genericShader->DisableTCGenEnvironment(); gl_genericShader->BindProgram(); // set uniforms gl_genericShader->SetUniform_ColorModulate(CGEN_VERTEX, AGEN_VERTEX); #endif MatrixSetupTranslation(transformMatrix, backEnd.viewParms.orientation.origin[0], backEnd.viewParms.orientation.origin[1], backEnd.viewParms.orientation.origin[2]); MatrixMultiplyMOD(backEnd.viewParms.world.viewMatrix, transformMatrix, modelViewMatrix); #if defined(USE_D3D10) //TODO #else GL_LoadProjectionMatrix(backEnd.viewParms.projectionMatrix); GL_LoadModelViewMatrix(modelViewMatrix); gl_genericShader->SetUniform_ModelMatrix(backEnd.orientation.transformMatrix); gl_genericShader->SetUniform_ModelViewProjectionMatrix(glState.modelViewProjectionMatrix[glState.stackIndex]); gl_genericShader->SetPortalClipping(backEnd.viewParms.isPortal); #endif if (backEnd.viewParms.isPortal) { float plane[4]; // clipping plane in world space 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; #if defined(USE_D3D10) //TODO #else gl_genericShader->SetUniform_PortalPlane(plane); #endif } dist = backEnd.viewParms.skyFar / 1.75; // div sqrt(3) size = dist * 0.4; VectorScale(tr.sunDirection, dist, origin); PerpendicularVector(vec1, tr.sunDirection); CrossProduct(tr.sunDirection, vec1, vec2); VectorScale(vec1, size, vec1); VectorScale(vec2, size, vec2); // farthest depth range #if defined(USE_D3D10) //TODO #else glDepthRange(1.0, 1.0); #endif // FIXME: use quad stamp Tess_Begin(Tess_StageIteratorGeneric, NULL, tr.sunShader, NULL, tess.skipTangentSpaces, qfalse, -1, tess.fogNum); VectorCopy(origin, temp); VectorSubtract(temp, vec1, temp); VectorSubtract(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 0; tess.texCoords[tess.numVertexes][1] = 0; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; VectorCopy(origin, temp); VectorAdd(temp, vec1, temp); VectorSubtract(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 0; tess.texCoords[tess.numVertexes][1] = 1; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; VectorCopy(origin, temp); VectorAdd(temp, vec1, temp); VectorAdd(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 1; tess.texCoords[tess.numVertexes][1] = 1; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; VectorCopy(origin, temp); VectorSubtract(temp, vec1, temp); VectorAdd(temp, vec2, temp); VectorCopy(temp, tess.xyz[tess.numVertexes]); tess.xyz[tess.numVertexes][3] = 1; tess.texCoords[tess.numVertexes][0] = 1; tess.texCoords[tess.numVertexes][1] = 0; tess.texCoords[tess.numVertexes][2] = 0; tess.texCoords[tess.numVertexes][3] = 1; tess.colors[tess.numVertexes][0] = 1; tess.colors[tess.numVertexes][1] = 1; tess.colors[tess.numVertexes][2] = 1; tess.numVertexes++; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 1; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 3; Tess_End(); // back to normal depth range #if defined(USE_D3D10) //TODO #else glDepthRange(0.0, 1.0); GL_PopMatrix(); #endif }