// Link statically with GLEW #define GLEW_STATIC // Headers #include #include #include #include // Shader sources const GLchar* vertexSource = "#version 150 core\n" "in vec2 position;" "in vec3 color;" "in vec2 texcoord;" "out vec3 Color;" "out vec2 Texcoord;" "void main()" "{" " Color = color;" " Texcoord = texcoord;" " gl_Position = vec4(position, 0.0, 1.0);" "}"; const GLchar* fragmentSource = "#version 150 core\n" "in vec3 Color;" "in vec2 Texcoord;" "out vec4 outColor;" "uniform sampler2D texKitten;" "uniform float time;" "void main()" "{" " if (Texcoord.y < 0.5)" " outColor = texture(texKitten, Texcoord);" " else" " outColor = texture(texKitten, vec2(Texcoord.x, 1.0 - Texcoord.y));" "}"; int main() { auto t_start = std::chrono::high_resolution_clock::now(); sf::ContextSettings settings; settings.depthBits = 24; settings.stencilBits = 8; sf::Window window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close, settings); // Initialize GLEW glewExperimental = GL_TRUE; glewInit(); // Create Vertex Array Object GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Create a Vertex Buffer Object and copy the vertex data to it GLuint vbo; glGenBuffers(1, &vbo); GLfloat vertices[] = { // Position Color Texcoords -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left }; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Create an element array GLuint ebo; glGenBuffers(1, &ebo); GLuint elements[] = { 0, 1, 2, 2, 3, 0 }; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); // Create and compile the vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSource, NULL); glCompileShader(vertexShader); // Create and compile the fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSource, NULL); glCompileShader(fragmentShader); // Link the vertex and fragment shader into a shader program GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glBindFragDataLocation(shaderProgram, 0, "outColor"); glLinkProgram(shaderProgram); glUseProgram(shaderProgram); // Specify the layout of the vertex data GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), 0); GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); glEnableVertexAttribArray(colAttrib); glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); glEnableVertexAttribArray(texAttrib); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GLfloat), (void*)(5 * sizeof(GLfloat))); // Load texture GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); int width, height; unsigned char* image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); GLint uniTime = glGetUniformLocation(shaderProgram, "time"); bool running = true; while (running) { sf::Event windowEvent; while (window.pollEvent(windowEvent)) { switch (windowEvent.type) { case sf::Event::Closed: running = false; break; } } // Clear the screen to black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Set the time uniform auto t_now = std::chrono::high_resolution_clock::now(); float time = std::chrono::duration_cast>(t_now - t_start).count(); glUniform1f(uniTime, time); // Draw a rectangle from the 2 triangles using 6 indices glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // Swap buffers window.display(); } glDeleteTextures(1, &tex); glDeleteProgram(shaderProgram); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteBuffers(1, &ebo); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); window.close(); return 0; }