#include #include #include #include "vertexShader.c" #include "fragmentShader.c" #include #include #include /** * 0.15 0.25 * | | * * 0__1 8__9 ___0.6 * | | | | * | | | | * | 4_____6 | ___0.05 * | 5_____7 | * | | | | * | | | | * 2__3 10_11 * * 12__________14 __-0.75 * 13__________15 __-0.85 * */ #define RESTART 345678 typedef struct { GLfloat x; GLfloat y; GLfloat value; } Point; GLuint program; GLuint vao; GLfloat rotation; void init(void) { // create and compile vertex shader GLchar *vertexText = malloc(vertexShader_glsl_len); memcpy(vertexText, vertexShader_glsl, vertexShader_glsl_len); const GLchar *vertexTextConst = vertexText; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexTextConst, &vertexShader_glsl_len); glCompileShader(vertexShader); GLint status; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); if (!status) { printf("Error compiling vertex shader: "); GLchar infoLog[1024]; glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog); printf("%s",infoLog); } free(vertexText); vertexText = NULL; vertexTextConst = NULL; // create and compile fragment shader GLchar *fragmentText = malloc(fragmentShader_glsl_len); memcpy(fragmentText, fragmentShader_glsl, fragmentShader_glsl_len); const GLchar *fragmentTextConst = fragmentText; GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentTextConst, &fragmentShader_glsl_len); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); if (!status) { printf("Error compiling fragment shader: "); GLchar infoLog[1024]; glGetShaderInfoLog(fragmentShader, 1024, NULL, infoLog); printf("%s",infoLog); } free(fragmentText); fragmentText = NULL; fragmentTextConst = NULL; // create and link shader program program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if (!status) { printf("Error linking program: "); GLchar infoLog[1024]; glGetProgramInfoLog(program, 1024, NULL, infoLog); printf("%s",infoLog); } glValidateProgram(program); glGetProgramiv(program, GL_VALIDATE_STATUS, &status); if (!status) { printf("Error validating program: "); GLchar infoLog[1024]; glGetProgramInfoLog(program, 1024, NULL, infoLog); printf("%s",infoLog); } size_t size = sizeof(Point) * 16; Point* corners = (Point *) malloc(size); corners[0].x = -0.25f; corners[0].y = 0.6f; corners[0].value = 0.0625f; corners[1].x = -0.15f; corners[1].y = 0.6f; corners[1].value = 0.125f; corners[2].x = -0.25f; corners[2].y = -0.6f; corners[2].value = 0.1875f; corners[3].x = -0.15f; corners[3].y = -0.6f; corners[3].value = 0.25f; corners[4].x = -0.15f; corners[4].y = 0.05f; corners[4].value = 0.3125f; corners[5].x = -0.15f; corners[5].y = -0.05f; corners[5].value = 0.375f; corners[6].x = 0.15f; corners[6].y = 0.05f; corners[6].value = 0.4375f; corners[7].x = 0.15f; corners[7].y = -0.05f; corners[7].value = 0.5f; corners[8].x = 0.15f; corners[8].y = 0.6f; corners[8].value = 0.5625f; corners[9].x = 0.25f; corners[9].y = 0.6f; corners[9].value = 0.625f; corners[10].x = 0.15f; corners[10].y = -0.6f; corners[10].value = 0.6875f; corners[11].x = 0.25f; corners[11].y = -0.6f; corners[11].value = 0.75f; corners[12].x = -0.25f; corners[12].y = -0.75f; corners[12].value = 0.8125f; corners[13].x = -0.25f; corners[13].y = -0.85f; corners[13].value = 0.875f; corners[14].x = 0.25f; corners[14].y = -0.75f; corners[14].value = 0.9375f; corners[15].x = 0.25f; corners[15].y = -0.85f; corners[15].value = 1.0f; GLuint triangleVertexBufferObject; glGenBuffers(1, &triangleVertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); glBufferData(GL_ARRAY_BUFFER, size, corners, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); free(corners); // create vertex array object glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(Point), 0 ); glEnableVertexAttribArray(0); glVertexAttribPointer( 1, 1, GL_FLOAT, GL_FALSE, sizeof(Point), (GLvoid*)(2 * sizeof(GLfloat)) ); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); } void draw(void) { glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); rotation = rotation + 0.01f; if (rotation > 2 * 3.1415926f) { rotation = 0; } glUniform1f(glGetUniformLocation(program, "rotation"), rotation); glFrontFace(GL_CW); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(RESTART); GLuint indices[] = {0, 1, 2, 3, RESTART, 4, 6, 5, 7, RESTART, 8, 9, 10, 11, RESTART, 12, 14, 13, 15}; glDrawElements(GL_TRIANGLE_STRIP, sizeof(indices) / sizeof(GLuint), GL_UNSIGNED_INT, indices); } void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); } int main(void) { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow *window = glfwCreateWindow(600, 600, "Computergrafik 1", NULL, NULL); if (!window) { printf("Failed to create window\n"); glfwTerminate(); return -1; } glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwMakeContextCurrent(window); glewInit(); printf("OpenGL version supported by this platform (%s):\n", glGetString(GL_VERSION)); init(); while (!glfwWindowShouldClose(window)) { draw(); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }