[GELOEST]OpenGL: Seltsamer Fragment Shader-Kompilierfehler
-
#include <glad/glad.h> #define GLFW_DLL #include <GLFW\glfw3.h> #include <cstdio> #include <cstdlib> #include <ctime> #include <cstdarg> #include <string> #include <iostream> // TODO: split source code for better readability class FileManager { public: FileManager(const char* fileName) { this->fileName = fileName; } ~FileManager() { fclose(this->fileHandle); } protected: const char* fileName; FILE* fileHandle; void rewriteToFile(const char* inputData) { this->accessFile("w+"); fprintf(this->fileHandle, inputData); fclose(this->fileHandle); return; } void writeToFile(const char* inputData) { this->accessFile("a+"); fprintf(this->fileHandle, inputData); fclose(this->fileHandle); return; } private: void accessFile(const char* fileAccessMode) { this->fileHandle = nullptr; fopen_s(&(this->fileHandle), this->fileName, fileAccessMode); if (nullptr == this->fileHandle) { fprintf(stderr, "ERROR: Failed to access file\n"); return; } return; } }; class LogFileManager : FileManager { public: LogFileManager(const char* logFileName) : FileManager(logFileName) { } void generateLogFile(const char* message) { time_t currentTime = time(nullptr); char currentDate[26]; ctime_s(currentDate, sizeof(currentDate), ¤tTime); // TODO: Bad code fix (double file access => slow) this->rewriteToFile(currentDate); this->writeToFile(message); return; } private: }; int main() { // Initialize GLFW if (GLFW_FALSE == glfwInit()) { fprintf(stderr, "ERROR: Failed to initialize GLFW3\n"); return EXIT_FAILURE; } // Create window glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL Game", nullptr, nullptr); if (nullptr == window) { fprintf(stderr, "ERROR: Failed to create window with GLFW3\n"); glfwTerminate(); return EXIT_FAILURE; } glfwMakeContextCurrent(window); // Load all OpenGL function pointers. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { fprintf(stderr, "ERROR: Failed to initialize GLAD\n"); return EXIT_FAILURE; } // Get info from renderer const GLubyte* renderer = glGetString(GL_RENDERER); const GLubyte* version = glGetString(GL_VERSION); fprintf(stdout, "Renderer: %s\nOpenGL version supported: %s\n", renderer, version); // Enable depth glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); // Put defining code here // Define triangle GLfloat points[] = {0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f}; // Create buffer object GLuint vbo = 0; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); // Create vertex attribute object GLuint vao = 0; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); // Shader definitions const char* vertexShaderSource = "#version 330\n" "in vec3 coordinates3d\n" "void main() {\n" " glPosition(coordinates3d.x, coordinates3d.y, coordinates3d.z, 1.0f);\n" "}"; const char* fragmentShaderSource = "#version 330\n" "out vec4 fragmentColor\n" "void main() {\n" " fragmentColor = vec4(0.5f, 0.0f, 0.0f, 1.0f);\n" "}"; // Create and compile shaders GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr); glCompileShader(vertexShader); // Check if the vertex shader got compile errors LogFileManager logFileManager("log.txt"); int success = 0; char message[512] = {}; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, nullptr, message); // TODO: Specify error type in message logFileManager.generateLogFile(message); } GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr); glCompileShader(fragmentShader); // Check if the fragment shader got compile errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, nullptr, message); // TODO: Specify error type in message logFileManager.generateLogFile(message); } // Create shader program and link it GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // Check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetShaderInfoLog(shaderProgram, 512, nullptr, message); // TODO: Specify error type in message logFileManager.generateLogFile(message); } // Render loop while (!glfwWindowShouldClose(window)) { // Wipe the drawing surface clear glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use shader program and vertex attribute object glUseProgram(shaderProgram); glBindVertexArray(vao); // Draw from the currently bound vertex attribute object glDrawArrays(GL_TRIANGLES, 0, 3); glfwPollEvents(); glfwSwapBuffers(window); } // Exit program glfwTerminate(); return EXIT_SUCCESS; }
Ich erwarte ein rotes Dreieck als Bildschirmausgabe, da laut Zeile 122, die Fragmente rot gefaerbt sein muessen.
Aber ich bekomme ein weisses Dreieck, da es offenbar laut erzeugter Logdatei einen Syntax-Fehler bei der Kompilerung des Fragment-Shaders gibt:...
ERROR: 0:3: 'void' : syntax error syntax errorDer Fragment-Shader (ab Zeile 119) ist eigentlich in Ordnung, trotzdem bekomme ich einen Kompilierfehler.
-
Es fehlen die Semikolons nach den Deklarationen in beiden Shadern:
"in vec3 coordinates3d;\n"
und"out vec4 fragmentColor;\n"
.Du prüfst auch fast keine GL Funktion auf Erfolg. Die Fehler würden sonst sofort in Zeilen 125 und 138 sofort auffallen.