shader.h
#pragma once
#ifndef SHADER_H
#define SHADER_H
#include
#include
#include
#include
using namespace std;
#include
class Shader
{
public:
//程序ID
GLuint Program;
//构造器读取并且创建Shader
Shader(const GLchar *vertexSourcePath, const GLchar *fragmentSourcePath);
//使用Program
void Use();
};
#endif
shader.cpp
#include"Shader.h"
Shader::Shader(const GLchar *vertexSourcePath, const GLchar *fragmentSourcePath)
{
//1.从文件路径获得vertex/fragment代码
std::string vertexCode;
std::string framgmentCode;
std::ifstream vShaderFile;
std::ifstream fshaderFile;
vShaderFile.exceptions(std::ifstream::badbit);
fshaderFile.exceptions(std::ifstream::badbit);
try {
vShaderFile.open(vertexSourcePath);
fshaderFile.open(fragmentSourcePath);
std::stringstream vShaderStream, fShaderStream;
//读取文件缓冲到流
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fshaderFile.rdbuf();
//关闭文件句柄
vShaderFile.close();
fshaderFile.close();
//将流转化为GLchar数组
vertexCode = vShaderStream.str();
framgmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "Error::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
}
const GLchar* vShaderCode = vertexCode.c_str();
const GLchar* fShaderCode = framgmentCode.c_str();
//编译着色器
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
//顶点着色器
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout << "ERROR::SHADER:FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertex);
glDeleteShader(fragment);
}
void Shader::Use()
{
glUseProgram(this->Program);
}
Camera.h
#pragma once
#ifndef CAMERA_H_
#define CAMERA_H_
#include
#include
#include
#include
enum Camera_Movement {
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
const GLfloat YAW = -90.0f;
const GLfloat PITCH = 0.0f;
const GLfloat SPEED = 100.0f;
const GLfloat SENSITIVTY = 0.25f;
const GLfloat ZOOM = 45.0f;
class Camera
{
public:
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH);
Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch);
glm::mat4 GetViewMatrix();
void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime);
void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true);
void ProcessMouseScroll(GLfloat yoffset);
glm::vec3 GetCameraPosition();
GLfloat GetZoom();
private:
glm::vec3 Position;
glm::vec3 Front;
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 WorldUp;
GLfloat Yaw;//方位角
GLfloat Pitch;//倾斜角
GLfloat MovementSpeed;
GLfloat MouseSensitivity;
GLfloat Zoom;
void updateCameraVectors();
};
#endif
Camera.cpp
#include"Camera.h"
Camera::Camera(glm::vec3 position, glm::vec3 up, GLfloat yaw , GLfloat pitch) :Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM)
{
this->Position = position;
this->WorldUp = up;
this->Yaw = yaw;
this->Pitch = pitch;
this->updateCameraVectors();
}
Camera::Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch) :Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM)
{
this->Position = glm::vec3(posX, posY, posZ);
this->WorldUp = glm::vec3(upX, upY, upZ);
this->Yaw = yaw;
this->Pitch = pitch;
this->updateCameraVectors();
}
glm::mat4 Camera::GetViewMatrix()
{
return glm::lookAt(this->Position, this->Position + this->Front, this->Up);
}
void Camera::ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime)
{
GLfloat velocity = this->MovementSpeed*deltaTime;
if (direction == FORWARD)
this->Position += this->Front*velocity;
if (direction == BACKWARD)
this->Position -= this->Front*velocity;
if (direction == LEFT)
this->Position -= this->Right*velocity;
if (direction == RIGHT)
this->Position += this->Right*velocity;
}
void Camera::ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch)//方向角和倾斜角改变
{
xoffset *= this->MouseSensitivity;
yoffset *= this->MouseSensitivity;
this->Yaw += xoffset;
this->Pitch += yoffset;
if (constrainPitch)
{
if (this->Pitch > 89.0f)
this->Pitch = 89.0f;
if (this->Pitch < -89.0f)
this->Pitch = -89.0f;
}
this->updateCameraVectors();
return;
}
void Camera::ProcessMouseScroll(GLfloat yoffset)//视角方法缩小
{
if (this->Zoom >= 1.0f&&this->Zoom <= 45.0f)
this->Zoom -= yoffset;
if (this->Zoom <= 1.0f)
this->Zoom = 1.0f;
if (this->Zoom >= 45.0f)
this->Zoom=45.0f;
return;
}
void Camera::updateCameraVectors()//更新前方,右方,上方
{
glm::vec3 front;
front.x = cos(glm::radians(this->Yaw))*cos(glm::radians(this->Pitch));
front.y = sin(glm::radians(this->Pitch));
front.z = sin(glm::radians(this->Yaw))*cos(glm::radians(this->Pitch));
this->Front = glm::normalize(front);
this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp));
this->Up = glm::normalize(glm::cross(this->Right, this->Front));
}
glm::vec3 Camera::GetCameraPosition()
{
return glm::vec3(Position);
}
GLfloat Camera::GetZoom()
{
return Zoom;
}
solarsystem.cpp
#include
#define GLEW_STATIC
#include
#include
#include
#include
#include
#include
#include
#include
#include"Shader.h"
#include"Camera.h"
const float PI = 3.14159265359;
Camera camera(glm::vec3(0.0f, 0.0f, 10.0f));
const GLuint WIDTH = 1000, HEIGHT = 800;
GLfloat lastX = WIDTH / 2;
GLfloat lastY = HEIGHT / 2;
bool firstMouse = true;
GLfloat delatTime = 0.0f;//相邻两帧图像相隔时间
GLfloat lastFrame = 0.0f;//上一帧的时间
//视角会随着鼠标的移动进行移动
void mouse_callback(GLFWwindow*window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
GLfloat xoffset = xpos - lastX;
GLfloat yoffset = lastY- ypos ;
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);
return;
}
bool keys[1024];
//按键W,S,A,D按下后,视图会向前,后,左,右移动
void movement()
{
if (keys[GLFW_KEY_W])
camera.ProcessKeyboard(FORWARD, delatTime);
if (keys[GLFW_KEY_S])
camera.ProcessKeyboard(BACKWARD, delatTime);
if (keys[GLFW_KEY_D])
camera.ProcessKeyboard(RIGHT, delatTime);
if (keys[GLFW_KEY_A])
camera.ProcessKeyboard(LEFT, delatTime);
return;
}
void 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 (key >= 0 && key <= 1024)
{
if (action == GLFW_PRESS)
keys[key] = true;
else if (action == GLFW_RELEASE)
keys[key] = false;
}
return;
}
void scroll_callback(GLFWwindow*window, double xoffset, double yoffset)
{
camera.ProcessMouseScroll(yoffset / 10);
}
const int angleSpan = 9;
//sphere此函数计算用三角形组合进行模拟球,并计算球的法向量,和对应纹理位置
GLfloat* sphere(GLfloat radius)
{
std::vector temp_position;
//计算球上的顶点的位置
for (GLfloat row_angle = -90; row_angle <= 90; row_angle += angleSpan)
{
for (GLfloat col_angle = 0; col_angle < 360; col_angle += angleSpan)
{
GLfloat r = radius*glm::cos(glm::radians(row_angle));
GLfloat x = r*glm::cos(glm::radians(col_angle));
GLfloat y = radius*glm::sin(glm::radians(row_angle));
GLfloat z = r*glm::sin(glm::radians(col_angle));
temp_position.push_back(x);
temp_position.push_back(y);
temp_position.push_back(z);
}
}
int row = 180 / angleSpan + 1;
int col = 360 / angleSpan;
int k = col*(row - 2) * 6 * 8;
GLfloat*vertiices = new GLfloat[k];
int count = 0;
for (int i = 0; i < row; i++)
{
if (i != 0 && i != row - 1)
{
for (int j = 0; j < col; j++)
{
k = i*col + j;
glm::vec3 norm = glm::normalize(glm::vec3(temp_position[(k + col) * 3], temp_position[(k + col) * 3 + 1], temp_position[(k + col) * 3 + 2]));
vertiices[count++] = temp_position[(k + col) * 3];
vertiices[count++] = temp_position[(k + col) * 3+1];
vertiices[count++] = temp_position[(k + col) * 3+2];
vertiices[count++] = norm.x;
vertiices[count++] = norm.y;
vertiices[count++] = norm.z;
vertiices[count++] = (GLfloat)j*1.0 / col;
vertiices[count++] = (i+1)*1.0 / row;
int index = k + 1;
if (j == col - 1)
index -= col;
norm = glm::normalize(glm::vec3(temp_position[index * 3], temp_position[index * 3 + 1], temp_position[index * 3 + 2]));
vertiices[count++] = temp_position[index * 3];
vertiices[count++] = temp_position[index * 3 + 1];
vertiices[count++] = temp_position[index * 3 + 2];
vertiices[count++] = norm.x;
vertiices[count++] = norm.y;
vertiices[count++] = norm.z;
vertiices[count++] = (GLfloat)(j+1)*1.0 / col;
vertiices[count++] = i*1.0 / row;
norm = glm::normalize(glm::vec3(temp_position[k * 3], temp_position[k * 3 + 1], temp_position[k * 3 + 2]));
vertiices[count++] = temp_position[k * 3];
vertiices[count++] = temp_position[k * 3 + 1];
vertiices[count++] = temp_position[k * 3 + 2];
vertiices[count++] = norm.x;
vertiices[count++] = norm.y;
vertiices[count++] = norm.z;
vertiices[count++] = (GLfloat)j*1.0 / col;
vertiices[count++] = i*1.0 / row;
}
for (int j = 0; j < col; j++)
{
k = i*col + j;
glm::vec3 norm = glm::normalize(glm::vec3(temp_position[(k - col) * 3], temp_position[(k - col) * 3 + 1], temp_position[(k - col) * 3 + 2]));
vertiices[count++] = temp_position[(k - col) * 3];
vertiices[count++] = temp_position[(k - col) * 3 + 1];
vertiices[count++] = temp_position[(k - col) * 3 + 2];
vertiices[count++] = norm.x;
vertiices[count++] = norm.y;
vertiices[count++] = norm.z;
vertiices[count++] = (GLfloat)j*1.0 / col;
vertiices[count++] = (i - 1)*1.0 / row;
int index = k - 1;
if (j == 0)
index += col;
norm = glm::normalize(glm::vec3(temp_position[index * 3], temp_position[index * 3 + 1], temp_position[index * 3 + 2]));
vertiices[count++] = temp_position[index * 3];
vertiices[count++] = temp_position[index * 3 + 1];
vertiices[count++] = temp_position[index * 3 + 2];
vertiices[count++] = norm.x;
vertiices[count++] = norm.y;
vertiices[count++] = norm.z;
vertiices[count++] = (GLfloat)(j - 1)*1.0 / col;
vertiices[count++] = i*1.0 / row;
norm = glm::normalize(glm::vec3(temp_position[k * 3], temp_position[k * 3 + 1], temp_position[k * 3 + 2]));
vertiices[count++] = temp_position[k * 3];
vertiices[count++] = temp_position[k * 3 + 1];
vertiices[count++] = temp_position[k * 3 + 2];
vertiices[count++] = norm.x;
vertiices[count++] = norm.y;
vertiices[count++] = norm.z;
vertiices[count++] = (GLfloat)j*1.0 / col;
vertiices[count++] = i*1.0 / row;
}
}
}
return vertiices;
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "solar system", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwMakeContextCurrent(window);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
glfwTerminate();
return -1;
}
Shader SunShader("sun.vs", "sun.frag");
Shader PlanetShader("planet.vs", "planet.frag");
glViewport(0, 0, WIDTH, HEIGHT);
WCHAR *sun[4] = { TEXT("sun.bmp"),TEXT("venus.bmp"),TEXT("earth.bmp"),TEXT("moon.bmp") };
HBITMAP hBMP[4];
BITMAP BMP[4];
GLuint texture[4];
glGenTextures(4, texture);
for (int i = 0; i < 4; i++)//将四个图片读入
{
hBMP[i] = (HBITMAP)LoadImage(GetModuleHandle(NULL), sun[i], IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
GetObject(hBMP[i], sizeof(BMP[i]), &BMP[i]);
glBindTexture(GL_TEXTURE_2D, texture[i]);
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BMP[i].bmWidth, BMP[i].bmHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, BMP[i].bmBits);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
glUniform1i(glGetUniformLocation(SunShader.Program, "texture_1"), 0);
glUniform1i(glGetUniformLocation(PlanetShader.Program, "material.diffuse"), 0);
GLfloat *planet;
planet = sphere(1);
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 4560*8*sizeof(GLfloat), planet, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
GLfloat Sun, venus, venus_sun, earth, earth_sun, moon, moon_earth;//公转或者自转角度
Sun = venus = venus_sun = earth = earth_sun = moon = moon_earth = 0;
while (!glfwWindowShouldClose(window))
{
GLfloat currentFrame = glfwGetTime();
delatTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glfwPollEvents();
movement();
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//绘制太阳
SunShader.Use();
glm::mat4 view;
view = camera.GetViewMatrix();
glm::mat4 model;
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -500.0f));
model = glm::rotate(model, Sun/180*PI, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 projection = glm::perspective(camera.GetZoom(), (GLfloat)WIDTH /(GLfloat) HEIGHT, 0.1f, 40000.0f);
glUniformMatrix4fv(glGetUniformLocation(SunShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(SunShader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(SunShader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform1f(glGetUniformLocation(SunShader.Program, "R"), 40);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES,0, 4560);
glBindVertexArray(0);
//绘制金星
PlanetShader.Use();
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -500.0f));
model = glm::rotate(model, venus_sun/180*PI, glm::vec3(glm::sin(glm::radians(30.0f)), glm::cos(glm::radians(30.0f)), 0));
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 100.0f));
model = glm::rotate(model, venus/180*PI, glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(glGetUniformLocation(PlanetShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(PlanetShader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(PlanetShader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform3f(glGetUniformLocation(PlanetShader.Program, "lightPos"), 0.0f,0.0f,-500.0F);
glUniform3f(glGetUniformLocation(PlanetShader.Program, "viewPos"), camera.GetCameraPosition().x, camera.GetCameraPosition().y, camera.GetCameraPosition().z);
glUniform1f(glGetUniformLocation(PlanetShader.Program, "material.shininess"),32.0f);
glUniform3f(glGetUniformLocation(PlanetShader.Program, "material.specular"), 0.5f, 0.5f, 0.5f);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glUniform1f(glGetUniformLocation(PlanetShader.Program, "R"), 10);
GLint lightAmbientLoc = glGetUniformLocation(PlanetShader.Program, "light.ambient");
GLint lightDiffuseLoc = glGetUniformLocation(PlanetShader.Program, "light.diffuse");
GLint lightSpecularLoc = glGetUniformLocation(PlanetShader.Program, "light.specular");
glUniform3f(lightAmbientLoc, 0.3f,0.3f,0.3f);
glUniform3f(lightDiffuseLoc, 1.0f, 1.0f, 1.0f);
glUniform3f(lightSpecularLoc, 0.0f, 0.0f, 0.0f);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 4560);
//绘制地球
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -500.0f));
model = glm::rotate(model, earth_sun/180*PI, glm::vec3(0, 1, 0));
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 250.0f));
model = glm::rotate(model, earth/180*PI, glm::vec3(0.0f, 1.0f, 0.0f));
glUniform1f(glGetUniformLocation(PlanetShader.Program, "R"), 10);
glUniformMatrix4fv(glGetUniformLocation(PlanetShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glBindTexture(GL_TEXTURE_2D, texture[2]);
glDrawArrays(GL_TRIANGLES, 0, 4560);
//绘制月球
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -500.0f));
model = glm::rotate(model, earth_sun/180*PI, glm::vec3(0, 1, 0));
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 250.0f));
model = glm::rotate(model, moon_earth/180*PI, glm::vec3(0.0f, 1.0f, 0.0f));
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 20.0f));
model = glm::rotate(model, moon/180*PI, glm::vec3(0.0f, 1.0f, 0.0f));
glUniform1f(glGetUniformLocation(PlanetShader.Program, "R"), 3);
glUniformMatrix4fv(glGetUniformLocation(PlanetShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glBindTexture(GL_TEXTURE_2D, texture[3]);
glDrawArrays(GL_TRIANGLES, 0, 4560);
glBindVertexArray(0);
Sleep(30);
glfwSwapBuffers(window);
Sun += 0.2;
if (Sun > 360)
Sun -=360 ;
venus += 1.3;
if (venus > 360)
venus -= 360;
venus_sun += 1.3;
if (venus_sun > 360)
venus_sun -= 360;
earth += 3.0;
if (earth > 360)
earth -= 360;
earth_sun += 2.0;
if (earth_sun > 360)
earth_sun -= 360;
moon += 4.0;
if (moon > 360)
moon -= 360;
moon_earth += 4.0;
if (moon_earth > 360)
moon_earth -= 360;
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
planet.vs 顶点着色器
#version 330 core
layout(location=0)in vec3 position;
layout(location=1)in vec3 normal;
layout(location=2)in vec2 texCoords;
out vec2 TexCoords;
out vec3 FragPos;
out vec3 Normal;
uniform float R;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
vec3 P=vec3(position.x*R,position.y*R,position.z*R);
gl_Position=projection*view*model*vec4(P,1.0f);
FragPos=vec3(model*vec4(position,1.0f));
Normal=mat3(transpose(inverse(model)))*normal;
TexCoords=texCoords;
}
planet.frag//片原着色器
#version 330 core
out vec4 color;
uniform vec3 lightPos;
uniform vec3 viewPos;
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;
struct Material
{
sampler2D diffuse;//漫反射物体颜色
vec3 specular;
float shininess;
};
uniform Material material;
struct Light
{
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform Light light;
void main()
{
//环境光
vec3 ambient=light.ambient*vec3(texture(material.diffuse,TexCoords));
//漫反射光
vec3 norm=normalize(Normal);
vec3 lightDir=normalize(lightPos-FragPos);
float diff=max(dot(norm,lightDir),0.0);
vec3 diffuse=light.diffuse*diff*vec3(texture(material.diffuse,TexCoords));
//镜面高光
vec3 viewDir=normalize(viewPos-FragPos);
vec3 reflectDir=reflect(-lightDir,norm);
float spec=pow(max(dot(viewDir,reflectDir),0.0),material.shininess);
vec3 specular=light.specular*(spec*(vec3(1.0f,1.0f,1.0f)));
vec3 result=ambient+diffuse+specular;
color=vec4(result,1.0f);
}
sun.vs
#version 330 core
layout(location=0)in vec3 position;
layout(location=1)in vec3 normal;
layout(location=2)in vec2 texCoords;
out vec2 TexCoords;
uniform float R;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
vec3 P=vec3(position.x*R,position.y*R,position.z*R);
gl_Position=projection*view*model*vec4(P,1.0f);
TexCoords=texCoords;
}
sun.frag
#version 330 core
out vec4 color;
in vec2 TexCoords;
uniform sampler2D texture_1;
void main()
{
color= texture(texture_1,TexCoords);
}