计算机图形学————绘制动态的行星系

绘制动态的行星系

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::vectortemp_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);
}

计算机图形学————绘制动态的行星系_第1张图片
代码以及exe文件下载

你可能感兴趣的:(OpenGL,图形,计算机,opengl,纹理贴图,着色器编程)