fd55f4e5bca90c65027b3cf4cbb0107493e5b05e
[opengl.git] / assignment1.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fstream>
4 #include <sstream>
5 #ifdef __APPLE__
6 #include <GL/glew.h>
7 #else
8 #include <OpenGL/glew.h>
9 #endif
10 #include <GLUT/glut.h>
11
12 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
13
14 using namespace std;
15
16 GLuint* vaos;
17
18 void display() {
19         glClear(GL_COLOR_BUFFER_BIT);
20         for (int i = 0; i < 2; i++) {
21                 glBindVertexArray(vaos[i]);
22                 glDrawArrays(GL_TRIANGLES, 0, 3);
23         }
24         glutSwapBuffers();
25 }
26
27 void attachShader(GLuint progId, const char* filePath, GLenum type) {
28         GLuint shader = glCreateShader(type);
29
30         if (!shader) {
31                 fprintf(stderr, "error creating shader\n");
32                 exit(1);
33         }
34
35         ifstream file(filePath);
36         stringstream buffer;
37         buffer << file.rdbuf();
38         const char* contents = buffer.str().c_str();
39
40         glShaderSource(shader, 1, (const GLchar**)&contents, NULL);
41         glCompileShader(shader);
42         GLint success;
43         glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
44         if (!success) {
45                 GLchar log[1024];
46                 glGetShaderInfoLog(shader, 1024, NULL, log);
47                 fprintf(stderr, "error: %s\n", log);
48                 exit(1);
49         }
50         glAttachShader(progId, shader);
51 }
52
53 GLuint compileShaders() {
54         GLuint progId = glCreateProgram();
55
56         attachShader(progId, "vertex.glsl", GL_VERTEX_SHADER);
57         attachShader(progId, "fragment.glsl", GL_FRAGMENT_SHADER);
58
59         glLinkProgram(progId);
60         GLint success = 0;
61         glGetProgramiv(progId, GL_LINK_STATUS, &success);
62         if (!success) {
63                 GLchar log[1024];
64                 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
65                 fprintf(stderr, "error linking: %s\n", log);
66                 exit(1);
67         }
68
69         glUseProgram(progId);
70         return progId;
71 }
72
73 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
74
75 GLuint* setupBuffers(GLuint progId) {
76         GLfloat vertices[2][9] = {
77                 {
78                         0.0f, -1.0f, 0.0f,
79                         1.0f, -1.0f, 0.0f,
80                         0.5f, 1.0f, 0.0f
81                 },
82
83                 {
84                         -1.0f, -1.0f, 0.0f,
85                         0.0f, -1.0f, 0.0f,
86                         -0.5f, 1.0f, 0.0f
87                 }
88         };
89
90         GLfloat colors[] = {
91                 0, 1, 0, 1,
92                 1, 0, 0, 1,
93                 0, 0, 1, 1
94         };
95
96         GLuint numVerts = 3;
97
98         GLuint vbos[2];
99         glGenBuffers(2, vbos);
100
101         GLuint* vaos = new GLuint[2];
102         glGenVertexArrays(2, vaos);
103
104         GLuint posId = glGetAttribLocation(progId, "vPosition");
105         GLuint colorId = glGetAttribLocation(progId, "vColor");
106
107         GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
108         GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
109
110
111         for(int i = 0; i < 2; i++) {
112                 glBindBuffer(GL_ARRAY_BUFFER, vbos[i]);
113                 glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
114
115                 glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices[i]);
116                 glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
117                 
118                 glBindVertexArray(vaos[i]);
119
120                 glEnableVertexAttribArray(posId);
121                 glEnableVertexAttribArray(colorId);
122                 
123                 glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
124                 glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
125         }
126
127         return vaos;
128 }
129
130 void init() {
131         GLuint progId = compileShaders();
132         vaos = setupBuffers(progId);
133         
134         glValidateProgram(progId);
135         
136         GLint success;
137         glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
138         if (!success) {
139                 GLchar log[1024];
140                 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
141                 fprintf(stderr, "error: %s\n", log);
142                 exit(1);
143         }
144 }
145
146 int main(int argc, char** argv) {
147         glutInit(&argc, argv);
148         glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
149         glutInitWindowSize(800, 600);
150         glutCreateWindow("Hello Triangle");
151         glutDisplayFunc(display);
152
153         glewInit();
154         
155         init();
156
157         glutMainLoop();
158
159         return 0;
160 }
161