2017-05-22 7 views
0

Dieses Programm sollte ein einzelnes Dreieck darstellen, aber nur ein schwarzer Bildschirm wird angezeigt.Basic openGL | Schwarzer Bildschirm

Ich habe diesen Code aktualisiert, um die in den Antworten/Kommentaren vorgeschlagenen Änderungen widerzuspiegeln.

[Ubuntu 16.04, GLFW, GLEW]

#define GLEW_STATIC 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 

#include <stdio.h> 

int main(int argc, char* argv[]) 
{ 

    glfwInit(); 
    // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
    // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    // glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    GLFWwindow *window = glfwCreateWindow(800, 600, "OpenGL Practice", NULL,  NULL); 
    glfwMakeContextCurrent(window); 

    glewExperimental = GL_TRUE; 
    glewInit(); 

    GLfloat verts[] = { 
     +0.0f, +1.0f, 
     -1.0f, -1.0f, 
     +1.0f, -1.0f 
    }; 

    GLuint vao; 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    GLuint vbo; 
    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    // glVertexPointer(2, GL_FLOAT, 0, 0); 

    // Main loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     glfwPollEvents(); 

     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 
     { 
      glfwSetWindowShouldClose(window, GL_TRUE); 
     } 

     glClearColor(1.0f, 1.0f, 0.0f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT); 

     glDrawArrays(GL_TRIANGLES, 0, 3); 

     glfwSwapBuffers(window); 


    } 

    glfwTerminate(); 

    return 0; 
} 

[Update: Es scheint, dass das Tutorial wurde dieser Code basiert auf wurde eine viel ältere Version von OpenGL, wo Shadern nicht erforderlich waren. Dies war für einen Anfänger teuflisch schwierig zu finden, da das Setup genau gleich war und keine Kompilierungs- oder Laufzeitfehler vorlagen. Ich habe die Antwort markiert, die dieser Erklärung am nächsten kommt.]

+1

Off Topic aber ist Ihre Breite und Höhe Werte umgekehrt? Sollte es nicht 600 Pixel in der Höhe und 800 Pixel in der Breite sein? –

+0

@FrancisCulger Nein, ich denke nicht. Es hängt davon ab, wie der Bildschirm aussehen soll. In diesem Fall ist die Breite des resultierenden Bildschirms jedoch größer als die Höhe. – assemblyDruid

+0

Die Verwendung von 'glVertexAttribPointer()' ohne Shader ist * technisch * gültig (nur für Attribut 0), aber ziemlich skizzenhaft. Fügen Sie einige Shader hinzu oder wechseln Sie zurück zum klassischen 'glVertexPointer()'. – genpfault

Antwort

0

Auch wenn Sie eine VBO und VAO erstellt und hat sie gefüllt Sie sind mit ihnen nicht richtig.

Zuerst müssen Sie VAO binden und anschließend VBO binden, dann Daten in den Puffer kopieren und die Funktion glVertexAttribPointer() verwenden und anschließend beide Puffer aufheben.

Dann vor dem Rendern binden Sie den VAO erneut und lösen Sie es nach dem Zeichnen.

Sie müssen auch SHADERS

Ich sehe keinen Shader in Ihrem Code.

Hier ist ein Arbeitscode:

#include <iostream> 

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

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


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

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

// Shaders 
const GLchar* vertexShaderSource = "#version 330 core\n" 
"layout (location = 0) in vec3 position;\n" 
"void main()\n" 
"{\n" 
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n" 
"}\0"; 
const GLchar* fragmentShaderSource = "#version 330 core\n" 
"out vec4 color;\n" 
"void main()\n" 
"{\n" 
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" 
"}\n\0"; 

// 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) 

// 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); 
    glBindVertexArray(VAO); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    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); 
} 

Quelle: https://learnopengl.com/code_viewer.php?code=getting-started/hellotriangle

Ich empfehle Ihnen OpenGL von Anfang zu lernen. https://learnopengl.com/ ist ein großartiger Ort, um OpenGL zu lernen.

+0

Danke für Ihre Antwort. Ich sehe keinen Unterschied darin, wie ich den VBO und VAO erstellt und gebunden habe, noch wie ich den VBO gefüllt habe. Würde es Ihnen etwas ausmachen, darauf hinzuweisen, wie Sie das anders gemacht haben? Außerdem habe ich Shader in anderen Tutorials mit Erfolg verwendet. Was mich umbringt, ist, dass das aktuelle Tutorial, das ich verwende, keine Shader verwendet (noch nicht, in diesem Stadium des Tutorials) und ihr Code funktioniert. Der einzige Unterschied ist, dass sie Qt für die Fensterverwaltung verwenden und ich GLFW verwende. Ich werde deinen Code ohne den Shader-Teil testen müssen, um zu sehen, ob es funktioniert. – assemblyDruid

+0

Es gibt keine Möglichkeit, ein MODERN opengl-Programm RENDER (wie Dreiecke) ohne Shader zu rendern, aber ältere opengl-Versionen (unter 3.0) können ohne Shader mit glBegin(), glVertex3f(), glEnd() usw. rendern ein altes OpenGL-Tutorial oder ein modernes OpenGL-Tutorial, das zu diesem Zeitpunkt gar nichts zeichnen möchte. Siehe learnopengl.com. Es hat alles erklärt, was Sie über VBOs und VAOs wissen und verwenden müssen. Wenn Sie das nicht verstehen, hinterlassen Sie bitte einen Kommentar und ich werde es erklären. :) – IAS0601

+0

Können Sie mir den Link zu dem Tutorial geben, das Sie verwenden? – IAS0601

2

You have Zeichnen -> Löschen -> Tauschen.

Klar vor ziehen Sie nicht nach:

while (!glfwWindowShouldClose(window)) 
{ 
    glfwPollEvents(); 
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 
    { 
     glfwSetWindowShouldClose(window, GL_TRUE); 
    } 

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glViewport(0, 0, width, height); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 

    glfwSwapBuffers(window); 
} 
+0

Danke!Leider hat das auch nicht funktioniert, obwohl ich mir sicher bin, dass es eines der darin enthaltenen Probleme war. Ich habe auch die Funktion glViewPort() entfernt. Ich bin ratlos! – assemblyDruid

+0

@cfarvin Überprüfen Sie die Wicklungsreihenfolge Ihrer Scheitelpunkte. CW vs. CCW und abhängig davon, ob BackfaceCulling ein- oder ausgeschaltet ist. –

+0

@FrancisCugler hmmmm ... Ich muss herausfinden, was du meinst. Ich habe noch nie von BacfaceCulling oder CW vs CCW gehört. Vielleicht hast du die Frage nicht gesehen, bevor sie von Mods bearbeitet wurde - ich bin ein totaler Anfänger und folge einem Tutorial. Ich werde nach einer Überprüfung zu diesen Themen^zurückkommen (und danke). – assemblyDruid

Verwandte Themen