bool InitResourceOpenGL(void) { // 計算出一個可以轉換到鏡頭座標系的矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 設定投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, 1.0f, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); // 載入貼圖 TGAImg tga_loader; if( IMG_OK!=tga_loader.Load("../../textures/lena_rgba.tga") ) return false; // 產生一個貼圖物件 glGenTextures( 1, &g_TextureID ); // 使用g_TextureID貼圖物件 glBindTexture( GL_TEXTURE_2D, g_TextureID ); // RGBA模式 glTexImage2D( GL_TEXTURE_2D, 0, 3, tga_loader.GetWidth(), tga_loader.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tga_loader.GetImg() ); // `設定顯示貼圖被縮小時使用線性內插` glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR ); // `設定顯示貼圖被放大時使用線性外插` glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // 使用2D貼圖功能 glEnable(GL_TEXTURE_2D); return true; }
bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFOV, 1.0f, 0.1f, 100.0f); InitStateDX9(); CGutModel::SetTexturePath("../../textures/"); g_Model_DX9.ConvertToDX9Model(&g_Model); g_SpotLightModel_DX9.ConvertToDX9Model(&g_SpotLightModel); g_material_stencilpass.m_bCullFace = false; g_material_spotlightpass.m_bBlend = true; g_material_spotlightpass.m_SrcBlend = D3DBLEND_ONE; g_material_spotlightpass.m_DestBlend = D3DBLEND_ONE; g_material_spotlightpass.m_Material.Diffuse.r = g_material_spotlightpass.m_Material.Diffuse.g = g_material_spotlightpass.m_Material.Diffuse.b = g_material_spotlightpass.m_Material.Diffuse.a = 0.3f; return true; }
bool InitResourceOpenGL(void) { // 鏡頭座標系轉換矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 設定投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, 1.0f, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); // 載入貼圖 const char *texture_array[] = { "../../textures/uffizi_right.tga", "../../textures/uffizi_left.tga", "../../textures/uffizi_top.tga", "../../textures/uffizi_bottom.tga", "../../textures/uffizi_back.tga", // `右手座標系上 Z+ 為鏡頭後方.` "../../textures/uffizi_front.tga" // `右手座標系上 Z- 為鏡頭前方.` }; g_TextureID = GutLoadCubemapTexture_OpenGL(texture_array); // 使用CUBEMAP貼圖功能 glEnable(GL_TEXTURE_CUBE_MAP); // 套用CUBEMAP貼圖 glBindTexture( GL_TEXTURE_CUBE_MAP, g_TextureID ); g_Model_OpenGL.ConvertToOpenGLModel(&g_Model); return true; }
void ResizeWindowOpenGL(int width, int height) { glViewport(0, 0, width, height); // 投影矩陣 float aspect = (float) height / (float) width; Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(60.0f, aspect, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); }
bool InitResourceOpenGL(void) { if ( glGenFramebuffersEXT==NULL ) { printf("Could not create frame buffer object\n"); return false; } // 投影矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFOV, 1.0f, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); // 開啟一個framebuffer object glGenFramebuffersEXT(1, &g_framebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_framebuffer); // 配罝一塊貼圖空間給framebuffer object繪圖使用 { glGenTextures(1, &g_texture); glBindTexture(GL_TEXTURE_2D, g_texture); // 設定filter glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 宣告貼圖大小及格式 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // framebuffer的RGBA繪圖 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_texture, 0); } // 配置zbuffer給framebuffer object使用 { glGenRenderbuffersEXT(1, &g_depthbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, g_depthbuffer); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 512, 512); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_depthbuffer); } // 檢查framebuffer object有沒有配置成功 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if ( status!=GL_FRAMEBUFFER_COMPLETE_EXT ) { return false; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); return true; }
bool InitResourceOpenGL(void) { // 計算出一個可以轉換到鏡頭座標系的矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 設定投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, 1.0f, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); return true; }
// callback function. 視窗大小改變時會被呼叫, 并傳入新的視窗大小. void ResizeWindowOpenGL(int width, int height) { // 使用新的視窗大小做為新的繪圖解析度 glViewport(0, 0, width, height); // 投影矩陣, 重設水平跟垂直方向的視角. float aspect = (float) height / (float) width; Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, aspect, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); }
bool InitResourceOpenGL(void) { // 投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(90.0f, 1.0f, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); glMatrixMode(GL_MODELVIEW); glEnable(GL_CULL_FACE); return true; }
bool InitResourceOpenGL(void) { // 計算出一個可以轉換到鏡頭座標系的矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(60.0f, 1.0f, 1.0f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); //glShadeModel(GL_FLAT); // 關閉內插 //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // 使用晝邊線模式 glEnable(GL_CULL_FACE); // 忽略背對鏡頭的面 return true; }
bool InitResourceOpenGL(void) { // 計算出一個可以轉換到鏡頭座標系的矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 設定投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, 1.0f, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); g_TextureID = GutLoadTexture_OpenGL("../../textures/lena.dds"); // 設定顯示貼圖時使用線性內插 glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR ); // 設定顯示貼圖時使用線性外插 glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // 使用2D貼圖功能 glEnable(GL_TEXTURE_2D); return true; }
bool InitResourceOpenGL(void) { // 計算出一個可以轉換到鏡頭座標系的矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 設定投影矩陣 Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, 1.0f, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); // 載入貼圖 TGAImg tga_loader; if( IMG_OK!=tga_loader.Load("../../textures/checkerboard.tga") ) return false; // 產生一個貼圖物件 glGenTextures( 1, &g_TextureID ); // 使用g_TextureID貼圖物件 glBindTexture( GL_TEXTURE_2D, g_TextureID ); // RGBA模式 GLuint format = GL_RGBA; switch(tga_loader.GetBPP()) { case 8: format = GL_LUMINANCE; break; case 24: format = GL_RGB; break; case 32: format = GL_RGBA; break; } glTexImage2D( GL_TEXTURE_2D, 0, 3, tga_loader.GetWidth(), tga_loader.GetHeight(), 0, format, GL_UNSIGNED_BYTE, tga_loader.GetImg() ); // 設定顯示貼圖時使用線性內插 glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR ); // 設定顯示貼圖時使用線性外插 glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // 使用2D貼圖功能 glEnable(GL_TEXTURE_2D); return true; }
bool InitResourceOpenGL(void) { // 計算出一個可以轉換到鏡頭座標系的矩陣 g_view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 投影矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(90.0f, 1.0f, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); g_models[0].ConvertToOpenGLModel(&g_sun_model); g_models[1].ConvertToOpenGLModel(&g_earth_model); return true; }
bool InitResourceOpenGL(void) { // 投影矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFOV, 1.0f, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glDisable(GL_CULL_FACE); CGutModel::SetTexturePath("../../textures/"); g_Model_OpenGL.ConvertToOpenGLModel(&g_Model); return true; }
bool InitResourceOpenGL(void) { // 投影矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(70.0f, 1.0f, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); for ( int i=0; i<3; i++ ) { g_Models_OpenGL[i].ConvertToOpenGLModel(&g_Models[i]); } return true; }
bool InitResourceOpenGL(void) { // 投影矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFovW, 1.0f, g_fNear, g_fFar); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); g_Model_OpenGL.ConvertToOpenGLModel(&g_Model); // 把正向跟反向的面都畫出來 glDisable(GL_CULL_FACE); // 啟動2D貼圖功能 glEnable(GL_TEXTURE_2D); // 啟動zbuffer隱藏面測試 glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); return true; }
static void RenderSolarSystemOpenGL(void) { Vector4 eye(0.0f, 0.0f, 15.0f); Vector4 lookat(0.0f, 0.0f, 0.0f); Vector4 up(0.0f, 1.0f, 0.0f); // `設定要用陣列的方式傳入頂點位置跟顏色` glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // `計算出一個可以轉換到鏡頭座標系的矩陣` Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_OpenGL(60.0f, 1.0f, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &projection_matrix); Matrix4x4 view_matrix = GutMatrixLookAtRH(eye, lookat, up); Matrix4x4 world_view_matrix; glMatrixMode(GL_MODELVIEW); glDisable(GL_TEXTURE_2D); // `太陽` world_view_matrix = g_sun_matrix * view_matrix; glLoadMatrixf( (float *) &world_view_matrix); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), g_pSunVertices); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), g_pSunVertices[0].m_RGBA); glDrawElements(GL_TRIANGLES, g_iNumSphereIndices, GL_UNSIGNED_SHORT, g_pSphereIndices); // `地球` world_view_matrix = g_earth_matrix * view_matrix; glLoadMatrixf( (float *) &world_view_matrix); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), g_pEarthVertices); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), g_pEarthVertices[0].m_RGBA); glDrawElements(GL_TRIANGLES, g_iNumSphereIndices, GL_UNSIGNED_SHORT, g_pSphereIndices); // `月球` world_view_matrix = g_moon_matrix * view_matrix; glLoadMatrixf( (float *) &world_view_matrix); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), g_pMoonVertices); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), g_pMoonVertices[0].m_RGBA); glDrawElements(GL_TRIANGLES, g_iNumSphereIndices, GL_UNSIGNED_SHORT, g_pSphereIndices); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 計算出一個可以轉換到鏡頭座標系的矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 計算出一個非平行投影的矩陣 Matrix4x4 perspective_matrix = GutMatrixPerspectiveRH_OpenGL(90.0f, 1.0f, 1.0f, 100.0f); // 把這兩個矩陣相乘 Matrix4x4 view_perspective_matrix = view_matrix * perspective_matrix; // 把空間中的座標點轉換到螢幕座標系上 Vector4 vertices[16]; for ( int i=0; i<16; i++ ) { vertices[i] = g_vertices[i] * view_perspective_matrix; vertices[i] /= vertices[i].GetW(); } // 畫出金字塔的8條邊線 glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(4, GL_FLOAT, sizeof(Vector4), vertices); glDrawArrays(GL_LINES, 0, 16); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 計算出一個可以轉換到鏡頭座標系的矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); // 設定鏡頭轉換矩陣 glMatrixMode(GL_MODELVIEW); glLoadMatrixf((float *) &view_matrix); // 計算出一個非平行投影的透視矩陣 Matrix4x4 perspective_matrix = GutMatrixPerspectiveRH_OpenGL(90.0f, 1.0f, 1.0f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf((float *) &perspective_matrix); // 畫出金字塔的8條邊線 glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(4, GL_FLOAT, sizeof(Vector4), g_vertices); glDrawArrays(GL_LINES, 0, 16); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { Matrix4x4 light_projection_matrix; Matrix4x4 light_view_matrix; Matrix4x4 light_world_view_matrix; Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); { // `使用` g_framebuffer framebuffer object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_framebuffer); glViewport(0, 0, 512, 512); // `清除畫面` glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // `光源位置` Vector4 vLightPos = g_Light.m_Position; Vector4 vLightUp(0.0f, 1.0f, 0.0f); Vector4 vLightLookat(0.0f, 0.0f, 0.0f); // `設定光源的轉換矩陣` light_projection_matrix = GutMatrixPerspectiveRH_OpenGL(60.0f, 1.0f, 0.1f, 100.0f); light_view_matrix = GutMatrixLookAtRH(vLightPos, vLightLookat, vLightUp); light_world_view_matrix = world_matrix * light_view_matrix; glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &light_projection_matrix ); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &light_world_view_matrix ); glDisable(GL_LIGHTING); // `畫出黑色的茶壼` sModelMaterial_OpenGL material; material.m_bCullFace = false; material.m_Diffuse.Set(0.0); material.Submit(NULL); g_Model_OpenGL.Render(0); } { // `使用主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); // `計算出一個可以轉換到鏡頭座標系的矩陣` Matrix4x4 view_matrix = g_Control.GetViewMatrix(); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &view_matrix); SetupLightingOpenGL(); Matrix4x4 world_view_matrix = world_matrix * view_matrix; glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); g_Model_OpenGL.Render(); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &view_matrix); glDisable(GL_LIGHTING); sModelMaterial_OpenGL material; material.m_Diffuse.Set(1.0f); material.m_Textures[0] = g_texture; material.Submit(NULL); Matrix4x4 uv_offset_matrix; uv_offset_matrix.Identity(); uv_offset_matrix.Scale(0.5f, 0.5f, 0.5f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 texture_matrix = light_view_matrix * light_projection_matrix * uv_offset_matrix; glMatrixMode(GL_TEXTURE); glLoadMatrixf( (float *)&texture_matrix); glDisable(GL_LIGHTING); // `設定頂點資料格式` glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); glClientActiveTexture(GL_TEXTURE0_ARB); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), &g_Quad[0].m_Position); // `直接把頂點資料拿來當貼圖座標使用` glTexCoordPointer(4, GL_FLOAT, sizeof(Vertex_VT), &g_Quad[0].m_Position); // `畫出看板` glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glPopClientAttrib(); glLoadIdentity(); } // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
bool InitResourceOpenGL(void) { if ( glGenFramebuffersEXT==NULL ) { printf("Could not create frame buffer object\n"); return false; } // 投影矩陣 g_projection_matrix = GutMatrixPerspectiveRH_OpenGL(g_fFOV, 1.0f, 0.1f, 100.0f); // 設定視角轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glDisable(GL_CULL_FACE); // 開啟一個framebuffer object glGenFramebuffersEXT(1, &g_framebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_framebuffer); // 配罝一塊貼圖空間給framebuffer object繪圖使用 { glGenTextures(1, &g_texture); glBindTexture(GL_TEXTURE_2D, g_texture); // 設定filter glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 宣告貼圖大小及格式 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, g_framebuffer_w, g_framebuffer_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // framebuffer的RGBA繪圖 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_texture, 0); } // 配置zbuffer給framebuffer object使用 { glGenRenderbuffersEXT(1, &g_depthbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, g_depthbuffer); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, g_framebuffer_w, g_framebuffer_h); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, g_depthbuffer); } // 檢查framebuffer object有沒有配置成功 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if ( status!=GL_FRAMEBUFFER_COMPLETE_EXT ) { return false; } for ( int i=0; i<2; i++ ) { // 再開啟一個framebuffer object glGenFramebuffersEXT(1, &g_blurframebuffer[i]); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_blurframebuffer[i]); // 配罝一塊貼圖空間給framebuffer object繪圖使用 { glGenTextures(1, &g_blurtexture[i]); glBindTexture(GL_TEXTURE_2D, g_blurtexture[i]); // 設定filter glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // 宣告貼圖大小及格式 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, g_framebuffer_w, g_framebuffer_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // framebuffer的RGBA繪圖 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_blurtexture[i], 0); } // 檢查framebuffer object有沒有配置成功 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if ( status!=GL_FRAMEBUFFER_COMPLETE_EXT ) { return false; } } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CGutModel::SetTexturePath("../../textures/"); g_Model_OpenGL.ConvertToOpenGLModel(&g_Model); g_Terrain_OpenGL.ConvertToOpenGLModel(&g_Terrain); for ( int i=0; i<4; i++ ) { g_Quad[i].m_Texcoord[1] = 1.0f - g_Quad[i].m_Texcoord[1]; } return true; }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { Matrix4x4 light_projection_matrix; Matrix4x4 light_view_matrix; Matrix4x4 light_world_view_matrix; Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); GLuint blurred_texture = 0; { // 使用g_framebuffer framebuffer object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_framebuffer); glViewport(0, 0, g_framebuffer_w, g_framebuffer_h); // 清除畫面 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 設定光源位置 Vector4 vLightPos = g_Light.m_Position; Vector4 vLightUp(0.0f, 1.0f, 0.0f); Vector4 vLightLookat(0.0f, 0.0f, 0.0f); light_projection_matrix = GutMatrixPerspectiveRH_OpenGL(60.0f, 1.0f, 0.1f, 100.0f); light_view_matrix = GutMatrixLookAtRH(vLightPos, vLightLookat, vLightUp); light_world_view_matrix = world_matrix * light_view_matrix; // 把鏡頭放到光源位置來畫陰影 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &light_projection_matrix ); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &light_world_view_matrix ); SetupLightingOpenGL(); // 套用預設材質, 把貼圖全部關閉 sModelMaterial_OpenGL material; material.m_Ambient = Vector4::GetZero(); material.m_Emissive = Vector4::GetZero(); material.m_Diffuse = Vector4::GetZero(); material.m_Specular = Vector4::GetZero(); material.m_bCullFace = false; material.Submit(NULL); // 畫出模型 g_Model_OpenGL.Render(0); } // 把影子柔化 { blurred_texture = BlurTexture(g_texture); } { // 使用主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); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &view_matrix); // 設定光源 SetupLightingOpenGL(); // 設定轉換矩陣 Matrix4x4 world_view_matrix = world_matrix * view_matrix; glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_projection_matrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); // 畫出茶壼 g_Model_OpenGL.Render(); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &view_matrix); sModelMaterial_OpenGL material; material.m_Textures[0] = blurred_texture; material.Submit(NULL); // 計算貼圖矩陣 Matrix4x4 uv_offset_matrix; uv_offset_matrix.Identity(); uv_offset_matrix.Scale(0.5f, 0.5f, 0.5f); uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f); Matrix4x4 texture_matrix = light_view_matrix * light_projection_matrix * uv_offset_matrix; glMatrixMode(GL_TEXTURE); glLoadMatrixf( (float *)&texture_matrix); // 開啟自動產生貼圖座標功能 // S/T/R分別代表貼圖座標的X/Y/Z軸 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); // 以光線的反射向量來做為貼圖座標 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); Matrix4x4 identMatrix = Matrix4x4::IdentityMatrix(); glTexGenfv(GL_S, GL_OBJECT_PLANE, &identMatrix[0][0]); glTexGenfv(GL_T, GL_OBJECT_PLANE, &identMatrix[1][0]); glTexGenfv(GL_R, GL_OBJECT_PLANE, &identMatrix[2][0]); // 畫出地表 g_Terrain_OpenGL.Render(0); glLoadIdentity(); } // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }