9 #include <OpenGL/glew.h>
11 #include <GLUT/glut.h>
13 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
20 bool hasDrawn = false;
23 glClear(GL_COLOR_BUFFER_BIT);
24 for (int i = 0; i < 2; i++) {
25 glUseProgram(progIds[i]);
26 glBindVertexArray(vaos[i]);
27 glDrawArrays(GL_TRIANGLES, 0, 3);
36 void attachShader(GLuint progId, const char* filePath, GLenum type) {
37 GLuint shader = glCreateShader(type);
40 fprintf(stderr, "error creating shader\n");
44 ifstream file(filePath);
46 buffer << file.rdbuf();
47 string str = buffer.str();
48 const char* contents = str.c_str();
50 glShaderSource(shader, 1, (const GLchar**)&contents, NULL);
51 glCompileShader(shader);
53 glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
56 glGetShaderInfoLog(shader, 1024, NULL, log);
57 fprintf(stderr, "error: %s\n", log);
60 glAttachShader(progId, shader);
63 GLuint compileShaders(char* vertexShader, char* fragmentShader) {
64 GLuint progId = glCreateProgram();
66 attachShader(progId, vertexShader, GL_VERTEX_SHADER);
67 attachShader(progId, fragmentShader, GL_FRAGMENT_SHADER);
69 glLinkProgram(progId);
71 glGetProgramiv(progId, GL_LINK_STATUS, &success);
74 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
75 fprintf(stderr, "error linking: %s\n", log);
82 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
84 GLuint setupBuffers(GLfloat* vertices, GLuint progId) {
95 glGenBuffers(1, &vbo);
98 glGenVertexArrays(1, &vao);
100 GLuint posId = glGetAttribLocation(progId, "vPosition");
101 GLuint colorId = glGetAttribLocation(progId, "vColor");
103 GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
104 GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
106 glBindBuffer(GL_ARRAY_BUFFER, vbo);
107 glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
109 glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
110 glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
112 glBindVertexArray(vao);
114 glEnableVertexAttribArray(posId);
115 glEnableVertexAttribArray(colorId);
117 glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
118 glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
123 void validateProgram(GLuint progId) {
124 glValidateProgram(progId);
127 glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
130 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
131 fprintf(stderr, "error: %s\n", log);
137 GLfloat vertices[2][9] = {
151 vaos = new GLuint[2];
152 progIds = new GLuint[2];
154 GLuint progId1 = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl");
155 vaos[0] = setupBuffers(vertices[0], progId1);
156 progIds[0] = progId1;
157 validateProgram(progId1);
159 GLuint progId2 = compileShaders((char*)"vertex.glsl", (char*)"yellow.glsl");
160 vaos[1] = setupBuffers(vertices[1], progId2);
161 progIds[1] = progId2;
162 validateProgram(progId2);
165 void keyboard(unsigned char key, int x, int y) {
169 int main(int argc, char** argv) {
170 glutInit(&argc, argv);
171 glutInitDisplayMode(GLUT_STENCIL|GLUT_SINGLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
172 glutInitWindowSize(800, 600);
173 int win = glutCreateWindow("Hello Triangle");
174 glutDisplayFunc(display);
180 glutKeyboardFunc(keyboard);