// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 設定好GPU要去哪讀取頂點資料 glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(4, GL_FLOAT, sizeof(Vector4), g_vertices); // 設定要變更GL_MODELVIEW矩陣 glMatrixMode(GL_MODELVIEW); // `旋轉角度` static float angle = 0.0f; angle += 0.01f; // `設定旋轉矩陣` Matrix4x4 world_view_matrix = g_view_matrix; world_view_matrix.RotateZ(angle); glLoadMatrixf( (float *) &world_view_matrix); // `畫出金字塔的8條邊線` glDrawElements( GL_LINES, // `指定所要畫的基本圖形種類` 16, // `有幾個索引值` GL_UNSIGNED_SHORT, // `索引值的型態` g_indices // `索引值陣列` ); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // 把正向跟反向的面都畫出來 glDisable(GL_CULL_FACE); // 使用CUBEMAP貼圖功能 glEnable(GL_TEXTURE_CUBE_MAP); // 套用CUBEMAP貼圖 glBindTexture( GL_TEXTURE_CUBE_MAP, g_TextureID ); // 開啟自動產生貼圖座標功能 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); // 以反射的值為貼圖座標 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); // Trilinear filter glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); // 使用自動normalize功能 glEnable(GL_NORMALIZE); // 計算出一個可以轉換到鏡頭座標系的矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); Matrix4x4 world_view_matrix = g_world_matrix * view_matrix; glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); // 傳入0代表不套用模型中的材質, 經由外部來設定. g_Model_OpenGL.Render(0); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // 設定要用陣列的方式傳入頂點位置跟顏色 glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), g_pSphereVertices); glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), g_pSphereVertices[0].m_RGBA); // 計算出一個可以轉換到鏡頭座標系的矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &view_matrix); glDrawElements( GL_TRIANGLES, // 指定所要畫的基本圖形種類 g_iNumSphereIndices, // 有幾個索引值 GL_UNSIGNED_SHORT, // 索引值的型態 g_pSphereIndices // 索引值陣列 ); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // 設定好GPU要去哪讀取頂點座標資料 glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), &g_vertices[0].m_Position); // 設定好GPU要去哪讀取頂點顏色資料 glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), &g_vertices[0].m_RGBA); // 設定要變更GL_MODELVIEW矩陣 glMatrixMode(GL_MODELVIEW); // 設定轉換矩陣 Matrix4x4 world_view_matrix = g_object_matrix * g_view_matrix; glLoadMatrixf( (float *) &world_view_matrix); // 畫出金字塔的8條邊線 glDrawElements( GL_TRIANGLES, // 指定所要畫的基本圖形種類 18, // 有幾個索引值 GL_UNSIGNED_SHORT, // 索引值的型態 g_indices // 索引值陣列 ); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 設定要用陣列的方式傳入頂點位置跟顏色 glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // 在此不需要用到zbuffer glDisable(GL_DEPTH_TEST); //glDepthFunc(GL_ALWAYS); glDepthMask(GL_FALSE); { // 不再用單一顏色來清除畫面, // 把整個畫面用磚墻圖片蓋過去 // 把modelview, projection矩陣設成單位矩陣 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // 套用貼圖 glBindTexture(GL_TEXTURE_2D, g_Texture0_ID); // 畫出矩形, 同時會清除ZBuffer glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), &g_FullScreenQuad[0].m_Position); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), &g_FullScreenQuad[0].m_Texcoord); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 把存放在stack中的projection取回來 glPopMatrix(); } { // 開啟混色功能 glEnable(GL_BLEND); // source_blend_factor = 1 // dest_blend_factor = 1 // 混色公式= source_color * 1 + dest_color * 1 glBlendFunc(GL_ONE, GL_ONE); // 套用貼圖 glBindTexture(GL_TEXTURE_2D, g_Texture1_ID); // 套入轉換矩陣 glMatrixMode(GL_PROJECTION); glLoadMatrixf( (float *) &g_proj_matrix); Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); Matrix4x4 world_view_matrix = g_world_matrix * view_matrix; glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); // 畫出矩形 glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), &g_Quad[0].m_Position); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), &g_Quad[0].m_Texcoord); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 關閉混色功能 glDisable(GL_BLEND); } // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// `使用OpenGL來繪圖` void RenderFrameOpenGL(void) { // `清除畫面` glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // `設定好GPU要去哪讀取頂點座標資料` glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), &g_vertices[0].m_Position); // `設定好GPU要去哪讀取頂點顏色資料` glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), &g_vertices[0].m_RGBA); // `設定要變更GL_MODELVIEW矩陣` glMatrixMode(GL_MODELVIEW); static float angle = 0.0f; angle += 0.01f; // `設定轉換矩陣` Matrix4x4 world_view_matrix = g_view_matrix; // `乘上旋轉矩陣` world_view_matrix.RotateZ(angle); glLoadMatrixf( (float *) &world_view_matrix); // `畫出金字塔的8條邊線` glDrawElements( GL_TRIANGLES, // `指定所要畫的基本圖形種類` 18, // `有幾個索引值` GL_UNSIGNED_SHORT, // `索引值的型態` g_indices // `索引值陣列` ); // `把背景backbuffer的畫面呈現出來` GutSwapBuffersOpenGL(); }
// 使用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) { { // `使用`g_framebuffer framebuffer object glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_framebuffer); glViewport(0, 0, 512, 512); // `清除畫面` glClearColor(0.4f, 0.4f, 0.4f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // RenderSolarSystemOpenGL(); } { // `使用主framebuffer object, 也就是視窗.` glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); int w, h; GutGetWindowSize(w, h); glViewport(0, 0, w, h); //` 清除畫面` glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // `計算出一個可以轉換到鏡頭座標系的矩陣` Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); Matrix4x4 world_view_matrix = world_matrix * view_matrix; glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); // `設定頂點資料格式` glEnableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, g_texture); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), g_Quad_Inv[0].m_Position); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), g_Quad_Inv[0].m_Texcoord); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } // `把背景backbuffer的畫面呈現出來` GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 設定轉換矩陣 Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix = g_Control.GetObjectMatrix(); Matrix4x4 world_view_matrix = world_matrix * view_matrix; glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &view_matrix); SetupLightingOpenGL(); glLoadMatrixf( (float *) &world_view_matrix); g_Model_OpenGL.Render(); // 把背景backbuffer的畫面呈現出來 GutSwapBuffersOpenGL(); }
// `使用OpenGL來繪圖` void RenderFrameOpenGL(void) { // `清除畫面` glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // `把正向跟反向的面都畫出來` glDisable(GL_CULL_FACE); // `設定要用陣列的方式傳入頂點位置跟顏色` glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // `計算出一個可以轉換到鏡頭座標系的矩陣` Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); Matrix4x4 world_view_matrix = g_world_matrix * view_matrix; glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); GLint modes[] = { GL_REPEAT, // `左下角` GL_MIRRORED_REPEAT, // `左上角` GL_CLAMP_TO_EDGE, // `右下角` GL_CLAMP_TO_BORDER, // `右上角` }; float border_color[4] = {0.5f, 0.5f, 0.5f, 0.5f}; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); for ( int i=0; i<4; i++ ) { glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VT), g_Quads[i][0].m_Position); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex_VT), g_Quads[i][0].m_Texcoord); // `套用不同的貼圖座標解讀模式` // GL_TEXTURE_WRAP_S `設定水平方向解讀模式` glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, modes[i]); // GL_TEXTURE_WRAP_T `設定垂直方向解讀模式` glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, modes[i]); // `畫出格子` glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } // `把背景backbuffer的畫面呈現出來` GutSwapBuffersOpenGL(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // 清除畫面 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // 把正向跟反向的面都畫出來 glDisable(GL_CULL_FACE); // 設定要用陣列的方式傳入頂點位置跟顏色 glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VCN), &g_Quad[0].m_Position); glColorPointer (4, GL_FLOAT, sizeof(Vertex_VCN), &g_Quad[0].m_Color); // 計算出一個可以轉換到鏡頭座標系的矩陣 Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); Matrix4x4 world_view_matrix = g_world_matrix * view_matrix; glMatrixMode(GL_MODELVIEW); glLoadMatrixf( (float *) &world_view_matrix); // 畫出格子 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 把背景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); // 計算出一個非平行投影的矩陣 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) { // `取得視窗大小` int w, h; GutGetWindowSize(w, h); // `清除畫面` glClearColor(0.4f, 0.4f, 0.4f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Vector4 camera_lookat(0.0f, 0.0f, 0.0f); Matrix4x4 ortho_proj = GutMatrixOrthoRH_OpenGL(20.0f, 20.0f, 0.1f, 100.0f); { // `前視圖` glViewport(0, h/2, w/2, h/2); // view matrix Vector4 camera_pos(0.0f, -20.0f, 0.0f); Vector4 camera_up(0.0f, 0.0f, 1.0f); g_view_matrix = GutMatrixLookAtRH(camera_pos, camera_lookat, camera_up); // projection matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(&ortho_proj[0][0]); // render objects RenderSolarSystemOpenGL(); } { // `上視圖` glViewport(w/2, h/2, w/2, h/2); // view matrix Vector4 camera_pos(0.0f, 0.0f, 20.0f); Vector4 camera_up(0.0f, 1.0f, 0.0f); g_view_matrix = GutMatrixLookAtRH(camera_pos, camera_lookat, camera_up); // projection matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(&ortho_proj[0][0]); // render objects RenderSolarSystemOpenGL(); } { // `右視圖` glViewport(0, 0, w/2, h/2); // view matrix Vector4 camera_pos(20.0f, 0.0f, 0.0f); Vector4 camera_up(0.0f, 0.0f, 1.0f); g_view_matrix = GutMatrixLookAtRH(camera_pos, camera_lookat, camera_up); // projection matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(&ortho_proj[0][0]); // render objects RenderSolarSystemOpenGL(); } { // `使用者視角` glViewport(w/2, 0, w/2, h/2); // object * view matrix Matrix4x4 object_matrix = g_Control.GetObjectMatrix(); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); g_view_matrix = object_matrix * view_matrix; // projection matrix glMatrixMode(GL_PROJECTION); glLoadMatrixf(&g_projection_matrix[0][0]); // render objects RenderSolarSystemOpenGL(); } { // `畫出viewport的邊界` glViewport(0, 0, w, h); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); // projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity(); // worldview matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // `畫邊界` glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), g_Border); glDrawArrays(GL_LINES, 0, 4); glPopClientAttrib(); } // `把背景backbuffer的畫面呈現出來` GutSwapBuffersOpenGL(); }
// `使用OpenGL來繪圖` void RenderFrameOpenGL(void) { // `取得視窗大小` int w, h; GutGetWindowSize(w, h); // `清除畫面` glClearColor(0.4f, 0.4f, 0.4f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // `在螢幕上畫出行星運動` RenderSolarSystemOpenGL(false); /* `啟動Selection Buffer, 硬體會試著去重畫一次3D物件,` `但不會更新畫面, 只會記錄下落在畫面中某個范圍內所有3D物件.` */ int x,y,buttons[3]; GutGetMouseState(x, y, buttons); if ( buttons[0] ) { GLint viewport[4]; glSelectBuffer(BUFSIZE,selectBuf); glRenderMode(GL_SELECT); glInitNames(); glGetIntegerv(GL_VIEWPORT,viewport); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // `設定Selection Buffer的檢查范圍` gluPickMatrix(x, viewport[3]-y, 3, 3, viewport); float fRatio = (viewport[2]+0.0) / viewport[3]; glMultMatrixf( (float *)&g_projection_matrix ); // `在Selection Buffer中畫出3D物件` RenderSolarSystemOpenGL(true); int hits = glRenderMode(GL_RENDER); GLuint *ptr = selectBuf; GLuint Zmin = 0xffffffff; GLuint SelectedObject = 0; // `找出檢查范圍中, 距離鏡頭最近的物體.` for ( int i=0; i<hits; i++, ptr+=4 ) { if ( ptr[1] < Zmin ) { Zmin = ptr[1]; SelectedObject = ptr[3]; } } switch(SelectedObject) { default: case 0: printf("Nothing\r"); break; case 1: printf("Sun \r"); break; case 2: printf("Earth \r"); break; } glMatrixMode(GL_PROJECTION); glPopMatrix(); } // `把背景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(); }
// 使用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(); }
// `使用OpenGL來繪圖` void RenderFrameOpenGL(void) { // `清除畫面` glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // `設定要用陣列的方式傳入頂點位置跟顏色` glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // `計算出一個可以轉換到鏡頭座標系的矩陣` Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); Matrix4x4 world_view_matrix; glMatrixMode(GL_MODELVIEW); // `載入鏡頭轉換矩陣` glLoadMatrixf( (float *) &view_matrix ); glPushMatrix(); // `把目前的矩陣存到stack里` // `太陽, 套入滑鼠的旋轉控制.` glRotatef(FastMath::RadianToDegree(g_fRotate_X), 1.0f, 0.0f, 0.0f); glRotatef(FastMath::RadianToDegree(g_fRotate_Y), 0.0f, 1.0f, 0.0f); 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); // `水星` glPushMatrix(); // `把目前的矩陣存到stack里` float mercury_rotate_y = 360.0f * (g_simulation_days / days_a_year_mercury); glRotatef(mercury_rotate_y, 0.0f, 1.0f, 0.0f); glTranslatef(mercury_to_sun_distance, 0.0f, 0.0f); 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); // `從stack里pop出一個矩陣, 并套用到目前所指定要操作的矩陣`GL_MODELVIEW glPopMatrix(); // `金星` glPushMatrix(); // `把目前的矩陣存到stack里` float venus_rotate_y = 360.0f * (g_simulation_days / days_a_year_venus); glRotatef(venus_rotate_y, 0.0f, 1.0f, 0.0f); glTranslatef(venus_to_sun_distance, 0.0f, 0.0f); 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); // `從stack里pop出一個矩陣, 并套用到目前所指定要操作的矩陣`GL_MODELVIEW glPopMatrix(); // `地球` glPushMatrix();// `把目前的矩陣存到stack里` float earth_rotate_y = 360.0f * (g_simulation_days / days_a_year); glRotatef(earth_rotate_y, 0.0f, 1.0f, 0.0f); glTranslatef(earth_to_sun_distance, 0.0f, 0.0f); 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); // `月球` float moon_rotate_y = 360.0f * (g_simulation_days / days_a_month); glRotatef(moon_rotate_y, 0.0f, 1.0f, 0.0f); glTranslatef(moon_to_earth_distance, 0.0f, 0.0f); 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); // `從stack里pop出一個矩陣, 并套用到目前所指定要操作的矩陣GL_MODELVIEW` glPopMatrix(); glPopMatrix(); // `把背景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(); 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(); }
// 使用OpenGL來繪圖 void RenderFrameOpenGL(void) { // `清除畫面` glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // `設定要用陣列的方式傳入頂點位置跟顏色` glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); // `計算出一個可以轉換到鏡頭座標系的矩陣` Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up); Vector4 border(-15.0f, 0.0f, -15.0f); Vector4 grid_position = border; const int grids_x = 30; const int grids_z = 30; for ( int x=0; x<grids_x; x++ ) { int grid_x = x & 0x07; grid_position[2] = border[2]; for ( int z=0; z<grids_z; z++ ) { int grid_z = z & 0x07; char c = g_map[grid_x][grid_z]; // `設定轉換矩陣` Matrix4x4 object_matrix; object_matrix.Identity(); if ( c==0 ) { object_matrix = view_matrix; object_matrix.Translate(grid_position); glLoadMatrixf( (float *) &object_matrix); // `設定GPU要去哪讀取頂點座標資料` glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), &g_road_vertices[0].m_Position); // `設定GPU要去哪讀取頂點顏色資料` glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), &g_road_vertices[0].m_RGBA); // `畫出地板` glDrawElements( GL_TRIANGLE_STRIP, // `指定所要畫的基本圖形種類` 4, // `有幾個索引值` GL_UNSIGNED_SHORT, // `索引值的型態` g_road_trianglestrip_indices // `索引值陣列` ); } else { // `設定金字塔的高度` object_matrix.Scale_Replace(1.0f, (float) c, 1.0f); object_matrix[3] = grid_position; Matrix4x4 world_view_matrix = object_matrix * view_matrix; glLoadMatrixf( (float *) &world_view_matrix); // `設定GPU要去哪讀取頂點座標資料` glVertexPointer(3, GL_FLOAT, sizeof(Vertex_VC), &g_pyramid_vertices[0].m_Position); // `設定GPU要去哪讀取頂點顏色資料` glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex_VC), &g_pyramid_vertices[0].m_RGBA); // `畫出金字塔` glDrawElements( GL_TRIANGLE_FAN, // `指定所要畫的基本圖形種類` 6, // `有幾個索引值` GL_UNSIGNED_SHORT, // `索引值的型態` g_pyramid_trianglefan_indices // `索引值陣列` ); } grid_position[2] += 1.0f; } grid_position[0] += 1.0f; } // `把背景backbuffer的畫面呈現出來` GutSwapBuffersOpenGL(); }