2017-01-15 4 views
0

Ich beginne mit OpenGL und folge den Anleitungen und versuche ein strukturiertes Dreieck zu erstellen. Die Shader in diesem Code sind fest codiert, sodass sie zu einer minimalen ausführbaren Datei werden. Es kompiliert reibungslos, aber die Ausgabe ist nur ein farbiges Fenster ohne ein Dreieck. Was mache ich falsch? Hier ist der Code:Textur zum 2D Element hinzufügen

#include <iostream> 

// GLEW 
#define GLEW_STATIC 
#include <GL/glew.h> 

// GLFW 
#include <GLFW/glfw3.h> 
#include <soil.h> 

// Function prototypes 
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); 

// Window dimensions 
const GLuint WIDTH = 800, HEIGHT = 600; 

// Texture co-ordinates 
GLfloat texCoords[] = { 
    0.0f, 0.0f, // Lower-left corner 
    1.0f, 0.0f, // Lower-right corner 
    0.5f, 1.0f // Top-center corner 
}; 

// Shaders 
const GLchar* vertexShaderSource = "#version 330 core\n layout (location = 0) in vec3 position;\r\nlayout (location = 1) in vec3 color;\r\nlayout (location = 2) in vec2 texCoord;\r\n\r\nout vec3 ourColor;\r\nout vec2 TexCoord;\r\n\r\nvoid main()\r\n{\r\n gl_Position = vec4(position, 1.0f);\r\n ourColor = color;\r\n TexCoord = texCoord;\r\n}"; 
const GLchar* fragmentShaderSource = "#version 330 core\r\nin vec3 ourColor;\r\nin vec2 TexCoord;\r\n\r\nout vec4 color;\r\n\r\nuniform sampler2D ourTexture;\r\n\r\nvoid main()\r\n{\r\n color = texture(ourTexture, TexCoord);\r\n}"; 

// The MAIN function, from here we start the application and run the game loop 
int main() 
{ 
    // Init GLFW 
    glfwInit(); 
    // Set all the required options for GLFW 
    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); 

    // Create a GLFWwindow object that we can use for GLFW's functions 
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); 
    glfwMakeContextCurrent(window); 

    // Set the required callback functions 
    glfwSetKeyCallback(window, key_callback); 

    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions 
    glewExperimental = GL_TRUE; 
    // Initialize GLEW to setup the OpenGL Function pointers 
    glewInit(); 

    // Define the viewport dimensions 
    int width, height; 
    glfwGetFramebufferSize(window, &width, &height); 
    glViewport(0, 0, width, height); 


    // Build and compile our shader program 
    // Vertex shader 
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); 
    glCompileShader(vertexShader); 
    // Check for compile time errors 
    GLint success; 
    GLchar infoLog[512]; 
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); 
    if (!success) 
    { 
     glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); 
     std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 
    } 
    // Fragment shader 
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); 
    glCompileShader(fragmentShader); 
    // Check for compile time errors 
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); 
    if (!success) 
    { 
     glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); 
     std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; 
    } 
    // Link shaders 
    GLuint shaderProgram = glCreateProgram(); 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 
    glLinkProgram(shaderProgram); 
    // Check for linking errors 
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); 
    if (!success) { 
     glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); 
     std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; 
    } 
    glDeleteShader(vertexShader); 
    glDeleteShader(fragmentShader); 


    // Set up vertex data (and buffer(s)) and attribute pointers 
    GLfloat vertices[] = { 
     -0.5f, -0.5f, 0.0f, // Left 
     0.5f, -0.5f, 0.0f, // Right 
     0.0f, 0.5f, 0.0f // Top 
    }; 
    GLuint VBO, VAO; 
    glGenVertexArrays(1, &VAO); 
    glGenBuffers(1, &VBO); 

    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). 
    glBindVertexArray(VAO); 

    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

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

    glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind 

    glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs) 

    // Attach image to texture 
    int t_width, t_height; 
    unsigned char* image = SOIL_load_image("texm.jpg", &t_width, &t_height, 0, SOIL_LOAD_RGB); 
    GLuint texture; 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, t_width, t_height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); 
    glGenerateMipmap(GL_TEXTURE_2D); 
    SOIL_free_image_data(image); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(2); 


    // Game loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 
     glfwPollEvents(); 

     // Render 
     // Clear the colorbuffer 
     glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT); 

     // Draw our first triangle 
     glUseProgram(shaderProgram); 
     glBindTexture(GL_TEXTURE_2D, texture); 
     glBindVertexArray(VAO); 
     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
     glBindVertexArray(0); 

     // Swap the screen buffers 
     glfwSwapBuffers(window); 
    } 
    // Properly de-allocate all resources once they've outlived their purpose 
    glDeleteVertexArrays(1, &VAO); 
    glDeleteBuffers(1, &VBO); 
    // Terminate GLFW, clearing any resources allocated by GLFW. 
    glfwTerminate(); 
    return 0; 
} 

// Is called whenever a key is pressed/released via GLFW 
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); 
} 

Dank und Gruß.

Antwort

1

Sie versuchen, mit glDrawElements zu zeichnen, aber in Ihrem Fall gibt es einige Probleme damit. Erstens ist das kein großer Fehler, aber da Sie ein Dreieck mit 3 Ecken haben, sollte der zweite Parameter für glDrawElements 3 sein. Er erwartet aber auch, dass ein Indexpuffer gebunden wird. Implementieren Sie also entweder Indizierung oder zeichnen Sie mit glDrawArrays.

Wenn Sie die Indizierung verwenden später (Sie werden), und Sie sind nicht vertraut mit: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/

Verwandte Themen