300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > openGL绘制带纹理太阳 地球 月亮 并且地球自转并且围绕太阳旋转。月亮自转也会围绕

openGL绘制带纹理太阳 地球 月亮 并且地球自转并且围绕太阳旋转。月亮自转也会围绕

时间:2021-11-12 23:18:56

相关推荐

openGL绘制带纹理太阳 地球 月亮 并且地球自转并且围绕太阳旋转。月亮自转也会围绕

openGL系列文章目录

前言

使用openGL绘制太阳、地球、月亮,太阳自转,地球自转并且围绕太阳旋转。月亮自转也会围绕地球旋转,其实月亮也会围绕太阳旋转的。

一、效果

还是有不满意的地方:

1.没有添加星空盒子

如果加上星空背景效果会好很多

2.贴图是我自己ps的,在太阳和月亮上有重合问题

二、实现思路

1.太阳、地球、月亮使用球体代替

2.我们的行星地球围绕太阳旋转的方式,以及月球围绕地球旋转的方式。

使用矩阵堆栈轻松地完成此操作。顾名思义,矩阵堆栈是一堆变换

矩阵。正如我们将看到的,矩阵堆栈使得创建和管理复杂的分层对象和场景变得容易,它

使得变换可以构建在其他变换之上(或者从其他变换中被移除)。

3. 太阳、地球、月亮纹理贴图

主要代码

main.cpp主程序

#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 "Utils.h"#include "Sphere.h"#include "camera.h"#include <iostream>#include <string>#include <fstream>#include <vector>#include <stack>using namespace std;static const int screen_width = 1920;static const int screen_height = 1080;int width = 0;int height = 0;GLuint renderingProgram = 0;static const int numberVAOs = 1;static const int numberVBOs = 3;GLuint vao[numberVAOs] = {0 };GLuint vbo[numberVBOs] = {0 };float cameraLocX = 0.f, cameraLocY = 0.f, cameraLocZ = 0.f;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;float aspect = 0.f;int mvLoc = 0;int projLoc = 0;float rotAmt = 0.f;glm::mat4 mMat(1.f), vMat(1.f), pMat(1.f), mvMat(1.f);//vector<glm::mat4> mvStack;GLuint sunTextureId = 0, earthTextureId = 0, moonTextureId = 0;Sphere sun = Sphere(48);Sphere earth = Sphere(48);Sphere moon = Sphere(48);GLboolean keys[1024] = {GL_FALSE };Camera camera(glm::vec3(0.f, 0.f, 5.f));GLfloat lastFrame = 0.0f;GLfloat deltaTime = 0.0f;GLboolean firstMouse = GL_TRUE;GLfloat lastX = 0.f;GLfloat lastY = 0.f;std::stack<glm::mat4> mvStack; //注意不要和vsctor<glm::mat4>相混淆void setupVertices(){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(numberVAOs, vao);glBindVertexArray(vao[0]);glGenBuffers(numberVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);size_t sizeFloat = sizeof(float);glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &(pValues[0]), GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &(tValues[0]), GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, nValues.size() * sizeof(float), &(nValues[0]), GL_STATIC_DRAW);}void press_key_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] = GL_TRUE;}else if (action == GLFW_RELEASE){//glfwSetWindowShouldClose(window, GL_FALSE);keys[key] = GL_FALSE;}}void key_movement_callback(){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);}}void mouse_move_callback(GLFWwindow* window, double xPos, double yPos){if (firstMouse){lastX = xPos;lastY = yPos;firstMouse = GL_FALSE;}GLfloat xOffset = xPos - lastX;GLfloat yOffset = lastY - yPos;lastX = xPos;lastY = yPos;camera.ProcessMouseMovement(xOffset, yOffset);}void scroll_callback(GLFWwindow* window, double xPos, double yPos){camera.ProcessMouseScroll(xPos);}void init(GLFWwindow* window){renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");glfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);glfwGetFramebufferSize(window, &width, &height);setupVertices();sunTextureId = Utils::loadTexture("resource/shining.jpg");earthTextureId = Utils::loadTexture("resource/earth.jpg");moonTextureId = Utils::loadTexture("resource/moon.jpg");}void display(GLFWwindow* window, float currentTime){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(0.1f, 0.1f, 0.4f, 1.f);//必不可少!!!否则窗口是黑的,不会渲染任何东西glUseProgram(renderingProgram);GLfloat currentTimeFrame = glfwGetTime();deltaTime = currentTimeFrame - lastFrame;lastFrame = currentTimeFrame;mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");key_movement_callback();//移动相机矩阵:这里必须是-cameraZ,否则相机看不到球体//vMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, -cameraZ));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), currentTime * 0.1f, glm::vec3(0.f, 1.f, 0.f));pMat = glm::perspective(camera.Zoom, (GLfloat)screen_width / (GLfloat)screen_height, 0.01f, 1000.f);//右乘规则//mvMat = mMat * vMat; //金字塔会离开视口mvMat = vMat * mMat;//将视图矩阵压入堆栈mvStack.push(vMat);//更改一个uniform矩阵变量或数组的值。要更改的uniform变量的位置由location指定,location的值应该由glGetUniformLocation函数返回// 将透视矩阵和MV 矩阵复制给相应的统一变量/*通过一致变量(uniform修饰的变量)引用将一致变量值传入渲染管线。location : uniform的位置。count : 需要加载数据的数组元素的数量或者需要修改的矩阵的数量。transpose : 指明矩阵是列优先(column major)矩阵(GL_FALSE)还是行优先(row major)矩阵(GL_TRUE)。value : 指向由count个元素的数组的指针。*/glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));// ---------------------- sun/*堆栈顶部的矩阵复制一份,并和其他的变换结合,然后再利用这个命令把新的矩阵副本推入堆栈中。*/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]);//指定了渲染时索引值为 index 的顶点属性数组的数据格式和位置/*Parametersindex指定要修改的顶点属性的索引值size指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(梦维:如position是由3个(x, y, z)组成,而颜色是4个(r, g, b, a))type指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。normalized指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)。stride指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。pointer指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为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);/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_NEAREST_MIPMAP_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_NEAREST_MIPMAP_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_NEAREST_MIPMAP_NEAREST);glBindTexture(GL_TEXTURE_2D, sunTextureId);*///背面剔除,默认情况下,背面剔除是关闭的//glEnable(GL_CULL_FACE);//glFrontFace(GL_CCW);glDrawArrays(GL_TRIANGLES, 0, sun.getNumIndices());mvStack.pop();/********************************** earth *///复制一份堆栈顶部矩阵压入堆栈/*push():在堆栈顶部创建一个新的条目。我们通常会把目前在堆栈顶部的矩阵复制一份,并和其他的变换结合,然后再利用这个命令把新的矩阵副本推入堆栈中。*///top():在不移除的情况下,返回堆栈最顶部矩阵的引用。mvStack.push(mvStack.top());mvStack.top() *= glm::translate(glm::mat4(1.f), glm::vec3(glm::sin((float)currentTime) * 2.5f, glm::cos((float)currentTime) * 0.4, glm::cos((float)currentTime) * 0.5f));mvStack.push(mvStack.top());//地球绕太阳旋转,即绕Y轴旋转mvStack.top() *= glm::rotate(glm::mat4(1.f), (float)currentTime, glm::vec3(0.f, 1.f, 0.f));mvStack.top() *= glm::scale(glm::mat4(1.f), glm::vec3(0.4f));//更改一个uniform矩阵变量或数组的值。要更改的uniform变量的位置由location指定,location的值应该由glGetUniformLocation函数返回// 将透视矩阵和MV 矩阵复制给相应的统一变量/*通过一致变量(uniform修饰的变量)引用将一致变量值传入渲染管线。location : uniform的位置。count : 需要加载数据的数组元素的数量或者需要修改的矩阵的数量。transpose : 指明矩阵是列优先(column major)矩阵(GL_FALSE)还是行优先(row major)矩阵(GL_TRUE)。value : 指向由count个元素的数组的指针。*/glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvStack.top()));glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);//指定了渲染时索引值为 index 的顶点属性数组的数据格式和位置/*Parametersindex指定要修改的顶点属性的索引值size指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(梦维:如position是由3个(x, y, z)组成,而颜色是4个(r, g, b, a))type指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。normalized指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)。stride指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。pointer指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0。*/glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);//启用或禁用通用顶点属性数组,参数0索引和着色器中的layout(location = 0)中的0相对应glEnableVertexAttribArray(0);//绑定到地球纹理坐标缓冲区glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, earthTextureId);//背面剔除,默认情况下,背面剔除是关闭的glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glDrawArrays(GL_TRIANGLES, 0, earth.getNumIndices());mvStack.pop();mvStack.pop();/**************************************** moon *///复制一份堆栈顶部矩阵压入堆栈/*push():在堆栈顶部创建一个新的条目。我们通常会把目前在堆栈顶部的矩阵复制一份,并和其他的变换结合,然后再利用这个命令把新的矩阵副本推入堆栈中。*///top():在不移除的情况下,返回堆栈最顶部矩阵的引用。mvStack.push(mvStack.top());mvStack.top() *= glm::translate(glm::mat4(1.f), glm::vec3(glm::sin((float)currentTime) * 3.f, glm::cos((float)currentTime) * 0.8f, glm::cos((float)currentTime) * 3.0f));mvStack.push(mvStack.top());//月球绕地球旋转,即绕Y轴旋转mvStack.top() *= glm::rotate(glm::mat4(1.f), (float)currentTime * 4.f, glm::vec3(0.f, 1.f, 0.f));mvStack.top() *= glm::scale(glm::mat4(1.f), glm::vec3(0.2f));//更改一个uniform矩阵变量或数组的值。要更改的uniform变量的位置由location指定,location的值应该由glGetUniformLocation函数返回// 将透视矩阵和MV 矩阵复制给相应的统一变量/*通过一致变量(uniform修饰的变量)引用将一致变量值传入渲染管线。location : uniform的位置。count : 需要加载数据的数组元素的数量或者需要修改的矩阵的数量。transpose : 指明矩阵是列优先(column major)矩阵(GL_FALSE)还是行优先(row major)矩阵(GL_TRUE)。value : 指向由count个元素的数组的指针。*/glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvStack.top()));glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);//指定了渲染时索引值为 index 的顶点属性数组的数据格式和位置/*Parametersindex指定要修改的顶点属性的索引值size指定每个顶点属性的组件数量。必须为1、2、3或者4。初始值为4。(梦维:如position是由3个(x, y, z)组成,而颜色是4个(r, g, b, a))type指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。normalized指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)。stride指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0。pointer指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0。*/glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);//启用或禁用通用顶点属性数组,参数0索引和着色器中的layout(location = 0)中的0相对应glEnableVertexAttribArray(0);//绑定到地球纹理坐标缓冲区glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, moonTextureId);//背面剔除,默认情况下,背面剔除是关闭的glEnable(GL_CULL_FACE | GL_DEPTH_TEST);glFrontFace(GL_CCW);glDepthFunc(GL_LEQUAL);glDrawArrays(GL_TRIANGLES, 0, moon.getNumIndices());mvStack.pop();mvStack.pop();mvStack.pop();星空盒//GLfloat skyboxVertices[] = {//// Positions//-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//};//GLuint skyboxVAO, skyboxVBO;//glGenVertexArrays(1, &skyboxVAO);//glGenBuffers(1, &skyboxVBO);//glBindVertexArray(skyboxVAO);//glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);//glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);//glEnableVertexAttribArray(0);//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);//glBindVertexArray(0);//vector<const GLchar*> faces;//faces.push_back("resource/right.jpg");//faces.push_back("resource/left.jpg");//faces.push_back("resource/top.jpg");//faces.push_back("resource/bottom.jpg");//faces.push_back("resource/front.jpg");//faces.push_back("resource/back.jpg");}void window_size_callback(GLFWwindow* window, int newWidth, int newHeight){glViewport(0, 0, newWidth, newHeight);aspect = (float)newWidth / (float)newHeight;pMat = glm::perspective(glm::radians(45.f), aspect, 0.01f, 1000.f);}// Loads a cubemap texture from 6 individual texture faces// Order should be:// +X (right)// -X (left)// +Y (top)// -Y (bottom)// +Z (front)// -Z (back)GLuint loadCubemap(vector<const GLchar*> faces){GLuint textureId;glGenTextures(1, &textureId);glBindTexture(GL_TEXTURE_CUBE_MAP, textureId);int width, height;unsigned char* image = nullptr;for (GLuint i = 0; i < faces.size(); i++){image = SOIL_load_image(faces[i], &width, &height, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);SOIL_free_image_data(image);}glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);glBindTexture(GL_TEXTURE_CUBE_MAP, 0);return textureId;}// This function loads a texture from file. Note: texture loading functions like these are usually // managed by a 'Resource Manager' that manages all resources (like textures, models, audio). // For learning purposes we'll just define it as a utility function.GLuint loadTexture(GLchar* path, GLboolean alpha /* = GL_FALSE */){GLuint textureId;glGenTextures(1, &textureId);glBindTexture(GL_TEXTURE_2D, textureId);int width, height;unsigned char* image = SOIL_load_image(path, &width, &height, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glBindTexture(GL_TEXTURE_2D, 0);SOIL_free_image_data(image);return textureId;}int main(){int glfwState = glfwInit();if (glfwState == GLFW_FALSE){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, GL_TRUE);GLFWwindow* window = glfwCreateWindow(screen_width, screen_height, "Sun earth moon", 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);glfwSetKeyCallback(window, press_key_callback);glfwSetCursorPosCallback(window, mouse_move_callback);glfwSetScrollCallback(window, scroll_callback);//一定要初始化glew,否则,无法创建着色器句柄int glewState = glewInit();if (glewState != GLEW_OK){cout << "GLEW initialize failed,invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}const GLubyte* renderer = glGetString(GL_RENDERER);const GLubyte* vendor = glGetString(GL_VENDOR);const GLubyte* version = glGetString(GL_VERSION);const GLubyte* glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);GLint major, minor;glGetIntegerv(GL_MAJOR_VERSION, &major);glGetIntegerv(GL_MINOR_VERSION, &minor);printf("GL Vendor : %s\n", vendor);printf("GL Renderer : %s\n", renderer);printf("GL Version (string) : %s\n", version);printf("GL Version (integer) : %d.%d\n", major, minor);printf("GLSL Version : %s\n", glslVersion);glfwSwapInterval(1);init(window);while (!glfwWindowShouldClose(window)){display(window, glfwGetTime());glfwSwapBuffers(window);glfwPollEvents();}return 0;}

vertShader.glsl 顶点着色器

#version 460 corelayout(location = 0) in vec3 position;layout(location = 1) in vec2 texCoords;uniform mat4 mv_matrix;uniform mat4 proj_matrix;layout(binding = 0) uniform sampler2D samp;out vec2 tc;void main(){gl_Position = proj_matrix * mv_matrix * vec4(position, 1.f);tc = texCoords;}

fragShader.glsl片元着色器

#version 460 corein vec2 tc;out vec4 color;//uniform mat4 mv_matrix;//uniform mat4 proj_matrix;layout(binding = 0) uniform sampler2D samp;void main(){color = texture(samp, tc);}

源码下载

源码下载地址

openGL绘制带纹理太阳 地球 月亮 并且地球自转并且围绕太阳旋转。月亮自转也会围绕地球旋转

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。