9 #include <OpenGL/glew.h>
11 #include <GLUT/glut.h>
13 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
21 glClear(GL_COLOR_BUFFER_BIT);
22 for (int i = 0; i < 2; i++) {
23 glUseProgram(progIds[i]);
24 glBindVertexArray(vaos[i]);
25 glDrawArrays(GL_TRIANGLES, 0, 3);
30 void attachShader(GLuint progId, const char* filePath, GLenum type) {
31 GLuint shader = glCreateShader(type);
34 fprintf(stderr, "error creating shader\n");
38 ifstream file(filePath);
40 buffer << file.rdbuf();
41 const char* contents = buffer.str().c_str();
43 glShaderSource(shader, 1, (const GLchar**)&contents, NULL);
44 glCompileShader(shader);
46 glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
49 glGetShaderInfoLog(shader, 1024, NULL, log);
50 fprintf(stderr, "error: %s\n", log);
53 glAttachShader(progId, shader);
56 GLuint compileShaders(char* vertexShader, char* fragmentShader) {
57 GLuint progId = glCreateProgram();
59 attachShader(progId, vertexShader, GL_VERTEX_SHADER);
60 attachShader(progId, fragmentShader, GL_FRAGMENT_SHADER);
62 glLinkProgram(progId);
64 glGetProgramiv(progId, GL_LINK_STATUS, &success);
67 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
68 fprintf(stderr, "error linking: %s\n", log);
75 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
77 GLuint setupBuffers(GLfloat* vertices, GLuint progId) {
88 glGenBuffers(1, &vbo);
91 glGenVertexArrays(1, &vao);
93 GLuint posId = glGetAttribLocation(progId, "vPosition");
94 GLuint colorId = glGetAttribLocation(progId, "vColor");
96 GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
97 GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
99 glBindBuffer(GL_ARRAY_BUFFER, vbo);
100 glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
102 glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
103 glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
105 glBindVertexArray(vao);
107 glEnableVertexAttribArray(posId);
108 glEnableVertexAttribArray(colorId);
110 glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
111 glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
116 void validateProgram(GLuint progId) {
117 glValidateProgram(progId);
120 glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
123 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
124 fprintf(stderr, "error: %s\n", log);
130 GLfloat vertices[2][9] = {
144 vaos = new GLuint[2];
145 progIds = new GLuint[2];
147 GLuint progId1 = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl");
148 vaos[0] = setupBuffers(vertices[0], progId1);
149 progIds[0] = progId1;
150 validateProgram(progId1);
152 GLuint progId2 = compileShaders((char*)"vertex.glsl", (char*)"yellow.glsl");
153 vaos[1] = setupBuffers(vertices[1], progId2);
154 progIds[1] = progId2;
155 validateProgram(progId2);
158 int main(int argc, char** argv) {
159 glutInit(&argc, argv);
160 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
161 glutInitWindowSize(800, 600);
162 glutCreateWindow("Hello Triangle");
163 glutDisplayFunc(display);