#include <GL/glew.h>
#include <GL/glfw.h>
#include <iostream>
#include <string>
#include <vector>
bool running;
int closedWindow()
{
running = false;
return GL_TRUE;
}
bool check_shader_compile_status(GLuint obj)
{
GLint status;
glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE)
{
GLint length;
glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &length);
std::vector<char> log(length);
glGetShaderInfoLog(obj, length, &length, &log[0]);
std::cerr << &log[0];
return false;
}
return true;
}
bool check_program_link_status(GLuint obj)
{
GLint status;
glGetProgramiv(obj, GL_LINK_STATUS, &status);
if(status == GL_FALSE)
{
GLint length;
glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &length);
std::vector<char> log(length);
glGetProgramInfoLog(obj, length, &length, &log[0]);
std::cerr << &log[0];
return false;
}
return true;
}
int main()
{
int width = 640;
int height = 480;
if(glfwInit() == GL_FALSE)
{
std::cerr << "failed to init GLFW" << std::endl;
return 1;
}
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE)
{
std::cerr << "failed to open window" << std::endl;
glfwTerminate();
return 1;
}
glfwSetWindowCloseCallback(closedWindow);
glewExperimental = GL_TRUE;
GLenum glew_error = glewInit();
if (glew_error != GLEW_OK)
{
std::cerr << "failed to init GLEW: " << glewGetErrorString(glew_error) << std::endl;
glfwCloseWindow();
glfwTerminate();
return 1;
}
std::string vertex_source =
"#version 330\n"
"out vec4 fcolor;\n"
"const vec2 quad[6] = vec2[](\n"
" vec2(0,0),vec2(1,0),vec2(1,1),\n"
" vec2(0,0),vec2(1,1),vec2(0,1)\n"
");\n"
"void main() {\n"
" fcolor = vec4(quad[gl_VertexID],0,1);\n"
" gl_Position = vec4(2*quad[gl_VertexID] - 1,0,1);\n"
"}\n";
std::string fragment_source =
"#version 330\n"
"in vec4 fcolor;\n"
"layout(location = 0) out vec4 FragColor;\n"
"void main() {\n"
" FragColor = fcolor;\n"
"}\n";
GLuint shader_program, vertex_shader, fragment_shader;
const char *source;
int length;
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
source = vertex_source.c_str();
length = vertex_source.size();
glShaderSource(vertex_shader, 1, &source, &length);
glCompileShader(vertex_shader);
if(!check_shader_compile_status(vertex_shader))
{
return 1;
}
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
source = fragment_source.c_str();
length = fragment_source.size();
glShaderSource(fragment_shader, 1, &source, &length);
glCompileShader(fragment_shader);
if(!check_shader_compile_status(fragment_shader))
{
return 1;
}
shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program);
check_program_link_status(shader_program);
glUseProgram(shader_program);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// stuff that shouldn't be required...
/*
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat), 0, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, (char*)0 + 0*sizeof(GLfloat));
*/
running = true;
while(running)
{
if(glfwGetKey(GLFW_KEY_ESC))
{
running = false;
}
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
GLenum error = glGetError();
if(error != GL_NO_ERROR)
{
std::cerr << error;
running = false;
}
glfwSwapBuffers();
}
glDeleteVertexArrays(1, &vao);
//glDeleteBuffers(1, &vbo);
glDetachShader(shader_program, vertex_shader);
glDetachShader(shader_program, fragment_shader);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
glDeleteProgram(shader_program);
glfwCloseWindow();
glfwTerminate();
return 0;
}