#include <cstdio>
#include "GL/ImmediateMode.h"
#include "GL/Cubes.h"
BEGIN_NAMESPACE
static GLfloat cubeVertices[] = {
0.0f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
1.0f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Bottom-right
0.0f, 0.0f, 1.0f, 1.0f, 1.0f // Bottom-left
};
static GLuint cubeElements[] = {
0, 1, 2,
2, 3, 0
};
static const char* vertextShaderSource = "\
#version 150\n\
\n\
in vec2 position;\n\
in vec3 color;\n\
out vec3 Color;\n\
\n\
void main()\n\
{\n\
Color = color;\n\
gl_Position = vec4(position, 0.0, 1.0);\n\
}\n\
";
static const char* fragmentShaderSource = "\
#version 150\n\
\n\
in vec3 Color;\n\
out vec4 outColor;\n\
\n\
void main()\n\
{\n\
outColor = vec4(Color, 1.0);\n\
}\n\
";
struct GLProgramContext
{
GLuint shaderProgram;
GLuint vao;
GLuint vbo;
GLuint ebo;
GLuint vertexShader;
GLuint fragmentShader;
};
static GLProgramContext cubesCtx;
void SetupCubes()
{
glGenVertexArrays(1, &cubesCtx.vao);
glBindVertexArray(cubesCtx.vao);
glGenBuffers(1, &cubesCtx.vbo); // Generate 1 buffer
glBindBuffer(GL_ARRAY_BUFFER, cubesCtx.vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
// Create an element array
glGenBuffers(1, &cubesCtx.ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubesCtx.ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeElements), cubeElements, GL_STATIC_DRAW);
/*
}
static void CompileShader()
{
*/
GLint status;
cubesCtx.vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(cubesCtx.vertexShader, 1, &vertextShaderSource, NULL);
glCompileShader(cubesCtx.vertexShader);
glGetShaderiv(cubesCtx.vertexShader, GL_COMPILE_STATUS, &status);
if ( status != GL_TRUE ) {
char buffer[512];
glGetShaderInfoLog(cubesCtx.vertexShader, 512, NULL, buffer);
printf("Vertex shader error: %s\n", buffer);
}
cubesCtx.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(cubesCtx.fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(cubesCtx.fragmentShader);
glGetShaderiv(cubesCtx.fragmentShader, GL_COMPILE_STATUS, &status);
if ( status != GL_TRUE ) {
char buffer[512];
glGetShaderInfoLog(cubesCtx.fragmentShader, 512, NULL, buffer);
printf("Fragment shader error: %s\n", buffer);
}
cubesCtx.shaderProgram = glCreateProgram();
glAttachShader(cubesCtx.shaderProgram, cubesCtx.vertexShader);
glAttachShader(cubesCtx.shaderProgram, cubesCtx.fragmentShader);
glBindFragDataLocation(cubesCtx.shaderProgram, 0, "outColor");
glLinkProgram(cubesCtx.shaderProgram);
glUseProgram(cubesCtx.shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(cubesCtx.shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
//glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
GLint colAttrib = glGetAttribLocation(cubesCtx.shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
}
void DrawCubes()
{
glUseProgram(cubesCtx.shaderProgram);
glBindVertexArray(cubesCtx.vao);
glDrawElements(GL_TRIANGLES, sizeof(cubeElements) / sizeof(GLuint), GL_UNSIGNED_INT, 0);
glUseProgram(0);
}
void CleaupCubes()
{
glDeleteProgram(cubesCtx.shaderProgram);
glDeleteShader(cubesCtx.fragmentShader);
glDeleteShader(cubesCtx.vertexShader);
glDeleteBuffers(1, &cubesCtx.ebo);
glDeleteBuffers(1, &cubesCtx.vbo);
glDeleteVertexArrays(1, &cubesCtx.vao);
}
END_NAMESPACE