2015-05-29 2 views
0

Я изо всех сил пытаюсь получить куб для рендеринга в opengl. Когда я передаю MVP, уже рассчитанный на вершинный шейдер, он отлично работает, но когда я проходил в модели, просмотр и проецирование выполняли вычисления в вершинном шейдере, он не показывает куб. Я также получаю ошибку 1282, когда я изменяю формы вершинного шейдера в mat4 вместо vec4.Куб OpenGL не отображается

main.cpp

#include <iostream> 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 
#include <glm/glm.hpp> 
#include <glm/gtc/type_ptr.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtx/transform.hpp> 
#include <fstream> 
#include <stdlib.h> 
#include <vector> 

GLuint getShader(const char* shaderName, GLenum shaderType) { 
    std::cout << "Making shader " << shaderName << std::endl; 

    /* Read file */ 
    std::cout << "Reading shader file" << std::endl; 
    std::ifstream shaderFile; 
    shaderFile.open(shaderName, std::ios_base::in); 

    if (!shaderFile) { 
     std::cout << shaderName << " not found" << std::endl; 
     return 0; 
    } 

    std::string line; 
    std::string shaderData; 
    while (std::getline(shaderFile, line)) { 
     shaderData += line + "\n"; 
    } 

    shaderFile.close(); 

    /* Create shader */ 
    std::cout << "Compiling shader" << std::endl; 
    GLuint shader = glCreateShader(shaderType); 

    if (shader == 0) { 
     std::cout << "Failed to create shader for " << shaderName << std::endl; 
     return 0; 
    } 

    const char *shaderStr = shaderData.c_str(); 

    glShaderSource(shader, 1, &shaderStr, nullptr); 
    glCompileShader(shader); 

    /* Check compile status */ 
    GLint status; 
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 
    if (status != GL_TRUE) { 
     GLint logLength; 
     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 

     GLchar *infoLog = new GLchar[logLength + 1]; 
     glGetShaderInfoLog(shader, logLength, nullptr, infoLog); 

     std::cout << shaderName << " failed to compile: " << infoLog << std::endl; 
     return 0; 
    } 

    GLenum error = glGetError(); 
    if(error != GL_NO_ERROR) { 
     std::cout << "Failed making shader program, error " << error << ": " << glewGetErrorString(error) << std::endl; 
     return 0; 
    } 

    return shader; 
} 

int end(const char* message) { 
    glfwTerminate(); 

    if(message != nullptr) { 
     std::cout << message << std::endl; 
     system("PAUSE"); 
    } 
    return -1; 
} 

struct Shader { 
    const char* file; 
    GLenum type; 

    Shader(const char* file, GLenum type) { 
     this->type = type; 
     this->file = file; 
    } 
}; 

GLuint getShader(Shader& shader) { 
    return getShader(shader.file, shader.type); 
} 

GLuint getShaderProgram(std::initializer_list<Shader> shaders, std::initializer_list<const char*> binds) { 
    /* Create the shader program */ 
    GLuint shaderProgram = glCreateProgram(); 
    GLenum error = glGetError(); 

    if (shaderProgram == 0) { 
     std::cout << "Failed to create shader program" << std::endl; 
     return 0; 
    } 
    else if (glIsProgram(shaderProgram) != GL_TRUE) { 
     std::cout << "Failed to create shader program" << std::endl; 
     return 0; 
    } 
    else if(error != GL_NO_ERROR) { 
     std::cout << "Failed creating shader program, error " << error << ": " << glewGetErrorString(error) << std::endl; 
     return 0; 
    } 

    /* Compile & attach the shaders */ 
    for(Shader shader : shaders) { 
     GLuint glShader = getShader(shader); 

     if (glShader == 0) { 
      std::cout << "Failed to load shader " << shader.file << std::endl; 
      return 0; 
     } 

     std::cout << "Attaching shader " << shader.file << std::endl; 
     glAttachShader(shaderProgram, glShader); 
     glDeleteShader(glShader); 

     error = glGetError(); 
     if(error != GL_NO_ERROR) { 
      std::cout << "Failed attaching shader, error " << error << ": " << glewGetErrorString(error) << std::endl; 
      return 0; 
     } 
    } 

    /* Bind */ 
    for(const char* bind : binds) { 
     std::cout << "Binding data location " << bind << std::endl; 
     glBindFragDataLocation(shaderProgram, 0, bind); 

     error = glGetError(); 
     if(error != GL_NO_ERROR) { 
      std::cout << "Failed binding data location, error " << error << ": " << glewGetErrorString(error) << std::endl; 
      return 0; 
     } 
    } 

    /* Link to opengl */ 
    glLinkProgram(shaderProgram); 
    error = glGetError(); 
    if(error != GL_NO_ERROR) { 
     std::cout << "Failed linking shader program, error " << error << ": " << glewGetErrorString(error) << std::endl; 
     return 0; 
    } 

    return shaderProgram; 
} 

int main() { 
    /* Initial checks */ 
    if (!glfwInit()) { 
     return end("Failed to startup GLFW"); 
    } 

    int major = 3; 
    int minor = 3; 
    int rev = 0; 
    glfwGetVersion(&major, &minor, &rev); 

    /* Create the window */ 
    GLFWwindow *window = glfwCreateWindow(500, 500, "3D world prototyping", nullptr, nullptr); 

    if (!window) { 
     return end("Failed to create window."); 
    } 

    glfwMakeContextCurrent(window); //make the window active 

    /* Startup GLEW */ 
    glewExperimental = GL_TRUE; 
    if (glewInit() != GLEW_OK) { 
     return end("Failed to startup GLEW"); 
    } 

    /* Start OpenGL constants */ 
    glEnable(GL_DEPTH_TEST); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glViewport(0, 0, 800, 600); 

    /* Support for multiple shaders without the need to switch attributes */ 
    GLuint vertexArray; 
    glGenVertexArrays(1, &vertexArray); 
    glBindVertexArray(vertexArray); 

    /* Shape vectors */ 
    GLfloat verticies[] = {//X, Y, Z 
      -0.5f, -0.5f, -0.5f, 
      0.5f, -0.5f, -0.5f, 
      0.5f, 0.5f, -0.5f, 
      0.5f, 0.5f, -0.5f, 
      -0.5f, 0.5f, -0.5f, 
      -0.5f, -0.5f, -0.5f, 

      -0.5f, -0.5f, 0.5f, 
      0.5f, -0.5f, 0.5f, 
      0.5f, 0.5f, 0.5f, 
      0.5f, 0.5f, 0.5f, 
      -0.5f, 0.5f, 0.5f, 
      -0.5f, -0.5f, 0.5f, 

      -0.5f, 0.5f, 0.5f, 
      -0.5f, 0.5f, -0.5f, 
      -0.5f, -0.5f, -0.5f, 
      -0.5f, -0.5f, -0.5f, 
      -0.5f, -0.5f, 0.5f, 
      -0.5f, 0.5f, 0.5f, 

      0.5f, 0.5f, 0.5f, 
      0.5f, 0.5f, -0.5f, 
      0.5f, -0.5f, -0.5f, 
      0.5f, -0.5f, -0.5f, 
      0.5f, -0.5f, 0.5f, 
      0.5f, 0.5f, 0.5f, 

      -0.5f, -0.5f, -0.5f, 
      0.5f, -0.5f, -0.5f, 
      0.5f, -0.5f, 0.5f, 
      0.5f, -0.5f, 0.5f, 
      -0.5f, -0.5f, 0.5f, 
      -0.5f, -0.5f, -0.5f, 

      -0.5f, 0.5f, -0.5f, 
      0.5f, 0.5f, -0.5f, 
      0.5f, 0.5f, 0.5f, 
      0.5f, 0.5f, 0.5f, 
      -0.5f, 0.5f, 0.5f, 
      -0.5f, 0.5f, -0.5f 
    }; 

    GLuint shaderProgram = getShaderProgram({ 
     Shader("vertexShader.glsl", GL_VERTEX_SHADER), 
     Shader("fragmentShader.glsl", GL_FRAGMENT_SHADER) 
    }, { 
     "outcolor" 
    }); 

    if(shaderProgram == 0) { 
     return end(""); 
    } 

     /* Load verticies into memory */ 
    GLuint vertexBuffer; 
    glGenBuffers(1, &vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW); 

    /* Getting uniform ids */ 
    glUseProgram(shaderProgram); 
// GLint mvpId = glGetUniformLocation(shaderProgram, "mvp"); 
    GLint projectionId = glGetUniformLocation(shaderProgram, "projection"); 
    GLint modelId = glGetUniformLocation(shaderProgram, "model"); 
    GLint viewId = glGetUniformLocation(shaderProgram, "view"); 

    GLenum error = glGetError(); 
    if(error != GL_NO_ERROR) { 
     std::cout << "Uniform error " << error << ": " << glewGetErrorString(error) << std::endl; 
     return end(""); 
    } 
// else if(mvpId == -1) { 
//  return end("MVP ID failed to load"); 
// } 

    GLint positionAttribute = glGetAttribLocation(shaderProgram, "position"); 

    if(positionAttribute == -1) { 
     std::cout << "Error: position attribute failed to load" << std::endl; 
     return end(""); 
    } 

    /* Positioning */ 
    //FOV, Screen ratio, display range short, display range long 
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 1.0f, 10.0f); 
    glm::mat4 model = glm::mat4(1.0f); 
    glm::mat4 mvp; 

    glm::vec3 camera = glm::vec3(0.0f, 0.0f, 3.0f); 
    glm::vec3 cameraLookingAt = glm::vec3(0.0f, 0.0f, 0.0f); 
    glm::vec3 cameraPitch = glm::vec3(0.0f, 1.0f, 0.0f); 
    float moveSpeed = 0.1f; 

    /* Rendering and logic */ 
    while (!glfwWindowShouldClose(window)) { 
     /* Shutdown logic */ 
     if (glfwGetKey(window, GLFW_KEY_ESCAPE)) { 
      break; 
     } 

     /* Clear */ 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glClearColor(0.2f, 0.2f, 0.2f, 1.0f); 

     /* Logic */ 
      /* Keypresses */ 
     glfwPollEvents(); 
     if(glfwGetKey(window, GLFW_KEY_W)) { 
      camera.z -= moveSpeed; 
      cameraLookingAt.z -= moveSpeed; 
     } 
     else if(glfwGetKey(window, GLFW_KEY_S)) { 
      camera.z += moveSpeed; 
      cameraLookingAt.z += moveSpeed; 
     } 

     if(glfwGetKey(window, GLFW_KEY_A)) { 
      camera.x -= moveSpeed; 
      cameraLookingAt.x -= moveSpeed; 
     } 
     else if(glfwGetKey(window, GLFW_KEY_D)) { 
      camera.x += moveSpeed; 
      cameraLookingAt.x += moveSpeed; 
     } 

     if(glfwGetKey(window, GLFW_KEY_Z)) { 
      camera.y += moveSpeed; 
      cameraLookingAt.y += moveSpeed; 
     } 
     else if(glfwGetKey(window, GLFW_KEY_X)) { 
      camera.y -= moveSpeed; 
      cameraLookingAt.y -= moveSpeed; 
     } 

     if(glfwGetKey(window, GLFW_KEY_UP)) { 
      cameraLookingAt.y += moveSpeed; 
     } 
     else if(glfwGetKey(window, GLFW_KEY_DOWN)) { 
      cameraLookingAt.y -= moveSpeed; 
     } 

     if(glfwGetKey(window, GLFW_KEY_LEFT)) { 
      cameraLookingAt.x -= moveSpeed; 
      cameraLookingAt.z -= moveSpeed; 
     } 
     else if(glfwGetKey(window, GLFW_KEY_RIGHT)) { 
      cameraLookingAt.x += moveSpeed; 
      cameraLookingAt.z += moveSpeed; 
     } 

      /* Update position */ 
     mvp = projection * glm::lookAt(
       camera, 
       cameraLookingAt, 
       cameraPitch 
     ) * model; 
     glm::mat4 view = glm::lookAt(
       camera, 
       cameraLookingAt, 
       cameraPitch 
     ); 

     /* Draw */ 
     glUseProgram(shaderProgram); 

      /* Update the position */ 
//  glUniformMatrix4fv(mvpId, 1, GL_FALSE, &mvp[0][0]); 
     glUniform4fv(viewId, 1, glm::value_ptr(view)); 
     glUniform4fv(modelId, 1, glm::value_ptr(model)); 
     glUniform4fv(projectionId, 1, glm::value_ptr(projection)); 

      /* Redraw the position using the verticies */ 
     glEnableVertexAttribArray(positionAttribute); 
     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
     glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); //because not just XYZ need to tell opengl the size of the stride 

      /* Draw the triangles */ 
     glDrawArrays(GL_TRIANGLES, 0, 36); 
     glDisableVertexAttribArray(positionAttribute); 
     glfwSwapBuffers(window); 

     /* Realtime error checking */ 
     error = glGetError(); 
     if(error != GL_NO_ERROR) { 
      std::cout << "Error " << error << ": " << glewGetErrorString(error) << std::endl; 
     } 
    } 

    glfwDestroyWindow(window); 
    glDeleteProgram(shaderProgram); 
    glDeleteBuffers(1, &vertexBuffer); 
    glDeleteVertexArrays(1, &vertexArray); 
    return end(nullptr); 
} 

Vertex шейдеров:

#version 330 

uniform mat4 projection; /* view port/perspective */ 
uniform mat4 model; /* object */ 
uniform mat4 view; /* camera */ 
in vec3 position; 

void main() { 
    gl_Position = projection * view * model * vec4(position, 1.0); 
} 

ответ

1

Я исправил его!

Первое, что я должен был сделать, это добавить привязку буфера и атрибут, указывающий на цикл while, я думаю, вы должны сообщать о них каждый раз, когда вы вызываете useProgram.

Второе, что мне нужно было вызвать glUniformMatrix4fv, если бы я хотел передать свои значения в качестве mat4 (для чего они должны были быть вместо vec4).

2

Вы должны указать шаг в вызове glVertexAttribPointer, потому что ваши вершины не упакованы (вы позиция и цветовые данные перемежаются):

glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0); 
+0

Ах, ладно. Я сделал это сейчас, но все еще не куб? – user1763295

+0

Опубликуйте свой код фрагмента шейдера, пожалуйста, – samgak

+0

Также проверьте, что glm :: перспектива принимает параметр fov в правильной форме. Попробуйте добавить #define GLM_FORCE_RADIANS верхнюю часть вашего файла (до # включая заголовки glm) или попробуйте передать параметр fov в виде градусов. Наверное, не проблема, но стоит попробовать – samgak

Смежные вопросы