#include "GL/glew.h"
#include "GL/glut.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#pragma comment(lib, "glew32.lib")
//#pragma comment(lib, "glew32s.lib") //<-- what is this even for?
struct ShaderProgramData
{
const char* vertexShaderSource;
const char* fragmentShaderSource;
int vertexShaderID;
int fragmentShaderID;
int programID;
int hWvp;
};
ShaderProgramData shader3D =
{
//the vertex shader
"uniform mat4 u_wvp;\r\n"
"attribute vec3 in_Position;\r\n"
"attribute vec4 in_Color;\r\n"
"varying vec4 v_Color;\r\n"
"\r\n"
"void main()\r\n"
"{\r\n"
"\tvec4 position = vec4(in_Position.x, in_Position.y, in_Position.z, 1.0);\r\n"
"\tgl_Position = u_wvp * position;\r\n"
"\tv_Color = in_Color;\r\n"
"}\r\n"
,
//the fragment shader
"varying vec4 v_Color;\r\n"
"\r\n"
"void main()\r\n"
"{\r\n"
"\tgl_FragColor = v_Color;\r\n"
"}\r\n"
,
0,
0,
0,
0
};
struct ModelData
{
unsigned int vertexBufferID;
int vertexCount;
const float srcData[];
};
ModelData triangle =
{
0,
3,
{
-5.0f, -5.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 5.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.5f,
5.0f, -5.0f, 0.0f,
0.0f, 0.0f, 1.0f, 1.0f
},
};
void draw()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//glLoadIdentity(); //<-- fixed function matrix style
//set shader
glUseProgram(shader3D.programID);
static glm::mat4 sworld;
glm::mat4 proj = glm::orthoLH(-25.0f, 25.0f, -25.0f, 25.0f, 1.0f, 100.0f);
//glm::mat4 proj = glm::perspectiveFovLH(glm::pi<float>() / 3.0f, 500.0f, 500.0f, 1.0f, 100.0f);
glm::mat4 view = glm::lookAtLH(glm::vec3(0.0f, 0.0f, -10.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 world = glm::rotate(sworld, .001f, glm::vec3(0.0f, 1.0f, 0.0f));
sworld = world;
glm::mat4 transform = proj * view * world;
//set vertex attributes
//glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); //not available until 4.5
//glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 12);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 28, (const void*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 28, (const void*)12);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//set vertex array to render
glBindBuffer(GL_ARRAY_BUFFER, triangle.vertexBufferID);
//glBindVertexArray(triangle.vertexArrayID); //not available until 4.3
//set uniforms
glUniformMatrix4fv(shader3D.hWvp, 1, false, (const GLfloat*)&transform[0]);
//draw triangle
glDrawArrays(GL_TRIANGLES, 0, triangle.vertexCount);
//reset vertex attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
//reset shader
glUseProgram(0);
//glFlush(); //<-- used with GLUT_SINGLE
glutSwapBuffers();
}
int main(int argc, char **argv)
{
//initialize GLUT
glutInit(&argc, argv);
//glutInitDisplayMode(GLUT_SINGLE);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Hello World, openGL!");
//initialize GLEW, must be _after_ an openGL context is created (ie. glut window creation)
glewInit();
//set up shader program, error checking ignored
shader3D.vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
shader3D.fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(shader3D.vertexShaderID, 1, &shader3D.vertexShaderSource, 0);
glShaderSource(shader3D.fragmentShaderID, 1, &shader3D.fragmentShaderSource, 0);
glCompileShader(shader3D.vertexShaderID);
glCompileShader(shader3D.fragmentShaderID);
shader3D.programID = glCreateProgram();
glAttachShader(shader3D.programID, shader3D.vertexShaderID);
glAttachShader(shader3D.programID, shader3D.fragmentShaderID);
glBindAttribLocation(shader3D.programID, 0, "in_Position"); //these must be set _before_ the shader program is linked
glBindAttribLocation(shader3D.programID, 1, "in_Color"); //alternatively, could just let program decide index, and call glGetAttribLocation
glLinkProgram(shader3D.programID);
shader3D.hWvp = glGetUniformLocation(shader3D.programID, "u_wvp");
//set up triangle vertex array
glGenBuffers(1, &triangle.vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, triangle.vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, triangle.vertexCount * 28, triangle.srcData, GL_STATIC_DRAW);
//set up rendering options, not needed atm
//glEnable(GL_DEPTH | GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//set rendering function
glutDisplayFunc(draw);
glutIdleFunc(draw);
//run main loop, glut holds the program in here until the "game" is finished
glutMainLoop();
//remove vertex array
glDeleteBuffers(1, &triangle.vertexBufferID);
//remove shader resources
glDetachShader(shader3D.programID, shader3D.vertexShaderID); //is this necessary since the program will be deleted?
glDetachShader(shader3D.programID, shader3D.fragmentShaderID);
glDeleteProgram(shader3D.programID);
glDeleteShader(shader3D.vertexShaderID);
glDeleteShader(shader3D.fragmentShaderID);
return 0;
}