#include <cstdio>
#include "GL/Shaders.h"
#include "GL/ImmediateMode.h"
BEGIN_NAMESPACE
static GLfloat vertices[] = {
0.5f, 1.0f, 1.0f, 0.0f, 0.0f, // Top-left
1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
1.0f, 0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
0.5f, 0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
static GLuint elements[] = {
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 ctx;
void SetupObjects()
{
glGenVertexArrays(1, &ctx.vao);
glBindVertexArray(ctx.vao);
glGenBuffers(1, &ctx.vbo); // Generate 1 buffer
glBindBuffer(GL_ARRAY_BUFFER, ctx.vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create an element array
glGenBuffers(1, &ctx.ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ctx.ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
/*
}
static void CompileShader()
{
*/
GLint status;
ctx.vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(ctx.vertexShader, 1, &vertextShaderSource, NULL);
glCompileShader(ctx.vertexShader);
glGetShaderiv(ctx.vertexShader, GL_COMPILE_STATUS, &status);
if ( status != GL_TRUE ) {
char buffer[512];
glGetShaderInfoLog(ctx.vertexShader, 512, NULL, buffer);
printf("Vertex shader error: %s\n", buffer);
}
ctx.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(ctx.fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(ctx.fragmentShader);
glGetShaderiv(ctx.fragmentShader, GL_COMPILE_STATUS, &status);
if ( status != GL_TRUE ) {
char buffer[512];
glGetShaderInfoLog(ctx.fragmentShader, 512, NULL, buffer);
printf("Fragment shader error: %s\n", buffer);
}
ctx.shaderProgram = glCreateProgram();
glAttachShader(ctx.shaderProgram, ctx.vertexShader);
glAttachShader(ctx.shaderProgram, ctx.fragmentShader);
glBindFragDataLocation(ctx.shaderProgram, 0, "outColor");
glLinkProgram(ctx.shaderProgram);
glUseProgram(ctx.shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(ctx.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(ctx.shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
}
void DrawShaderObjects()
{
glUseProgram(ctx.shaderProgram);
glBindVertexArray(ctx.vao);
glDrawElements(GL_TRIANGLES, sizeof(elements) / sizeof(GLuint), GL_UNSIGNED_INT, 0);
glUseProgram(0);
}
void CleanupObjects()
{
glDeleteProgram(ctx.shaderProgram);
glDeleteShader(ctx.fragmentShader);
glDeleteShader(ctx.vertexShader);
glDeleteBuffers(1, &ctx.ebo);
glDeleteBuffers(1, &ctx.vbo);
glDeleteVertexArrays(1, &ctx.vao);
}
END_NAMESPACE