Bildschirm bleibt schwarz.
-
Hoi!
Ich hab mit diesem Tutorial angefangen, OpenGL zu lernen. Meinen OpenGL-Context erstelle ich jedoch nicht mit FreeGlut, sondern mit GLFW. Aus irgend einem Grund bleibt mein Fenster aber einfach schwarz.
#include <iostream> #include "gl.hpp" #include "shader.hpp" #include "shader_list.hpp" #include "shader_program.hpp" #include "types.hpp" int main() { glfwInit(); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, 1); glfwOpenWindow(1920, 1080, 0, 0, 0, 0, 0, 0, GLFW_WINDOW); glfwSetWindowTitle("OpenGL"); glewInit(); shader_list l; l += shader("test.vs", shader_type::vertex); l += shader("test.fs", shader_type::fragment); shader_program sp(l); sp.use(); glClearColor(0.f, 0.f, 0.f, 1.f); glfloat const vertices[] { 0.5f, 0.5f, 0.f, 1.f, 0.5f, -0.5f, 0.f, 1.f, -0.5f, -0.5f, 0.f, 1.f, }; gluint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW); do { glClear(GL_COLOR_BUFFER_BIT); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(); } while(!glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED)); glfwCloseWindow(); }
Meine Shader:
#version 330 layout(location = 0) in vec4 position; void main() { gl_Position = position; }
#version 330 out vec4 outputColor; void main() { outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); }
Hat irgendjemand eine Idee?
Gruesse,
Der Kellerautomat
-
Niemand?
-
So einfach ist es nicht den Fehler zu finden.Er könnte in den Shadersn oder in der Zeichenmethode liegen.
Daher die Idee: Entferne mal die Shader und zeichne mit der Standardpipeline, ist dann was zu sehen?
Kann deine Grafikkarte überhaupt die gewählte Shaderversion?
Wo verbirgt sich z.B. das "glCompileShader"?Ich kenne den Ablauf der Shadererzeugung und Verwendung (angegeben als Pseudocode) so:
glCreateShader(myVertexsShaderID); glShaderSource(myVertexShaderQuellcodeText,myVertexShaderID); glCompileShader(myVertexShaderID)
glCreateShader(myFragmentShaderID); glShaderSource(myFragmentShaderQuellcodeText,myFragmentShaderID); glCompileShader(myFragmentShaderID)
glCreateProgram(myProgramID) glAttachShader(myVertexShaderID); glAttachShader(myFragmentShaderID); glLinkProgramm(myProgramID); glUseProgram(myProgramID);
Hast du sowas wie eine Fehlerausgabe für die Shader?
void shaderInfo(GLuint ob) { int l = 0; int c = 0; char *info; glGetShaderiv(ob, GL_INFO_LOG_LENGTH, &l); if (l> 0) { info = (char*) malloc(l); glGetShaderInfoLog(ob, l, &c, info); print("%s\n", info); free(info); } }
Oder Fehlerausgabe für das Programm
void shaderInfo(GLuint ob) { int l = 0; int c = 0; char *info; glGetShaderiv(ob, GL_INFO_LOG_LENGTH, &l); if (l> 0) { info = (char*) malloc(l); glGetProgramInfoLog(ob, l, &c, info); print("%s\n", info); free(info); } }
Als "ob" der Methode die myVertexsShaderID bzw myFragmentShaderID und bei der Fehlerausgabe des Programs die myProgramID angeben.
Die beiden Methoden habe ich aufgeschrieben ohne Tests. Es könnten also Fehler drin sein.
-
Die Shader funktionieren tadellos. Die Klassen dafuer habe ich mir selbst geschrieben und diese schmeissen Exceptions im Fehlerfall.
-
Dein Dreieck wird geculled.
-
Was heisst das und was kann ich dagegen tun?
Abgesehen davon hab ich jetzt mal den kompletten Rendercode entfernt und auf Errors gesprueft. Direkt nach glewInit() bekomme ich GL_INVALID_ENUM. So sieht der Code aus:
#include <iostream> #include "gl.hpp" void check_errors() { GLenum const err = glGetError(); switch(err) { case GL_NO_ERROR: std::cerr << "GL_NO_ERROR\n"; break; case GL_INVALID_ENUM: std::cerr << "GL_INVALID_ENUM\n"; break; case GL_INVALID_VALUE: std::cerr << "GL_INVALID_VALUE\n"; break; case GL_INVALID_OPERATION: std::cerr << "GL_INVALID_OPERATION\n"; break; case GL_STACK_OVERFLOW: std::cerr << "GL_STACK_OVERFLOW\n"; break; case GL_STACK_UNDERFLOW: std::cerr << "GL_STACK_UNDERFLOW\n"; break; case GL_OUT_OF_MEMORY: std::cerr << "GL_OUT_OF_MEMORY\n"; break; case GL_TABLE_TOO_LARGE: std::cerr << "GL_TABLE_TOO_LARGE\n"; break; default: std::cerr << "unknown error\n"; break; } } int main() { glfwInit(); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, 1); glfwOpenWindow(1920, 1080, 0, 0, 0, 0, 0, 0, GLFW_WINDOW); glfwSetWindowTitle("OpenGL"); if(glewInit() != GLEW_OK) std::cerr << "error intializing glew\n"; check_errors(); glfwCloseWindow(); }
-
http://en.wikipedia.org/wiki/Back-face_culling
GLEW ist nicht kompatibel mit einem OpenGL Core Profile, hab oben nicht registriert, dass du ja GLEW benutzt. Verwend gl3w.
-
OK, darauf waere ich nie gekommen. Jetzt erzeugt die Zeile
glEnableVertexAttribArray(0);
in meiner Main-Loop einen GL_INVALID_OPERATION-Error. Laut Doc ist das nur der Fall, wenn ich die Funktion swischen glBegin und glEnd aufrufe. Aber diese Funktionen verwende ich doch gar nicht?!
-
Wie sieht der Code jetzt aus?
-
#include <iostream> #include "gl.hpp" #include "shader.hpp" #include "shader_list.hpp" #include "shader_program.hpp" #include "types.hpp" void check_errors() { GLenum const err = glGetError(); switch(err) { case GL_NO_ERROR: std::cerr << "GL_NO_ERROR\n"; break; case GL_INVALID_ENUM: std::cerr << "GL_INVALID_ENUM\n"; break; case GL_INVALID_VALUE: std::cerr << "GL_INVALID_VALUE\n"; break; case GL_INVALID_OPERATION: std::cerr << "GL_INVALID_OPERATION\n"; break; case GL_STACK_OVERFLOW: std::cerr << "GL_STACK_OVERFLOW\n"; break; case GL_STACK_UNDERFLOW: std::cerr << "GL_STACK_UNDERFLOW\n"; break; case GL_OUT_OF_MEMORY: std::cerr << "GL_OUT_OF_MEMORY\n"; break; default: std::cerr << "unknown error\n"; break; } } int main() { glfwInit(); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, 1); glfwOpenWindow(1920, 1080, 0, 0, 0, 0, 0, 0, GLFW_WINDOW); glfwSetWindowTitle("OpenGL"); if(gl3wInit() == -1) std::cerr << "error intializing gl3w\n"; shader_list l; l += shader("test.vs", shader_type::vertex); l += shader("test.fs", shader_type::fragment); shader_program sp(l); sp.use(); glDisable(GL_CULL_FACE); glClearColor(0.f, 0.f, 0.f, 1.f); glfloat const vertices[] { 0.5f, 0.5f, 0.f, 1.f, 0.5f, -0.5f, 0.f, 1.f, -0.5f, -0.5f, 0.f, 1.f, }; gluint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW); do { glClear(GL_COLOR_BUFFER_BIT); glEnableVertexAttribArray(0); check_errors(); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(); } while(!glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED)); glfwCloseWindow(); }
-
Hab die Loesung von jemandem aus dem IRC.
gluint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao);
Hab das vor erstellen des Buffers reingeschrieben. Keine Ahnung was das macht, aber es funktioniert nun. Will mir das jemand erklaeren?
-
In OpenGL 3.3+ Core brauchst du ein VAO um etwas zu zeichnen.
-
Das VAO definiert erst, was die eingaben für deine Shader sind. Du kannst eine Menge Buffer vor dem Rendern setzen, aber was welcher Buffer genau darstellt, wird im VAO gespeichert.
-
Kellerautomat schrieb:
Hab die Loesung von jemandem aus dem IRC.
gluint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao);
Hab das vor erstellen des Buffers reingeschrieben. Keine Ahnung was das macht, aber es funktioniert nun. Will mir das jemand erklaeren?
Wird in "Chapter 5. Objects in Depth" in dem Tutorial, das du benutzt, erklärt.
-
Ah, okay. So weit bin ich noch nicht.
Was haltet ihr eigentlich von dem Tutorial?
-
Mir gefällt es sehr gut. Ich bin momentan selbst dabei, damit zu lernen.