/* ===================== R_ObliqueProjection - adjust near plane of previously set projection matrix to perform an oblique projection ===================== */ static void R_ObliqueProjection(viewDef_t *parms) { float mvt[16]; //model view transpose idPlane pB = parms->clipPlanes[0]; idPlane cp; R_MatrixTranspose(parms->worldSpace.modelViewMatrix, mvt); R_GlobalPlaneToLocal(mvt, pB, cp); //transform plane (which is set to the surface we're mirroring about's plane) to camera space //oblique projection adjustment code idVec4 clipPlane(cp[0], cp[1], cp[2], cp[3]); idVec4 q; q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + parms->projectionMatrix[8]) / parms->projectionMatrix[0]; q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + parms->projectionMatrix[9]) / parms->projectionMatrix[5]; q[2] = -1.0f; q[3] = (1.0f + parms->projectionMatrix[10]) / parms->projectionMatrix[14]; // scaled plane vector float d = 2.0f / (clipPlane * q); // Replace the third row of the projection matrix parms->projectionMatrix[2] = clipPlane[0] * d; parms->projectionMatrix[6] = clipPlane[1] * d; parms->projectionMatrix[10] = clipPlane[2] * d + 1.0f; parms->projectionMatrix[14] = clipPlane[3] * d; }
void WaterReflectionRenderPass::Draw(RenderSystem * renderSystem, uint32 clearBuffers) { Camera *mainCamera = renderSystem->GetMainCamera(); Camera *drawCamera = renderSystem->GetDrawCamera(); if (!passDrawCamera) { passMainCamera = new Camera(); passDrawCamera = new Camera(); } passMainCamera->CopyMathOnly(*mainCamera); UpdateCamera(passMainCamera); Vector4 clipPlane(0,0,1, -(waterLevel-0.1f)); Camera* currMainCamera = passMainCamera; Camera* currDrawCamera; if (drawCamera==mainCamera) { currDrawCamera = currMainCamera; } else { passDrawCamera->CopyMathOnly(*drawCamera); UpdateCamera(passDrawCamera); currDrawCamera = passDrawCamera; currMainCamera->PrepareDynamicParameters(&clipPlane); } currDrawCamera->SetupDynamicParameters(&clipPlane); //add clipping plane visibilityArray.Clear(); renderSystem->GetRenderHierarchy()->Clip(currMainCamera, &visibilityArray, RenderObject::CLIPPING_VISIBILITY_CRITERIA | RenderObject::VISIBLE_REFLECTION); renderPassBatchArray->Clear(); renderPassBatchArray->PrepareVisibilityArray(&visibilityArray, currMainCamera); ClearBuffers(clearBuffers); DrawLayers(currMainCamera); }
void drawModel(const Model& mdl) { // setup world-view matrix auto modelView = (viewMatrix * mdl.transform.GetMatrix()).ToMatrix4(); glLoadMatrix_T(modelView.Ptr()); #ifdef TEST_MESH_CLIPPING Gm::Plane clipPlane( Gs::Vector3(1, 0, 0).Normalized(), -0.3f ); clipPlane = Gm::TransformPlane(modelView.Inverse(), clipPlane); Gm::TriangleMesh front, back; Gm::MeshModifier::ClipMesh(mdl.mesh, clipPlane, front, back); drawMesh(front, wireframeMode); #ifdef TEST_SHOW_SPLIT auto trans2 = mdl.transform; trans2.MoveGlobal({ -0.1f, 0, 0 }); modelView = (viewMatrix * trans2.GetMatrix()).ToMatrix4(); glLoadMatrix_T(modelView.Ptr()); #endif drawMesh(back, wireframeMode); #else // draw model drawMesh(mdl.mesh, wireframeMode); #endif #ifdef TEST_SHOW_EDGES // draw edges drawMeshEdges(mdl.mesh); #endif }
// renderStageWater - Render distant water without blend, for exceptional cases void DistantLand::renderStageWater() { DECLARE_MWBRIDGE IDirect3DStateBlock9 *stateSaved; UINT passes; if(isRenderCached) return; if(mwBridge->CellHasWater()) { // Save state block manually since we can change FVF/decl device->CreateStateBlock(D3DSBT_ALL, &stateSaved); effect->Begin(&passes, D3DXFX_DONOTSAVESTATE); // Draw water plane bool u = mwBridge->IsUnderwater(eyePos.z); bool i = !mwBridge->IsExterior(); if(u || i) { // Set up clip plane at fog end for certain environments to save fillrate float clipAt = Configuration.DL.InteriorFogEnd * 8192.0; D3DXPLANE clipPlane(0, 0, -clipAt, mwProj._33 * clipAt + mwProj._43); device->SetClipPlane(0, clipPlane); device->SetRenderState(D3DRS_CLIPPLANEENABLE, 1); } // Switch to appropriate shader and render effect->BeginPass(u ? PASS_RENDERUNDERWATER : PASS_RENDERWATER); renderWaterPlane(); effect->EndPass(); effect->End(); stateSaved->Apply(); stateSaved->Release(); } }
void GLCamera::Apply(int pickx, int picky, int pickw, int pickh) { glViewport(vpX, vpY, vpW, vpH); if(vpW == 0 || vpH == 0) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); return; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(fieldOfView, vpW/vpH, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GLMatrix mx = fCamBase*fCamTrans; GLVector3 pos = mx.GetTranslation(); GLVector3 fwd = mx.GetBaseVec(1); GLVector3 center = pos-fwd; GLVector3 up = fCamBase.GetBaseVec(3); gluLookAt(pos[0], pos[1], pos[2], center[0], center[1], center[2], up[0], up[1], up[2]); UpdateCache(); GLPlane clipPlane(EyeDirection(), EyePoint()); for (int i = 0; i < 8; i++) { double sx = (i&1) ? -1 : 1; double sy = (i&2) ? -1 : 1; double sz = (i&4) ? -1 : 1; double cdist = clipPlane.DistanceTo(GLVertex3(sceneSize*sx, sceneSize*sy, sceneSize*sz)); if (i == 0) farClip = nearClip = cdist; if (cdist < nearClip) nearClip = cdist; if (cdist > farClip) farClip = cdist; } nearClip *= 0.49; farClip *= 2.01; if (farClip < 2.0) farClip = 2.0; if (nearClip < farClip/1000.0) nearClip = farClip/1000.0; glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (pickw > 0 && pickh > 0) { int vport[4] = { vpX, vpY, vpW, vpH }; gluPickMatrix(pickx, vpH-picky, pickw, pickh, vport); gluPerspective(fieldOfView, vpW/vpH, nearClip, farClip); } else gluPerspective(fieldOfView, vpW/vpH, nearClip, farClip); glMatrixMode(GL_MODELVIEW); UpdateCache(); }
//------------------------------------------------------------------------------- // @ Game::Game() //------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------- Game::Game() : IvGame(), mPosition( 0.0f, -0.5f, 0.0f ), mPlaneBuffer(0) { IvPlane clipPlane( 0.0f, -1.0f, 0.0f, 1.0f ); mClipper.SetPlane( clipPlane ); } // End of Game::Game()