#include <iostream> | |
#include <math.h> | |
#if ( (defined(__MACH__)) && (defined(__APPLE__)) ) | |
#include <stdlib.h> | |
#include <OpenGL/gl.h> | |
#include <GLUT/glut.h> | |
#include <OpenGL/glext.h> | |
#else | |
#include <stdlib.h> | |
#include <GL/glew.h> | |
#include <GL/gl.h> | |
#include <GL/glut.h> | |
#include <GL/glext.h> | |
#endif | |
using namespace std; | |
const char *VERTEX_SHADER_SOURCE = "\n" \ | |
"layout(location = 0) in vec3 pos; \n" \ | |
"layout(location = 1) in vec3 color; \n" \ | |
"uniform vec3 translate; \n" \ | |
"out vec4 v_pos; \n" \ | |
"out vec4 v_color; \n" \ | |
"void main () \n" \ | |
"{ \n" \ | |
" gl_Position = vec4(pos+translate, 1.0); \n" \ | |
" v_pos = gl_Position; \n" \ | |
" v_color = vec4(color.r, color.g, color.b, 1.0); \n" \ | |
"} \n" \ | |
"\n"; | |
const char * FRAGMENT_SHADER_SOURCE = "\n" \ | |
"varying vec4 v_pos; \n" \ | |
"varying vec4 v_color; \n" \ | |
"void main () \n" \ | |
"{ \n" \ | |
" gl_FragColor = v_color; \n" \ | |
"} \n" \ | |
"\n"; | |
GLfloat vertices[12] = { | |
-0.5f, -0.5f, 0.0f, | |
-0.5f, 0.5f, 0.0f, | |
0.5f, 0.5f, 0.0f, | |
0.5f, -0.5f, 0.0f | |
}; | |
GLfloat colors1[12] = { | |
1.0f, 0.0f, 0.0f, | |
1.0f, 0.0f, 0.0f, | |
0.0f, 0.0f, 1.0f, | |
0.0f, 0.0f, 1.0f | |
}; | |
GLfloat colors2[12] = { | |
0.0f, 1.0f, 0.0f, | |
0.0f, 1.0f, 0.0f, | |
0.0f, 0.2f, 0.0f, | |
0.0f, 0.2f, 0.0f | |
}; | |
GLuint indices[4] = { 0, 1, 2, 2 }; | |
GLuint theShaderProgram; | |
GLuint theIndexVBO; | |
GLuint theVertexVBO; | |
GLuint theColor1VBO; | |
GLuint theColor2VBO; | |
GLuint theVAO1; | |
GLuint theVAO2; | |
void MakeVAO(GLuint vao, GLuint indexVBO, GLuint vertexVBO, GLuint colorVBO) | |
{ | |
glBindVertexArray(vao); | |
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); | |
glBindBuffer(GL_ARRAY_BUFFER, colorVBO); | |
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); | |
glEnableVertexAttribArray(0); | |
glEnableVertexAttribArray(1); | |
} | |
void DefineUnitQuad () | |
{ | |
glGenBuffers(1, &theVertexVBO); | |
glBindBuffer(GL_COPY_WRITE_BUFFER, theVertexVBO); | |
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
glGenBuffers(1, &theColor1VBO); | |
glBindBuffer(GL_COPY_WRITE_BUFFER, theColor1VBO); | |
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(colors1), colors1, GL_STATIC_DRAW); | |
glGenBuffers(1, &theColor2VBO); | |
glBindBuffer(GL_COPY_WRITE_BUFFER, theColor2VBO); | |
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(colors2), colors2, GL_STATIC_DRAW); | |
glGenBuffers(1, &theIndexVBO); | |
glBindBuffer(GL_COPY_WRITE_BUFFER, theIndexVBO); | |
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); | |
glGenVertexArrays(1, &theVAO1); | |
MakeVAO(theVAO1, theIndexVBO, theVertexVBO, theColor1VBO); | |
glGenVertexArrays(1, &theVAO2); | |
MakeVAO(theVAO2, theIndexVBO, theVertexVBO, theColor2VBO); | |
} | |
void InitCanvas() | |
{ | |
glViewport(0, 0, 500, 500); | |
glClearColor(0.1, 0.1, 0.1, 1.0); | |
DefineUnitQuad(); | |
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &VERTEX_SHADER_SOURCE, NULL); | |
glCompileShader(vertexShader); | |
// catch vertex shader compilation error | |
GLint success; | |
GLchar infoLog[512]; | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | |
std::cout << "Vertex shader did not compile\n" << infoLog << std::endl; | |
} | |
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &FRAGMENT_SHADER_SOURCE, NULL); | |
glCompileShader(fragmentShader); | |
// catch fragment shader compilation error | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); | |
std::cout << "Fragment shader did not compile\n" << infoLog << std::endl; | |
} | |
theShaderProgram = glCreateProgram(); | |
glAttachShader(theShaderProgram, vertexShader); | |
glAttachShader(theShaderProgram, fragmentShader); | |
glLinkProgram(theShaderProgram); | |
// catch program linking error | |
glGetProgramiv(theShaderProgram, GL_LINK_STATUS, &success); | |
if (!success) | |
{ | |
glGetProgramInfoLog(theShaderProgram, 512, NULL, infoLog); | |
std::cout << "Shader program did not link\n" << infoLog << std::endl; | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
} | |
void Timer(int vp_time) | |
{ | |
glutPostRedisplay(); | |
glutTimerFunc(100, Timer, 0); | |
} | |
void Draw () | |
{ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glOrtho(-1.0, 1.0, -1.0, 1.0, -10, 10); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
glUseProgram(theShaderProgram); | |
GLuint uniAttrLoc = glGetUniformLocation(theShaderProgram, "translate"); | |
glUniform3f(uniAttrLoc, -0.25f, -0.25f, 0.0f); | |
glBindVertexArray(theVAO1); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, theIndexVBO); | |
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, (void*) 0); | |
glUniform3f(uniAttrLoc, 0,0,0); //0.25f, 0.25f, 0.0f); | |
glBindVertexArray(theVAO2); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, theIndexVBO); | |
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, (void*) 0); | |
glFlush(); | |
} | |
int main (int argc, char *argv[]) | |
{ | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_RGBA); | |
glutInitWindowSize(500, 500); | |
glutInitWindowPosition(0, 0); | |
glutCreateWindow("helloGL"); | |
glewInit(); | |
if (glewIsSupported("GL_VERSION_2_0")) | |
{ | |
cout << "Ready for OpenGL 2.0\n"; | |
} | |
else | |
{ | |
cout << "OpenGL 2.0 not supported\n"; | |
exit(1); | |
} | |
InitCanvas(); | |
glutTimerFunc(100, Timer, 0); | |
glutDisplayFunc(Draw); | |
glutMainLoop(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment