[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), &currentTime);
    		// 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 error

    Der 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.