#include #include #include #include GLuint program; GLuint vao; GLfloat hue = 0.0f; GLfloat hueshift = 32.7f; GLfloat offsetX = -0.75f; GLfloat offsetY = 0.4f; GLfloat speedX = 0.0005f; GLfloat speedY = -0.0005f; #define NUM_TRIANGLES 8 typedef struct { GLfloat x; GLfloat y; } Point; typedef struct { Point p1; Point p2; Point p3; } Triangle; typedef struct { Triangle t1; Triangle t2; } TriangleRect; void createRect(TriangleRect* rect, GLfloat posx, GLfloat posy, GLfloat width, GLfloat height) { rect->t1.p1.x = posx; rect->t1.p1.y = posy; rect->t1.p2.x = posx + width; rect->t1.p2.y = posy; rect->t1.p3.x = posx; rect->t1.p3.y = posy + height; rect->t2.p1.x = posx + width; rect->t2.p1.y = posy; rect->t2.p2.x = posx + width; rect->t2.p2.y = posy + height; rect->t2.p3.x = posx; rect->t2.p3.y = posy + height; } void createCenterRect(TriangleRect* rect, GLfloat posx, GLfloat posy, GLfloat width, GLfloat height) { createRect(rect, posx - width / 2, posy - height / 2, width, height); } void init(void) { // create and compile vertex shader const char *vertexText = "#version 330 core\n" "layout (location = 0) in vec2 aPosition;\n" "uniform vec3 color;\n" "uniform vec2 offset;" "out vec3 vertexColor;\n" "void main() {\n" " gl_Position = vec4(aPosition + offset, 0.0, 1.0);\n" " vertexColor = color;" "}\n"; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexText, NULL); 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); } // create and compile fragment shader const char *fragmentText = "#version 330 core\n" "in vec3 vertexColor;\n" "void main() {\n" " gl_FragColor = vec4(vertexColor, 1.0);\n" "}\n"; GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentText, NULL); 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); } // 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); } TriangleRect triangleVertices[4]; createCenterRect(&triangleVertices[0], -0.2f, 0.0f, 0.1f, 1.2f); createCenterRect(&triangleVertices[1], 0.2f, 0.0f, 0.1f, 1.2f); createCenterRect(&triangleVertices[2], 0.0f, 0.0f, 0.3f, 0.1f); createCenterRect(&triangleVertices[3], 0.0f, -0.8f, 0.5f, 0.1f); GLuint triangleVertexBufferObject; glGenBuffers(1, &triangleVertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // 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); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); } void hueToRgb(GLfloat hue, GLfloat* r, GLfloat* g, GLfloat* b) { GLfloat x = hue / 60; while (x > 2) x -= 2; x = x - 1; x = 1 - fabs(x); if (hue < 60) { *r = 1.0f; *g = x; *b = 0; } else if (hue < 120) { *r = x; *g = 1.0f; *b = 0; } else if (hue < 180) { *r = 0; *g = 1.0f; *b = x; } else if (hue < 240) { *r = 0; *g = x; *b = 1.0f; } else if (hue < 300) { *r = x; *g = 0; *b = 1.0f; } else { *r = 1.0f; *g = 0; *b = x; } } void draw(void) { glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); offsetX += speedX; offsetY += speedY; if (offsetX >= 0.75f || offsetX <= -0.75f) { speedX *= -1; hue += hueshift; } if (offsetY >= 0.4f || offsetY <=-0.15f) { speedY *= -1; hue += hueshift; } if (hue > 360) hue -= 360; GLfloat r; GLfloat g; GLfloat b; hueToRgb(hue, &r, &g, &b); // SET COLOR // glUniform3f(glGetUniformLocation(program, "color"), 0.7719f, 0.2105f, 0.0175f); glUniform3f(glGetUniformLocation(program, "color"), r, g, b); glUniform2f(glGetUniformLocation(program, "offset"), offsetX, offsetY); glDrawArrays(GL_TRIANGLES, 0, NUM_TRIANGLES * 3); } void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); } int main(void) { printf("Hello World!\n"); glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow *window = glfwCreateWindow(800, 600, "Computergrafik 1", NULL, NULL); if (!window) { printf("Failed to create window\n"); glfwTerminate(); return -1; } glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwMakeContextCurrent(window); glewInit(); init(); while (!glfwWindowShouldClose(window)) { draw(); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }