带有OPENGL的3D金字塔

时间:2018-08-10 01:47:48

标签: c++ opengl

我正在尝试在OpenGL中编码3d金字塔,我无法弄清楚为什么我的三角形在金字塔的侧面不重叠,以及为了达到实际金字塔形状需要做的事情。

我尝试更新步幅,旋转,但我茫然。我还尝试过将形状加倍的概念,但这也不起作用。

我将感谢任何人对于如何完成此代码以获得3D金字塔的见识

我的代码:

    #include <GLEW/glew.h>
    #include <GLFW/glfw3.h>
    #include <iostream>

   //GLM library
   #include <glm/glm.hpp>
   #include<glm/gtc/matrix_transform.hpp>
   #include<glm/gtc/type_ptr.hpp>

   using namespace std;

   int width, height; const double PI = 3.14159; const float toRadians =
   PI / 180.0f;

   // Draw Primitive(s) void draw() {   GLenum mode = GL_TRIANGLES;
    GLsizei indices = 6;    glDrawElements(mode, indices,
   GL_UNSIGNED_BYTE, nullptr);


   }

   // Create and Compile Shaders static GLuint CompileShader(const
   string& source, GLuint shaderType) {     // Create Shader object     GLuint
   shaderID = glCreateShader(shaderType);   const char* src =
   source.c_str();

    // Attach source code to Shader object  glShaderSource(shaderID, 1,
   &src, nullptr);

    // Compile Shader   glCompileShader(shaderID);

    // Return ID of Compiled shader     return shaderID;

   }

   // Create Program Object static GLuint CreateShaderProgram(const
   string& vertexShader, const string& fragmentShader) {    // Compile
   vertex shader    GLuint vertexShaderComp = CompileShader(vertexShader,
   GL_VERTEX_SHADER);

    // Compile fragment shader  GLuint fragmentShaderComp =
   CompileShader(fragmentShader, GL_FRAGMENT_SHADER);

    // Create program object    GLuint shaderProgram = glCreateProgram();

    // Attach vertex and fragment shaders to program object
    glAttachShader(shaderProgram, vertexShaderComp);
    glAttachShader(shaderProgram, fragmentShaderComp);

    // Link shaders to create executable    glLinkProgram(shaderProgram);

    // Delete compiled vertex and fragment shaders
    glDeleteShader(vertexShaderComp);
    glDeleteShader(fragmentShaderComp);

    // Return Shader Program    return shaderProgram;

   }


   int main(void) {     width = 640; height = 480;

    GLFWwindow* window;

    /* Initialize the library */    if (!glfwInit())        return -1;

    /* Create a windowed mode window and its OpenGL context */  window =
   glfwCreateWindow(width, height, "Main Window", NULL, NULL);  if
   (!window)    {       glfwTerminate();        return -1;  }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    // Initialize GLEW  if (glewInit() != GLEW_OK)      cout << "Error!" <<
   endl;

    GLfloat vertices[] = {

        // Triangle 1
        0.0,1.0,0.0,
        1.0,0.0,0.0,

        -1.0,-1.0,1.0,
        0.0,1.0,0.0,

        1.0,-1.0,1.0,
        0.0,0.0,1.0,

        //Triangle 2
        0.0,1.0,0.0,
        1.0,0.0,0.0,

        1.0,-1.0,1.0,
        0.0,0.0,1.0,

        1.0,-1.0,-1.0,
        0.0,1.0,0.0,

        //Triangle 3
        0.0,1.0,0.0,
        1.0,0.0,0.0,

        1.0,-1.0,-1.0,
        0.0,1.0,0.0,

        -1.0,-1.0,-1.0,
        0.0,0.0,1.0,

        //Triangle 4
        0.0,1.0,0.0,
        1.0,0.0,0.0,

        -1.0,-1.0,-1.0,
        0.0,0.0,1.0,

        -1.0,-1.0,1.0,
        0.0,1.0,0.0

    };

    // Define element indices   GLubyte indices[] = {       0, 1, 2,        1, 2,
   3    };

    //plane positions   glm::vec3 planePositions[] =    {
        glm::vec3(0.0f,0.0f,0.5f),      glm::vec3(0.5f,0.0f,0.0f),
        glm::vec3(0.0f,0.0f,-0.5f),         glm::vec3(-0.5f,0.0f,0.0f)  };

    //Plane rotations   glm::float32 planeRotationsY[] = {
        0.0f,80.0f, 10.0f, 90.f     };

    glm::float32 planeRotationsX[] = {
        20.0f,-15.0f, 90.0f, 45.f   };

    //Enable Depth buffer
    glEnable(GL_DEPTH_TEST);

    //Wireframe mode
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);


    GLuint VBO, EBO, VAO;

    glGenBuffers(1, &VBO); // Create VBO
    glGenBuffers(1, &EBO); // Create EBO

    glGenVertexArrays(1, &VAO); // Create VOA
    glBindVertexArray(VAO);

    // VBO and EBO Placed in User-Defined VAO
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // Select VBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Select EBO


    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // Load indices 

                        // Specify attribute location and layout to GPU
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindVertexArray(0); // Unbind VOA or close off (Must call VOA explicitly in loop)

                          // Vertex shader source code
    string vertexShaderSource =
        "#version 330 core\n"
        "layout(location = 0) in vec4 vPosition;"
        "layout(location = 1) in vec4 aColor;"
        "out vec4 oColor;"
        "uniform mat4 model;"
        "uniform mat4 view;"
        "uniform mat4 projection;"
        "void main()\n"
        "{\n"
        "gl_Position =  projection * view * model * vPosition;"
        "oColor = aColor;"
        "}\n";

    // Fragment shader source code
    string fragmentShaderSource =
        "#version 330 core\n"
        "in vec4 oColor;"
        "out vec4 fragColor;"
        "void main()\n"
        "{\n"
        "fragColor = oColor;"
        "}\n";

    // Creating Shader Program
    GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);

    // Use Shader Program exe once
    //glUseProgram(shaderProgram);


    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {

        // Resize window and graphics simultaneously
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);

        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Use Shader Program exe and select VAO before drawing 
        glUseProgram(shaderProgram); // Call Shader per-frame when     updating attributes

                                     //Declare identity matrix
        glm::mat4 viewMatrix;
        glm::mat4 projectionMatrix;

        //Initialize transforms
        //modelMatrix = glm::scale(modelMatrix, glm::vec3(0.5f, 0.5f, 0.5f));

        viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, -3.0f));
        viewMatrix = glm::rotate(viewMatrix, 45.0f * toRadians, glm::vec3(1.0f, 0.0f, 0.0f));


        projectionMatrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);

        //Select uniform shader and variable
        GLuint modelLoc = glGetUniformLocation(shaderProgram, "model");
        GLuint viewLoc = glGetUniformLocation(shaderProgram, "view");
        GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection");

        //Pass transform to shader

        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(viewMatrix));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projectionMatrix));


        glBindVertexArray(VAO); // User-defined VAO must be called before draw. 

        for (GLuint i = 0; i< 4; i++)
        {
            glm::mat4 modelMatrix;

            modelMatrix = glm::translate(modelMatrix, planePositions[i]);

            modelMatrix = glm::rotate(modelMatrix, planeRotationsY[i] * toRadians, glm::vec3(0.0f, 1.0f, 0.0f));
            modelMatrix = glm::rotate(modelMatrix, planeRotationsX[i] * toRadians, glm::vec3(1.0f, 0.0f, 0.0f));

            glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));


            // Draw primitive(s)
            draw();

        }



        // Unbind Shader exe and VOA after drawing per frame
        glBindVertexArray(0); //Incase different VAO wii be used after
        glUseProgram(0); // Incase different shader will be used after

                         /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    //Clear GPU resources
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);


    glfwTerminate();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

似乎存在一些代码格式化问题,但是我看到了:

// Define element indices
GLubyte indices[] = { 0, 1, 2, 1, 2, 3 };

在我看来,这是不正确的,顶点数据的注释方式看起来应该是这样的:

GLubyte indices[] = {
    // First triangle
    0, 1, 2,
    // Second triangle
    3, 4, 5,
    // Third triangle
    6, 7, 8,
    // Fourth triangle
    9, 10, 11,
};

然后您可以:

glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);

但是索引数组是不必要的。您可以将其完全删除,只需使用:

glDrawArrays(GL_TRIANGLES, 0, 12);