// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); // 清除畫面 glClearColor(0.0f, 0.0f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // 畫出茶壼 RenderModelOpenGL(false, NULL); // 設定轉換矩陣 Matrix4x4 view_matrix = g_Control.GetViewMatrix();; Matrix4x4 world_view_matrix = view_matrix; glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); sModelMaterial_OpenGL material; material.Submit(NULL); // 設定頂點資料格式 glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_V), &g_Quad_v[0].m_Position); // 畫出鏡子, 同時把鏡子部分的stencil buffer設為1. { glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glColor4f(0.0f, 0.0f, 0.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } // 把鏡子部分的zbuffer清為1.0 { glStencilFunc(GL_EQUAL, 1, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // 把z值的輸出范圍設定為1~1, 也就是z永遠輸出1. glDepthRange(1.0f, 1.0f); glDepthFunc(GL_ALWAYS); // 只更新zbuffer,不需要更新顏色. glColorMask(false, false, false, false); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 恢復更新顏色的功能 glColorMask(true, true, true, true); glDepthFunc(GL_LESS); // 把z值的范圍還原為0~1 glDepthRange(0.0f, 1.0f); } // 畫出鏡子里的茶壼 { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); RenderModelOpenGL(true, &vPlane); glDisable(GL_STENCIL_TEST); } // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); { // 使用g_framebuffer framebuffer object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_framebuffer); glViewport(0, 0, 512, 512); // 清除畫面 glClearColor(0.0f, 0.0f, 0.9f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // RenderModelOpenGL(true, &vPlane); } { // 使用主framebuffer object, 也就是視窗. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); int w, h; GutGetWindowSize(w, h); glViewport(0, 0, w, h); // 清除畫面 glClearColor(0.0f, 0.0f, 0.6f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); RenderModelOpenGL(false, NULL); // 設定轉換矩陣 Matrix4x4 world_view_matrix = g_Control.GetViewMatrix(); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); sModelMaterial_OpenGL material; material.m_Textures[0] = g_texture; material.Submit(NULL); // 設定頂點資料格式 glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0_ARB); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // 計算貼圖座標矩陣 Matrix4x4 uv_offset_matrix; uv_offset_matrix.Scale_Replace(0.5f, 0.5f, 1.0f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.0f, 1.0f); Matrix4x4 texture_matrix = g_mirror_view_matrix * g_projection_matrix * uv_offset_matrix; glMatrixMode(GL_TEXTURE); glLoadMatrixf( (float *) &texture_matrix ); // vertex position & texcoord使用同樣的資料 glVertexPointer(3, GL_FLOAT, sizeof(Vertex_V), &g_Quad[0].m_Position); glTexCoordPointer(3, GL_FLOAT, sizeof(Vertex_V), &g_Quad[0].m_Position); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glLoadIdentity(); } // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
void RenderFrameDX10(void) { Vector4 vColorDarkBlue(0.0f, 0.0f, 0.5f, 1.0f); Vector4 vColorBlue(0.0f, 0.0f, 0.8f, 1.0f); Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); D3D10_VIEWPORT mainVP, VP; // `取得呼叫GutCreateGraphicsDeviceDX10時所產生的D3D10物件` ID3D10RenderTargetView *pRenderTargetView = GutGetDX10RenderTargetView(); ID3D10DepthStencilView *pDepthStencilView = GutGetDX10DepthStencilView(); // front/back buffer IDXGISwapChain *pSwapChain = GutGetDX10SwapChain(); // `在動態貼圖中畫出鏡射的茶壼` { UINT nViewports = 1; g_pDevice->RSGetViewports(&nViewports, &mainVP); // new rendertarget viewport size VP.TopLeftX = VP.TopLeftY = 0; VP.Width = VP.Height = 512; VP.MinDepth = 0.0f; VP.MaxDepth = 1.0f; ID3D10ShaderResourceView *null_views[4] = {NULL, NULL, NULL, NULL}; g_pDevice->PSSetShaderResources(0, 4, null_views); // `使用代表動態貼圖的`RenderTarget g_pDevice->OMSetRenderTargets(1, &g_pRGBAView, g_pDepthStencilView); // g_pDevice->RSSetViewports(1, &VP); // `清除顏色` g_pDevice->ClearRenderTargetView(g_pRGBAView, (float *)&vColorDarkBlue); // `清除`Depth/Stencil buffer g_pDevice->ClearDepthStencilView(g_pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); // `畫鏡射的茶壼` RenderModelDX10(true, &vPlane); } // `在主Framebuffer中畫出正常的茶壼` { // `使用主`framebuffer g_pDevice->OMSetRenderTargets(1, &pRenderTargetView, pDepthStencilView); // g_pDevice->RSSetViewports(1, &mainVP); // `清除顏色` g_pDevice->ClearRenderTargetView(pRenderTargetView, (float *)&vColorBlue); // `清除`Depth/Stencil buffer g_pDevice->ClearDepthStencilView(pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); // `畫茶壼` RenderModelDX10(false, &vPlane); } // `在主framebuffer中畫出鏡面` { UINT stride = sizeof(Vertex_VT); UINT offset = 0; // `設定`vertex shader g_pDevice->VSSetShader(g_pVertexShader); // `設定`pixel shader g_pDevice->PSSetShader(g_pPixelShader); // `設定`Shader Constants g_pDevice->VSSetConstantBuffers(0, 1, &g_pVSConstBuffer); // `設定vertex資料格式` g_pDevice->IASetInputLayout(g_pVertexLayout); // `設定三角形頂點索引值資料排列是triangle strip` g_pDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // Vertex Buffer g_pDevice->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); // `計算`texture matrix Matrix4x4 uv_offset_matrix; uv_offset_matrix.Scale_Replace(0.5f, -0.5f, 1.0f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.0f, 1.0f); Matrix4x4 texture_matrix = g_mirror_view_matrix * g_proj_matrix * uv_offset_matrix; Vertex_VT *pVertices = NULL; g_pVertexBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, (void **) &pVertices); for ( int i=0; i<4; i++ ) { Vector4 vPosition = g_Quad[i].m_Position; Vector4 vTexcoord = vPosition * texture_matrix; vTexcoord /= vTexcoord.GetW(); pVertices[i].m_Position = vPosition; pVertices[i].m_Texcoord = vTexcoord; } g_pVertexBuffer->Unmap(); // `計算矩陣` Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 wvp_matrix = view_matrix * g_proj_matrix; // `更新shader參數` Matrix4x4 *pConstData; g_pVSConstBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, (void **) &pConstData ); *pConstData = wvp_matrix; g_pVSConstBuffer->Unmap(); // `套用第1張貼圖` g_pDevice->PSSetShaderResources(0, 1, &g_pTextureView); g_pDevice->PSSetSamplers(0, 1, &g_pSamplerState); // `畫出格子` g_pDevice->Draw(4, 0); } // `等待硬體掃結束, 然後才更新畫面.` pSwapChain->Present(1, 0); }
// 使用Direct3D9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); device->BeginScene(); // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0); // 畫出茶壼 RenderModelDX9(false, NULL); // 畫出鏡面, 同時把stencil值設為1. { device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILREF, 1); Matrix4x4 identity_matrix = Matrix4x4::IdentityMatrix(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &identity_matrix); sModelMaterial_DX9 material; material.m_Material.Diffuse.r = material.m_Material.Diffuse.g = material.m_Material.Diffuse.b = material.m_Material.Diffuse.a = 0.0f; material.Submit(); // 畫出鏡面 device->SetFVF(D3DFVF_XYZ); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad_v, sizeof(Vertex_V)); } // 把鏡面范圍的ZBuffer清為1.0 { // 設定stencil test條件, 只更新鏡面范圍的像素. device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); // 關閉z test device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); // 關閉RGBA的輸出 // 經由修改viewport Z范圍的方法, 把3D物件的Z值輸出固定為1. int w, h; GutGetWindowSize(w, h); D3DVIEWPORT9 viewport; viewport.X = viewport.Y = 0; viewport.Width = w; viewport.Height = h; viewport.MinZ = 1.0f; viewport.MaxZ = 1.0f; device->SetViewport(&viewport); // 畫出鏡面 device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad_v, sizeof(Vertex_V)); // 把Z值范圍還原成0-1 viewport.MinZ = 0.0f; viewport.MaxZ = 1.0f; device->SetViewport(&viewport); // 還原zbuffer test的測試條件 device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); // 重新打開RGBA的輸出 device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA); } // 在鏡面范圍里畫出鏡射的茶壼 { RenderModelDX9(true, &vPlane); device->SetRenderState(D3DRS_STENCILENABLE, FALSE); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
void RenderFrameDX10(void) { Vector4 vColorDarkBlue(0.0f, 0.0f, 0.5f, 1.0f); Vector4 vColorBlue(0.0f, 0.0f, 0.8f, 1.0f); Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); D3D10_VIEWPORT mainVP, VP; // 取得呼叫GutCreateGraphicsDeviceDX10時所產生的D3D10物件 ID3D10RenderTargetView *pRenderTargetView = GutGetDX10RenderTargetView(); //frame buffer ID3D10DepthStencilView *pDepthStencilView = GutGetDX10DepthStencilView(); //depth/stencil buffer IDXGISwapChain *pSwapChain = GutGetDX10SwapChain(); // front/back buffer // 在動態貼圖中畫出鏡射的茶壼 { UINT nViewports = 1; g_pDevice->RSGetViewports(&nViewports, &mainVP); // new rendertarget viewport size VP.TopLeftX = VP.TopLeftY = 0; VP.Width = VP.Height = 512; VP.MinDepth = 0.0f; VP.MaxDepth = 1.0f; ID3D10ShaderResourceView *null_views[4] = {NULL, NULL, NULL, NULL}; g_pDevice->PSSetShaderResources(0, 4, null_views); // 使用代表動態貼圖的RenderTarget g_pDevice->OMSetRenderTargets(1, &g_pRGBAView, g_pDepthStencilView); // g_pDevice->RSSetViewports(1, &VP); // 清除顏色 g_pDevice->ClearRenderTargetView(g_pRGBAView, (float *)&vColorDarkBlue); // 清除Depth/Stencil buffer g_pDevice->ClearDepthStencilView(g_pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); // 畫鏡射的茶壼 RenderModelDX10(true, &vPlane); } // 在主Framebuffer中畫出正常的茶壼 { // 使用主framebuffer g_pDevice->OMSetRenderTargets(1, &pRenderTargetView, pDepthStencilView); // g_pDevice->RSSetViewports(1, &mainVP); // 清除顏色 g_pDevice->ClearRenderTargetView(pRenderTargetView, (float *)&vColorBlue); // 清除Depth/Stencil buffer g_pDevice->ClearDepthStencilView(pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0); // 畫茶壼 RenderModelDX10(false, &vPlane); } // 在主framebuffer中畫出鏡面 { UINT stride = sizeof(Vertex_V); UINT offset = 0; // 設定vertex shader g_pDevice->VSSetShader(g_pVertexShader); // 設定pixel shader g_pDevice->PSSetShader(g_pPixelShader); // 設定Shader Constants g_pDevice->VSSetConstantBuffers(0, 1, &g_pVSConstBuffer); // 設定vertex資料格式 g_pDevice->IASetInputLayout(g_pVertexLayout); // 設定三角形頂點索引值資料排列是triangle strip g_pDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // Vertex Buffer g_pDevice->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); // 計算texture matrix Matrix4x4 uv_offset_matrix; uv_offset_matrix.Scale_Replace(0.5f, -0.5f, 1.0f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.0f, 1.0f); Matrix4x4 texture_matrix = g_mirror_view_matrix * g_proj_matrix * uv_offset_matrix; // 計算矩陣 Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 wvp_matrix = view_matrix * g_proj_matrix; // 更新shader參數 Matrix4x4 *pConstData; g_pVSConstBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, (void **) &pConstData ); pConstData[0] = wvp_matrix; pConstData[1] = texture_matrix; g_pVSConstBuffer->Unmap(); // 套用第1張貼圖 g_pDevice->PSSetShaderResources(0, 1, &g_pTextureView); // 畫出鏡面 g_pDevice->Draw(4, 0); } // 等待硬體掃結束, 然後才更新畫面 pSwapChain->Present(1, 0); }
// 使用DirectX 9來繪圖 void RenderFrameDX9(void) { LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z); // 開始下繪圖指令 device->BeginScene(); { LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup; device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release(); device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release(); LPDIRECT3DSURFACE9 pSurface; g_pTexture->GetSurfaceLevel(0, &pSurface); device->SetRenderTarget(0, pSurface); device->SetDepthStencilSurface(g_pDepthStencil); device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 200, 255), 1.0f, 0); RenderModelDX9(true, &vPlane); pSurface->Release(); device->SetRenderTarget(0, pFrameBufferBackup); device->SetDepthStencilSurface(pDepthBufferBackup); } // 把上一個步驟的結果當成貼圖來使用 { // 消除畫面 device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0); RenderModelDX9(false, NULL); Matrix4x4 identMat; identMat.Identity(); device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &identMat); sModelMaterial_DX9 material; material.m_pTextures[0] = g_pTexture; material.Submit(); device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); Matrix4x4 uv_offset_matrix; uv_offset_matrix.Scale_Replace(0.5f, -0.5f, 1.0f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 inv_view_matrix = g_Control.GetViewMatrix(); inv_view_matrix.FastInvert(); Matrix4x4 texture_matrix = inv_view_matrix * g_mirror_view_matrix * g_projection_matrix * uv_offset_matrix; device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix); device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); // D3DTTFF_PROJECTED告知direct3d裝置texcoord需要除以w device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED); float v[12]; for ( int i=0; i<4; i++ ) { g_Quad[i].m_Position.StoreXYZ(&v[i*3]); } // 畫出矩形 device->SetFVF(D3DFVF_XYZ); //device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_V)); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, 12); } // 宣告所有的繪圖指令都下完了 device->EndScene(); // 把背景backbuffer的畫面呈現出來 device->Present( NULL, NULL, NULL, NULL ); }
IFXRESULT CIFXDeviceTexUnitOGL::SetHWTexCoordGen(IFXenum eGenMode) { IFXRESULT rc = IFX_OK; m_eTexCoordGen = eGenMode; m_pDevice->SetActiveTexUnit(m_uTexUnitNum); m_mTexGenMatrix.Reset(); IFXASSERTBOX(m_pOGL->m_bValidOpenGL, "(Error): Making OpenGL call on Invalid context!"); switch(eGenMode) { case IFX_NONE: m_pOGL->glDisable(GL_TEXTURE_GEN_S); m_pOGL->glDisable(GL_TEXTURE_GEN_T); m_pOGL->glDisable(GL_TEXTURE_GEN_R); break; case IFX_TEXGEN_REFLECTION_SPHERE: m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); break; case IFX_TEXGEN_VIEWPOSITION: { // Texgen matrix is the local->canera matrix. IFXMatrix4x4 mView = m_pDevice->GetViewMatrix(); m_mTexGenMatrix.Multiply3x4(mView, m_pDevice->GetWorldMatrix()); m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); IFXVector4 vPlane(1,0,0,0); m_pOGL->glTexGenfv(GL_S, GL_OBJECT_PLANE, vPlane.Raw()); vPlane.Set(0,1,0,0); m_pOGL->glTexGenfv(GL_T, GL_OBJECT_PLANE, vPlane.Raw()); vPlane.Set(0,0,1,0); m_pOGL->glTexGenfv(GL_R, GL_OBJECT_PLANE, vPlane.Raw()); } break; case IFX_TEXGEN_VIEWNORMAL: if(m_pOGL->CubeTextureSupport()) { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); } break; case IFX_TEXGEN_VIEWREFLECTION: if(m_pOGL->CubeTextureSupport()) { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); } break; case IFX_TEXGEN_WORLDPOSITION: { // Texgen matrix is the local->world matrix. m_mTexGenMatrix = m_pDevice->GetWorldMatrix(); m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); IFXVector4 vPlane(1,0,0,0); m_pOGL->glTexGenfv(GL_S, GL_OBJECT_PLANE, vPlane.Raw()); vPlane.Set(0,1,0,0); m_pOGL->glTexGenfv(GL_T, GL_OBJECT_PLANE, vPlane.Raw()); vPlane.Set(0,0,1,0); m_pOGL->glTexGenfv(GL_R, GL_OBJECT_PLANE, vPlane.Raw()); } break; case IFX_TEXGEN_WORLDNORMAL: { // TexGenMatrix is inverse transpose of the camera->world matrix // The device View matrix is the Inverse of camera->world matrix m_mTexGenMatrix = m_pDevice->GetViewMatrix(); // Don't want to translate direction vectors m_mTexGenMatrix[12] = 0; m_mTexGenMatrix[13] = 0; m_mTexGenMatrix[14] = 0; // Now for the transpose part of inverse transpose. m_mTexGenMatrix.Transpose(); if(m_pOGL->CubeTextureSupport()) { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); } } break; case IFX_TEXGEN_WORLDREFLECTION: { // TexGenMatrix is inverse transpose of the camera->world matrix // The device View matrix is the Inverse of camera->world matrix m_mTexGenMatrix = m_pDevice->GetViewMatrix(); // Don't want to translate direction vectors m_mTexGenMatrix[12] = 0; m_mTexGenMatrix[13] = 0; m_mTexGenMatrix[14] = 0; // Now for the transpose part of inverse transpose. m_mTexGenMatrix.Transpose(); if(m_pOGL->CubeTextureSupport()) { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); } } break; case IFX_TEXGEN_LOCALPOSITION: { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); IFXVector4 vPlane(1,0,0,0); m_pOGL->glTexGenfv(GL_S, GL_OBJECT_PLANE, vPlane.Raw()); vPlane.Set(0,1,0,0); m_pOGL->glTexGenfv(GL_T, GL_OBJECT_PLANE, vPlane.Raw()); vPlane.Set(0,0,1,0); m_pOGL->glTexGenfv(GL_R, GL_OBJECT_PLANE, vPlane.Raw()); } break; case IFX_TEXGEN_LOCALNORMAL: { // The texgen matrix is the inverse transpose of the camera->local // matrix. This is the same as the transpose of the concatenated // world and view matrices sent to the device. IFXMatrix4x4 mView = m_pDevice->GetViewMatrix(); // Concatenate the world and view matrices. m_mTexGenMatrix.Multiply3x4(mView, m_pDevice->GetWorldMatrix()); // Don't want to translate direction vectors. m_mTexGenMatrix[12] = 0; m_mTexGenMatrix[13] = 0; m_mTexGenMatrix[14] = 0; // Finally, take the transpose. m_mTexGenMatrix.Transpose(); if(m_pOGL->CubeTextureSupport()) { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB); } } break; case IFX_TEXGEN_LOCALREFLECTION: { // The texgen matrix is the inverse transpose of the camera->local // matrix. This is the same as the transpose of the concatenated // world and view matrices sent to the device. IFXMatrix4x4 mView = m_pDevice->GetViewMatrix(); // Concatenate the world and view matrices. m_mTexGenMatrix.Multiply3x4(mView, m_pDevice->GetWorldMatrix()); // Don't want to translate direction vectors. m_mTexGenMatrix[12] = 0; m_mTexGenMatrix[13] = 0; m_mTexGenMatrix[14] = 0; // Finally, take the transpose. m_mTexGenMatrix.Transpose(); if(m_pOGL->CubeTextureSupport()) { m_pOGL->glEnable(GL_TEXTURE_GEN_S); m_pOGL->glEnable(GL_TEXTURE_GEN_T); m_pOGL->glEnable(GL_TEXTURE_GEN_R); m_pOGL->glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); m_pOGL->glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); m_pOGL->glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); } } break; } IFXRUN(rc, SetHWTextureTransform(m_mTexMatrix)); return rc; }