Куб эргүүлэх : uniform, matrix, vbo, vao, ibo

Өмнөх постууд дандаа 2 хэмжээст огторгуйд дүрс рэндэрлэж байсан бол одоо матрицийн тусламжтайгаар 3-н хэмжээст дүрс рэндэрлэж эргүүлье.


Vertex Shader
#version 330

layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
out vec4 ex_Color;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

void main(void)
{
 gl_Position = (ProjectionMatrix * ViewMatrix * ModelMatrix) * in_Position;
 ex_Color = in_Color;
}

Fragment Shader
#version 330

in vec4 ex_Color;
out vec4 out_Color;

void main(void)
{
 out_Color = ex_Color;
}

Code
#define GLEW_STATIC
#include "GL/glew.h"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/constants.hpp>
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>

using namespace std;

GLuint loadShader(string filePath, GLenum shaderType) {
    GLuint shaderID = 0;
    string shaderString;
    ifstream sourceFile(filePath.c_str());
    if (sourceFile) {
        shaderString.assign(
                (istreambuf_iterator<char>(sourceFile)),
                (istreambuf_iterator<char>()));
        shaderID = glCreateShader(shaderType);
        const GLchar* shaderSource = shaderString.c_str();
        glShaderSource(shaderID, 1, (const GLchar**) &shaderSource, NULL);
        glCompileShader(shaderID);
        GLint shaderCompiled = GL_FALSE;
        glGetShaderiv(shaderID, GL_COMPILE_STATUS, &shaderCompiled);
        if (shaderCompiled != GL_TRUE) {
            cout << "cannot compiled" << endl;
            glDeleteShader(shaderID);
            shaderID = 0;
        }
        sourceFile.close();
    } else {
        cout << "cannot open file" << endl;
    }
    return shaderID;
}

int main(int argc, char** argv) {
    float width = 800;
    float height = 600;

    GLFWwindow* window;
    if (!glfwInit())
        return EXIT_FAILURE;

    window = glfwCreateWindow((int) width, (int) height, "OpenGL Rotate 3D cube", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        cout << "error in glewInit " << glewGetErrorString(err) << endl;
        return EXIT_FAILURE;
    }

    cout << "start cooking" << endl;

    GLuint programID = glCreateProgram();
    cout << "created program : " << programID << endl;
    GLuint vertexShader = loadShader("simple.vert.glsl", GL_VERTEX_SHADER);
    if (vertexShader == 0) {
        glDeleteProgram(programID);
        programID = 0;
        return EXIT_FAILURE;
    }
    glAttachShader(programID, vertexShader);
    GLuint fragmentShader = loadShader("simple.frag.glsl", GL_FRAGMENT_SHADER);
    if (fragmentShader == 0) {
        glDeleteProgram(programID);
        programID = 0;
        return EXIT_FAILURE;
    }
    glAttachShader(programID, fragmentShader);
    glLinkProgram(programID);
    glUseProgram(programID);
    GLint programSuccess = GL_TRUE;
    glGetProgramiv(programID, GL_LINK_STATUS, &programSuccess);
    if (programSuccess != GL_TRUE) {
        cout << "error in linkin program " << programID << endl;
        glDeleteProgram(programID);
        programID = 0;
        return EXIT_FAILURE;
    }


    glm::mat4 projectionMatrix;
    glm::mat4 viewMatrix;
    glm::mat4 modelMatrix;
    GLuint ProjectionMatrixUniformLocation;
    GLuint ViewMatrixUniformLocation;
    GLuint ModelMatrixUniformLocation;
    GLuint BufferIds[3] = {0};
    float cubeRotation = 0.0f;

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);

    modelMatrix = glm::mat4(1.0f); // identity матриц
    projectionMatrix = glm::mat4(1.0f);
    viewMatrix = glm::mat4(1.0f);
    viewMatrix = glm::translate(viewMatrix, glm::vec3(0, 0, -2));

    glViewport(0, 0, (int) width, (int) height);
    projectionMatrix = glm::perspective(60.0f, width / height, 1.0f, 100.0f);

    typedef struct Vertex {
        float Position[4];
        float Color[4];
    } Vertex;

    const Vertex VERTICES[8] = {
        {
            { -.5f, -.5f, .5f, 1},
            { 0, 0, 1, 1}
        },
        {
            { -.5f, .5f, .5f, 1},
            { 1, 0, 0, 1}
        },
        {
            { .5f, .5f, .5f, 1},
            { 0, 1, 0, 1}
        },
        {
            { .5f, -.5f, .5f, 1},
            { 1, 1, 0, 1}
        },
        {
            { -.5f, -.5f, -.5f, 1},
            { 1, 1, 1, 1}
        },
        {
            { -.5f, .5f, -.5f, 1},
            { 1, 0, 0, 1}
        },
        {
            { .5f, .5f, -.5f, 1},
            { 1, 0, 1, 1}
        },
        {
            { .5f, -.5f, -.5f, 1},
            { 0, 0, 1, 1}
        }
    };

    const GLuint INDICES[36] = {
        0, 2, 1, 0, 3, 2,
        4, 3, 0, 4, 7, 3,
        4, 1, 5, 4, 0, 1,
        3, 6, 2, 3, 7, 6,
        1, 6, 5, 1, 2, 6,
        7, 5, 6, 7, 4, 5
    };

    ModelMatrixUniformLocation = glGetUniformLocation(programID, "ModelMatrix");
    ViewMatrixUniformLocation = glGetUniformLocation(programID, "ViewMatrix");
    ProjectionMatrixUniformLocation = glGetUniformLocation(programID, "ProjectionMatrix");

    glGenVertexArrays(1, &BufferIds[0]);
    glBindVertexArray(BufferIds[0]);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glGenBuffers(2, &BufferIds[1]);
    glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof (VERTICES), VERTICES, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof (VERTICES[0]), (GLvoid*) 0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof (VERTICES[0]), (GLvoid*)sizeof (VERTICES[0].Position));
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof (INDICES), INDICES, GL_STATIC_DRAW);
    glBindVertexArray(0);

    glUseProgram(programID);
    glUniformMatrix4fv(ProjectionMatrixUniformLocation, 1, GL_FALSE, &projectionMatrix[0][0]);
    glUseProgram(0);

    float deltaTime = 0.0f;
    float startTime = glfwGetTime();
    float buffTime = 0.0;
    int counter = 0;
    while (!glfwWindowShouldClose(window)) {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        float CubeAngle;
        cubeRotation += 4005.0f * (deltaTime);
        CubeAngle = cubeRotation * (float) (glm::pi<float>() / 180); // degree to radian

        modelMatrix = glm::mat4(1);
        modelMatrix = glm::rotate(modelMatrix, CubeAngle, glm::vec3(0, 1, 0));
        modelMatrix = glm::rotate(modelMatrix, CubeAngle, glm::vec3(1, 0, 0));

        glUseProgram(programID);

        glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, &modelMatrix[0][0]);
        glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, &viewMatrix[0][0]);
        glBindVertexArray(BufferIds[0]);

        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*) 0);

        glBindVertexArray(0);
        glUseProgram(0);

        glfwSwapBuffers(window);
        glfwPollEvents();

        double lastTime = glfwGetTime();
        deltaTime = lastTime - startTime;
        startTime = lastTime;
        counter++;
        buffTime += deltaTime;
        if (buffTime > 1.0f) {
            buffTime = 0.0f;
            cout << "fps " << counter << endl;
            counter = 0;
        }
    }


    glDeleteBuffers(2, &BufferIds[1]);
    glDeleteVertexArrays(1, &BufferIds[0]);

    // shader ээ устгах
    glUseProgram(0);
    glDetachShader(programID, vertexShader);
    glDetachShader(programID, fragmentShader);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glDeleteProgram(programID);

    glfwTerminate();
    return 0;
}


скрээншот


Popular posts from this blog

Apache Spark + Cassandra. Hello World