#include <stdlib.h>
#include <fstream>
#include <sstream>
+#include <vector>
#ifdef __APPLE__
#include <GL/glew.h>
#else
using namespace std;
+GLuint* vaos;
+GLuint* progIds;
+
+bool hasDrawn = false;
+
void display() {
glClear(GL_COLOR_BUFFER_BIT);
- glDrawArrays(GL_TRIANGLES, 0, 6);
+ for (int i = 0; i < 2; i++) {
+ glUseProgram(progIds[i]);
+ glBindVertexArray(vaos[i]);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ }
glutSwapBuffers();
+ if (!hasDrawn) {
+ glutPostRedisplay();
+ hasDrawn = true;
+ }
}
void attachShader(GLuint progId, const char* filePath, GLenum type) {
ifstream file(filePath);
stringstream buffer;
buffer << file.rdbuf();
- const char* contents = buffer.str().c_str();
+ string str = buffer.str();
+ const char* contents = str.c_str();
glShaderSource(shader, 1, (const GLchar**)&contents, NULL);
glCompileShader(shader);
glAttachShader(progId, shader);
}
-GLuint compileShaders() {
+GLuint compileShaders(char* vertexShader, char* fragmentShader) {
GLuint progId = glCreateProgram();
- attachShader(progId, "vertex.glsl", GL_VERTEX_SHADER);
- attachShader(progId, "fragment.glsl", GL_FRAGMENT_SHADER);
+ attachShader(progId, vertexShader, GL_VERTEX_SHADER);
+ attachShader(progId, fragmentShader, GL_FRAGMENT_SHADER);
glLinkProgram(progId);
GLint success = 0;
exit(1);
}
- glUseProgram(progId);
return progId;
}
-void generateObjectBuffers() {
- GLfloat vertices[] = {
- 0.0f, -1.0f, 0.0f,
- 1.0f, -1.0f, 0.0f,
- 0.5f, 1.0f, 0.0f,
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
- -1.0f, -1.0f, 0.0f,
- 0.0f, -1.0f, 0.0f,
- -0.5f, 1.0f, 0.0f
- };
+GLuint setupBuffers(GLfloat* vertices, GLuint progId) {
GLfloat colors[] = {
- 0, 1, 0, 1,
- 1, 0, 0, 1,
- 0, 0, 1, 1,
-
0, 1, 0, 1,
1, 0, 0, 1,
0, 0, 1, 1
};
- GLuint numVerts = 6;
+ GLuint numVerts = 3;
+
+ GLuint vbo;
+ glGenBuffers(1, &vbo);
- GLuint VBO;
- glGenBuffers(1, &VBO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, numVerts * 7 * sizeof(GLfloat), NULL, GL_STATIC_DRAW);
+ GLuint vao;
+ glGenVertexArrays(1, &vao);
+
+ GLuint posId = glGetAttribLocation(progId, "vPosition");
+ GLuint colorId = glGetAttribLocation(progId, "vColor");
GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
- glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
- glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
-}
-#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
-void linkBuffers(GLuint progId) {
- GLuint numVerts = 6;
- GLuint posId = glGetAttribLocation(progId, "vPosition");
- GLuint colorId = glGetAttribLocation(progId, "vColor");
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
+ glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
- GLuint vao = 0;
- glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(posId);
- glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
-
glEnableVertexAttribArray(colorId);
+
+ glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
+ return vao;
}
-void init() {
- GLuint progId = compileShaders();
- generateObjectBuffers();
- linkBuffers(progId);
-
+void validateProgram(GLuint progId) {
glValidateProgram(progId);
GLint success;
}
}
+void init() {
+ GLfloat vertices[2][9] = {
+ {
+ 0.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f,
+ 0.5f, 1.0f, 0.0f
+ },
+
+ {
+ -1.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ -0.5f, 1.0f, 0.0f
+ }
+ };
+
+ vaos = new GLuint[2];
+ progIds = new GLuint[2];
+
+ GLuint progId1 = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl");
+ vaos[0] = setupBuffers(vertices[0], progId1);
+ progIds[0] = progId1;
+ validateProgram(progId1);
+
+ GLuint progId2 = compileShaders((char*)"vertex.glsl", (char*)"yellow.glsl");
+ vaos[1] = setupBuffers(vertices[1], progId2);
+ progIds[1] = progId2;
+ validateProgram(progId2);
+}
+
+void keyboard(unsigned char key, int x, int y) {
+ glutPostRedisplay();
+}
+
int main(int argc, char** argv) {
glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
+ glutInitDisplayMode(GLUT_STENCIL|GLUT_SINGLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
glutInitWindowSize(800, 600);
- glutCreateWindow("Hello Triangle");
+ int win = glutCreateWindow("Hello Triangle");
glutDisplayFunc(display);
glewInit();
init();
+ glutKeyboardFunc(keyboard);
+
glutMainLoop();
return 0;