openGL天空盒实现-立方体贴图
openGL系列文章目錄
文章目錄
- openGL系列文章目錄
- 前言
- 一、pandas是什么?
- 二、實現步驟
- 1.主程序
- 2.著色器
- 運行效果
- 源碼下載
前言
如前所述,天空盒容易受到圖像畸變和接縫的影響。接縫指兩個紋理圖像接觸的地方(比
如沿著立方體的邊緣)有時出現的可見線條。圖9.8 展示了一個圖像上半部分出現接縫的示
例,它是運行程序9.1 時出現的偽影。為了避免接縫,需要仔細構建立方體貼圖圖像,并分
配精確的紋理坐標
一、pandas是什么?
構建天空盒的另一種方法是使用OpenGL 紋理立方體貼圖。OpenGL 立方體貼圖比我們
在上一節中看到的簡單方法稍微復雜一點。但是,使用OpenGL 立方體貼圖有自己的優點,
例如減少接縫以及支持環境貼圖。
OpenGL 紋理立方體貼圖類似于稍后將要研究的3D 紋理,它們都使用3 個紋理坐標訪
問——通常標記為(s, t, r)——而不是我們目前為止用到的兩個。OpenGL 紋理立方體貼圖
的另一個特性是,其中的圖像以紋理圖像的左上角(而不是通常的左下角)作為紋理坐標
(0, 0, 0),這通常是混亂產生的源頭。
程序9.1 中展示的方法通過讀入單個圖像來為立方體貼圖添加紋理,而程序9.2 中展示
的loadCubeMap()函數則讀入6 個單獨的立方體面圖像文件。正如我們在第5 章中所學的,
有許多方法可以讀取紋理圖像,我們選擇使用SOIL2 庫。在這里,SOIL2 用于實例化和加
載OpenGL 立方體貼圖也非常方便。我們先找到需要讀入的文件, 然后調用
SOIL_load_OGL_cubemap(),其參數包括6 個圖像文件和一些其他參數,類似于我們在第5
章中看到的SOIL_load_OGL_texture()。在使用OpenGL 立方體貼圖時,無須垂直翻轉紋理,
OpenGL 會自動進行處理,注意,loadCubeMap()函數放在“Utils.cpp”文件中。
init()函數現在包含一個函數調用以啟用GL_TEXTURE_CUBE_MAP_SEAMLESS,它告
訴OpenGL 嘗試混合立方體相鄰的邊以減少或消除接縫。在display()中,立方體的頂點像以
前一樣沿管線向下發送,但這次不需要發送立方體的紋理坐標。我們將會看到,OpenGL 紋
理立方體貼圖通常使用立方體的頂點位置作為其紋理坐標。之后禁用深度測試并繪制立方
體。然后為場景的其余部分重新啟用深度測試。
完成后的OpenGL 紋理立方體貼圖使用了int 類型的標識符進行引用。與陰影貼圖時一
樣,通過將紋理包裹模式設置為“夾緊到邊緣”,可以減少沿邊框的偽影。在這種情況下,
它還可以幫助進一步縮小接縫。請注意,這里需要為3 個紋理坐標s、t 和r 都設置紋理包
裹模式。
在片段著色器中使用名為samplerCube 的特殊類型的采樣器訪問紋理。在紋理立方體貼
圖中,從采樣器返回的值是沿著方向向量(s, t, r)從原點“看到”的紋素。因此,我們通常可
以簡單地使用傳入的插值頂點位置作為紋理坐標。在頂點著色器中,我們將立方體頂點位
置分配到輸出紋理坐標屬性中,以便在它們到達片段著色器時進行插值。另外需要注意,
在頂點著色器中,我們將傳入的視圖矩陣轉換為3×3,然后再轉換回4×4。這個“技巧”
有效地移除了平移分量,同時保留了旋轉(回想一下,平移值在轉換矩陣的第四列中)。這
樣,就將立方體貼圖固定在了攝像機位置,同時仍允許合成相機“環顧四周”。
二、實現步驟
1.主程序
#include "glew/glew.h" #include "glfw/glfw3.h" #include "glm/glm.hpp" #include "glm/gtc/matrix_transform.hpp" #include "glm/gtc/type_ptr.hpp" #include "Torus.h" #include "Utils.h" #include "Sphere.h" #include "camera.h" #include "SOIL2/SOIL2.h" #include <iostream> #include <fstream> #include <string> #include <stack>using namespace std;static const float pai = 3.1415926f; float toRadins(float degrees) { return degrees * 2.f * pai / (float)360.f; }static const int screenWidth = 1920; static const int screenHeight = 1080;GLuint renderingProgram = 0;static const int numVAOs = 1; static const int numVBOs = 6; float cameraX = 0.f, cameraY = 0.f, cameraZ = 5.f; float torLocX = 0.f, torLocY = 0.f, torLocZ = 0.f; GLuint vao[numVAOs] = { 0 }; GLuint vbo[numVBOs] = { 0 }; GLuint brickTexture = 0, skyboxTexture = 0; float rotAmt = 0.f;// variable allocation for display GLuint mvLoc = 0, projLoc = 0; int width = 0; int height = 0; float aspect = 0.f; glm::mat4 mMat(1.f), vMat(1.f), pMat(1.f), mvMat(1.f);Torus myTorus(0.5f, 0.2f, 48); int numTorusVertices = 0, numTorusIndices = 0;float sunLocX = 0.f, sunLocY = 0.f, sunLocZ = 0.f; float earthLocX = 0.f, earthLocY = 0.f, earthLocZ = 0.f; float moonLocX = 0.f, moonLocY = 0.f, moonLocZ = 0.f; GLuint sunTextureId = 0, earthTextureId = 0, moonTextureId = 0;Sphere sun = Sphere(48); Sphere earth = Sphere(48); Sphere moon = Sphere(48); std::stack<glm::mat4> mvStack; //注意不要和vector<glm::mat4>相混淆Camera camera(glm::vec3(0.f, 0.f, 5.f)); GLboolean keys[1024] = { GL_FALSE }; GLboolean b_firstMouse = GL_TRUE; float deltaTime = 0.f;float lastFrame = 0.f; float lastLocX = 0.f; float lastLocY = 0.f;void do_movement() {if (keys[GLFW_KEY_W]){camera.ProcessKeyboard(FORWARD, deltaTime);}if (keys[GLFW_KEY_S]){camera.ProcessKeyboard(BACKWARD, deltaTime);}if (keys[GLFW_KEY_A]){camera.ProcessKeyboard(LEFT, deltaTime);}if (keys[GLFW_KEY_D]){camera.ProcessKeyboard(RIGHT, deltaTime);}/*if (keys[GLFW_KEY_ESCAPE]){glfwSetWindowShouldClose(window, GL_TRUE);}*/ }void key_press_callback(GLFWwindow* window, int key, int scancode, int action, int mode) {if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)){glfwSetWindowShouldClose(window, GL_TRUE);}if (action == GLFW_PRESS){keys[key] = GLFW_TRUE; //這里一定一定不能寫成“==“,否則 按鍵WSAD按鍵失效!!!!!!!}else if (action == GLFW_RELEASE){keys[key] = GLFW_FALSE; //這里一定一定不能寫成“==“,否則 按鍵WSAD按鍵失效!!!!!!!} }void mouse_move_callback(GLFWwindow* window, double xPos, double yPos) {if (b_firstMouse){lastLocX = xPos;lastLocY = yPos;b_firstMouse = GL_FALSE;}float xOffset = xPos - lastLocX;float yOffset = lastLocY - yPos;lastLocX = xPos;lastLocY = yPos;camera.ProcessMouseMovement(xOffset, yOffset);}void mouse_scroll_callback(GLFWwindow* window, double xPos, double yPos) {camera.ProcessMouseScroll(yPos); }void setupVertices(void) {float cubeVertexPosition[108] ={-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f,1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f,-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f};float cubeTextureCoords[72] ={1.00f, 0.6666666f, 1.00f, 0.3333333f, 0.75f, 0.3333333f, // back face lower right0.75f, 0.3333333f, 0.75f, 0.6666666f, 1.00f, 0.6666666f, // back face upper left0.75f, 0.3333333f, 0.50f, 0.3333333f, 0.75f, 0.6666666f, // right face lower right0.50f, 0.3333333f, 0.50f, 0.6666666f, 0.75f, 0.6666666f, // right face upper left0.50f, 0.3333333f, 0.25f, 0.3333333f, 0.50f, 0.6666666f, // front face lower right0.25f, 0.3333333f, 0.25f, 0.6666666f, 0.50f, 0.6666666f, // front face upper left0.25f, 0.3333333f, 0.00f, 0.3333333f, 0.25f, 0.6666666f, // left face lower right0.00f, 0.3333333f, 0.00f, 0.6666666f, 0.25f, 0.6666666f, // left face upper left0.25f, 0.3333333f, 0.50f, 0.3333333f, 0.50f, 0.0000000f, // bottom face upper right0.50f, 0.0000000f, 0.25f, 0.0000000f, 0.25f, 0.3333333f, // bottom face lower left0.25f, 1.0000000f, 0.50f, 1.0000000f, 0.50f, 0.6666666f, // top face upper right0.50f, 0.6666666f, 0.25f, 0.6666666f, 0.25f, 1.0000000f // top face lower left};/*numTorusVertices = myTorus.getNumVertices();numTorusIndices = myTorus.getNumIndices();vector<int> ind = myTorus.getIndices();vector<glm::vec3> vert = myTorus.getVertices();vector<glm::vec2> text = myTorus.getTexCoords();vector<glm::vec3> norm = myTorus.getNormals();vector<float> pValues;vector<float> tValues;vector<float> nValues;for (int i=0; i<numTorusVertices; i++){pValues.push_back(vert[i].x);pValues.push_back(vert[i].y);pValues.push_back(vert[i].z);tValues.push_back(text[i].s);tValues.push_back(text[i].t);nValues.push_back(norm[i].x);nValues.push_back(norm[i].y);nValues.push_back(norm[i].z);}glGenVertexArrays(numVAOs, vao);glBindVertexArray(vao[0]);glGenBuffers(numVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);size_t cubeVertexPositionSize = sizeof(cubeVertexPosition);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertexPosition) * sizeof(float), cubeVertexPosition, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeTextureCoords) * sizeof(float), cubeTextureCoords, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &pValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &tValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * sizeof(int), &ind[0], GL_STATIC_DRAW);*/vector<int> ind = sun.getIndices();vector<glm::vec3> vert = sun.getVertices();vector<glm::vec2> text = sun.getTexCoords();vector<glm::vec3> norm = sun.getNormals();vector<glm::vec3> tang = sun.getTangents();vector<float> pValues; //頂點位置vector<float> tValues; //紋理坐標vector<float> nValues; //法線向量int numIndices = sun.getNumIndices();for (int i = 0; i < numIndices; i++){//pValues.push_back(vert[ind[i]].x);pValues.push_back((vert[ind[i]]).x);pValues.push_back((vert[ind[i]]).y);pValues.push_back((vert[ind[i]]).z);tValues.push_back((text[ind[i]]).s);tValues.push_back((text[ind[i]]).t);nValues.push_back((norm[ind[i]]).x);nValues.push_back((norm[ind[i]]).y);nValues.push_back((norm[ind[i]]).z);}glGenVertexArrays(numVAOs, vao);glBindVertexArray(vao[0]);glGenBuffers(numVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertexPosition) * sizeof(float), cubeVertexPosition, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeTextureCoords) * sizeof(float), cubeTextureCoords, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);size_t sizeFloat = sizeof(float);glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &(pValues[0]), GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &(tValues[0]), GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[4]);glBufferData(GL_ARRAY_BUFFER, nValues.size() * sizeof(float), &(nValues[0]), GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[5]);glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * sizeof(int), &ind[0], GL_STATIC_DRAW);/*glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &pValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &tValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * sizeof(int), &ind[0], GL_STATIC_DRAW);*/}void init(GLFWwindow* window) {renderingProgram = Utils::createShaderProgram("vertShader.vert", "fragShader.frag");glfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(toRadins(45.f), aspect, 0.01f, 1000.f);setupVertices();brickTexture = Utils::loadTexture("brick1.jpg");skyboxTexture = Utils::loadTexture("alien.jpg");sunTextureId = Utils::loadTexture("resource/shining.jpg");earthTextureId = Utils::loadTexture("resource/earth.jpg");moonTextureId = Utils::loadTexture("resource/moon.jpg");torLocX = 0.f, torLocY = -0.75f, torLocZ = 0.f;cameraX = 0.f, cameraY = 0.f, cameraZ = 5.f; }void display(GLFWwindow* window, double currentTime) {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(0.f, 0.5f, 1.f, 1.f);vMat = glm::translate(glm::mat4(1.f), glm::vec3(-cameraX, -cameraY, -cameraZ));// draw cube mapglUseProgram(renderingProgram);deltaTime = currentTime - lastFrame;lastFrame = currentTime;do_movement();//這句必須要有,否則鼠標中鍵失效pMat = glm::perspective(camera.Zoom, aspect, 0.01f, 1000.f);//沒有這句,背景就沒在相機視點上了,把圓環移到相機的位置mMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, 4.5f));vMat = camera.GetViewMatrix();mMat = glm::rotate(mMat, glm::radians(35.f), glm::vec3(1.f, 0.f, 0.f));mvMat = vMat * mMat;//將視圖矩陣壓入堆棧mvStack.push(vMat);mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(1);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, skyboxTexture);glEnable(GL_CULL_FACE); //開啟剔除操作效果//GL_CCW 表示窗口坐標上投影多邊形的頂點順序為逆時針方向的表面為正面。//GL_CW 表示窗口坐標上投影多邊形的頂點順序為順時針方向的表面為正面。glFrontFace(GL_CCW);// cube is CW, but we are viewing the insideglDisable(GL_DEPTH_TEST); //為了繪制背景天空盒,先關閉深度測試,時天空盒被物體遮擋glDrawArrays(GL_TRIANGLES, 0, 36); //繪制立方體貼圖glEnable(GL_DEPTH_TEST); draw scene (in this case it is just a torus//glUseProgram(renderingProgram);//mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");//projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");//mMat = glm::translate(glm::mat4(1.f), glm::vec3(torLocX, torLocY, torLocZ));//mMat = glm::rotate(mMat, toRadins(30.f), glm::vec3(1.f, 0.f, 0.f));//mvMat = vMat * mMat;//glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));//glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);//glEnableVertexAttribArray(0);紋理layout(location = 1)//glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);//glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);//glEnableVertexAttribArray(1);//glActiveTexture(GL_TEXTURE0);//glBindTexture(GL_TEXTURE_2D, brickTexture);//glClear(GL_DEPTH_BUFFER_BIT);//glEnable(GL_CULL_FACE);//glFrontFace(GL_CCW);//glDisable(GL_LEQUAL);//glDrawArrays(GL_TRIANGLES, 0, 36);//glEnable(GL_DEPTH_TEST);//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);//glDrawElements(GL_TRIANGLES, numTorusIndices, GL_UNSIGNED_INT, 0);/************************************ 太陽 ***********************************/glUseProgram(renderingProgram);mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");vMat = camera.GetViewMatrix();/*sunLocZ = -6.f;*/mMat = glm::translate(glm::mat4(1.f), glm::vec3(sunLocX, sunLocY, sunLocZ));mMat = glm::rotate(glm::mat4(1.f), (float)currentTime * 0.1f, glm::vec3(0.f, 1.f, 0.f));pMat = glm::perspective(camera.Zoom, (GLfloat)screenWidth / (GLfloat)screenHeight, 0.01f, 1000.f);//右乘規則//mvMat = mMat * vMat; //金字塔會離開視口mvMat = vMat * mMat;//將視圖矩陣壓入堆棧mvStack.push(vMat);glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));/*堆棧頂部的矩陣復制一份,并和其他的變換結合,然后再利用這個命令把新的矩陣副本推入堆棧中。*/mvStack.push(mvStack.top());//向矩陣堆棧頂部的矩陣添加平移mvStack.top() *= glm::translate(glm::mat4(1.f), glm::vec3(0.f, 0.f, 0.f));mvStack.push(mvStack.top());//在不移除的情況下,返回堆棧最頂部旋轉矩陣(繞X軸)的引用。mvStack.top() *= glm::rotate(glm::mat4(1.f), (float)glfwGetTime() * 0.4f, glm::vec3(0.f, 1.f, 0.f));glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvStack.top()));//綁定到太陽頂點緩沖區glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);//啟用或禁用通用頂點屬性數組,參數0索引和著色器中的layout(location = 0)中的0相對應,頂點位置glEnableVertexAttribArray(0);//綁定到紋理坐標緩沖區glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(1);//激活紋理坐標 glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, sunTextureId);//glDrawArrays(GL_TRIANGLES, 0, sun.getNumIndices());glBindBuffer(GL_ARRAY_BUFFER, vbo[4]);glDrawArrays(GL_TRIANGLES, 0, sun.getNumVertices());mvStack.pop();}void window_size_callback(GLFWwindow* window, int newWidth, int newHeight) {aspect = (float)newWidth / (float)newHeight;glViewport(0, 0, newWidth, newHeight);pMat = glm::perspective(toRadins(45.f), aspect, 0.01f, 1000.f); }int main(int argc, char** argv) {int glfwState = glfwInit();if (GLFW_FALSE == glfwState){cout << "GLFW initialize failed,invoke glfwInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "sky box simple", nullptr, nullptr);if (!window){cout << "GLFW create window failed,invoke glfwCreateWindow()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwMakeContextCurrent(window);glfwSetWindowSizeCallback(window, window_size_callback);glfwSetCursorPosCallback(window, mouse_move_callback);glfwSetScrollCallback(window, mouse_scroll_callback);glfwSetKeyCallback(window, key_press_callback);int glewState = glewInit();if (GLEW_OK != glewState){cout << "GLEW initialize failed,invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwSwapInterval(1);init(window);while (!glfwWindowShouldClose(window)){display(window, glfwGetTime());glfwSwapBuffers(window);glfwPollEvents(); //如果沒這句,程序直接掛了}glfwDestroyWindow(window);glfwTerminate();exit(EXIT_SUCCESS);return 0; }2.著色器
1.頂點著色器
#version 460 corelayout(location = 0) in vec3 position; layout(location = 1) in vec2 texCoord; out vec2 tc;uniform mat4 mv_matrix; uniform mat4 proj_matrix; layout(binding = 0) uniform sampler2D samp;void main(void) {tc = texCoord;gl_Position = proj_matrix * mv_matrix * vec4(position, 1.f); }2.片元著色器
#version 460 corein vec2 tc; out vec4 fragColor;uniform mat4 mv_matrix; uniform mat4 proj_matrix; layout(binding = 0) uniform sampler2D samp;void main(void) {fragColor = texture(samp, tc); }運行效果
源碼下載
源碼下載地址
總結
以上是生活随笔為你收集整理的openGL天空盒实现-立方体贴图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sysadmin.php,骆驼IPTV源
- 下一篇: EEGLAB使用流程