11 #include <OpenGL/glew.h>
13 #include <GLUT/glut.h>
14 #include <glm/glm.hpp>
15 #include <glm/ext.hpp>
16 #include <glm/gtc/type_ptr.hpp>
18 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
24 glm::vec3 camPos = glm::vec3(0.0f, 0.0f, -5.0f);
25 glm::vec3 camFront = glm::vec3(0.0f, 0.0f, 1.0f);
26 glm::vec3 camUp = glm::vec3(0.0f, 1.0f, 0.0f);
27 float yaw = 1.57, pitch = 0;
28 bool doScale, doRotate, doTranslate;
31 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
33 glBindVertexArray(vaos[0]);
34 for (int i = 0; i < 100; i++) {
36 GLuint projId = glGetUniformLocation(progId, "projection");
37 glm::mat4 proj = glm::perspective(glm::radians(45.f), 1.33f, 0.01f, 10000.f);
38 glUniformMatrix4fv(projId, 1, GL_FALSE, glm::value_ptr(proj));
40 GLuint viewId = glGetUniformLocation(progId, "view");
41 glm::mat4 view = glm::lookAt(camPos, camPos + camFront, camUp);
42 glUniformMatrix4fv(viewId, 1, GL_FALSE, glm::value_ptr(view));
44 GLuint modelId = glGetUniformLocation(progId, "model");
45 glm::mat4 model = glm::mat4(1.f);
47 float d = (float)glutGet(GLUT_ELAPSED_TIME) * 0.001f;
48 model = glm::translate(model, glm::vec3(sin(i * 30) * 10, cos(i * 30) * 10, i * 2));
51 model = glm::rotate(model, d * glm::radians(30.f), glm::vec3(0.f, 1.f, 0.f));
52 model = glm::rotate(model, d * glm::radians(20.f), glm::vec3(1.f, 0.f, 0.f));
56 model = glm::scale(model, glm::vec3(1.f, 0.7f + 0.7f * (1 + sin(d + (i + 3))), 1.f));
59 model = glm::translate(model, glm::vec3(sin(d + (i + 1)), cos(d + (i + -3)), sin(d + (i + 4))));
62 glUniformMatrix4fv(modelId, 1, GL_FALSE, glm::value_ptr(model));
64 glDrawArrays(GL_TRIANGLES, 0, 12);
69 void attachShader(GLuint progId, const char* filePath, GLenum type) {
70 GLuint shader = glCreateShader(type);
73 fprintf(stderr, "error creating shader\n");
77 ifstream file(filePath);
79 buffer << file.rdbuf();
80 string str = buffer.str();
81 const char* contents = str.c_str();
83 glShaderSource(shader, 1, (const GLchar**)&contents, NULL);
84 glCompileShader(shader);
86 glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
89 glGetShaderInfoLog(shader, 1024, NULL, log);
90 fprintf(stderr, "error: %s\n", log);
93 glAttachShader(progId, shader);
96 GLuint compileShaders(char* vertexShader, char* fragmentShader) {
97 GLuint progId = glCreateProgram();
99 attachShader(progId, vertexShader, GL_VERTEX_SHADER);
100 attachShader(progId, fragmentShader, GL_FRAGMENT_SHADER);
102 glLinkProgram(progId);
104 glGetProgramiv(progId, GL_LINK_STATUS, &success);
107 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
108 fprintf(stderr, "error linking: %s\n", log);
115 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
117 GLuint setupBuffers(GLfloat* vertices, GLuint progId) {
137 GLuint numVerts = 12;
140 glGenBuffers(1, &vbo);
143 glGenVertexArrays(1, &vao);
145 GLuint posId = glGetAttribLocation(progId, "vPosition");
146 GLuint colorId = glGetAttribLocation(progId, "vColor");
148 GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
149 GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
151 glBindBuffer(GL_ARRAY_BUFFER, vbo);
152 glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
154 glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
155 glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
157 glBindVertexArray(vao);
158 glEnableVertexAttribArray(posId);
159 glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
161 glEnableVertexAttribArray(colorId);
162 glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
167 void validateProgram(GLuint progId) {
168 glValidateProgram(progId);
171 glGetProgramiv(progId, GL_VALIDATE_STATUS, &success);
174 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
175 fprintf(stderr, "error: %s\n", log);
181 GLfloat vertices[9*4] = {
200 vaos = new GLuint[2];
202 progId = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl");
203 glUseProgram(progId);
204 vaos[0] = setupBuffers(vertices, progId);
205 validateProgram(progId);
207 glEnable(GL_DEPTH_TEST);
210 bool* keyStates = new bool[256];
212 void keyboard(unsigned char key, int x, int y) {
213 keyStates[key] = true;
217 doRotate = !doRotate;
219 doTranslate = !doTranslate;
222 void keyboardUp(unsigned char key, int x, int y) {
223 keyStates[key] = false;
227 float xSpeed = 0.f, ySpeed = 0.f, zSpeed = 0.f;
241 camPos.x += xSpeed * sin(yaw) + zSpeed * cos(yaw);
243 camPos.z += zSpeed * sin(yaw) - xSpeed * cos(yaw);
245 glutTimerFunc(16, idle, 0);
248 int prevMouseX, prevMouseY;
249 bool firstMouse = true;
251 void motion(int x, int y) {
257 int dx = x - prevMouseX, dy = y - prevMouseY;
262 const float sensitivity = 0.005f;
263 yaw += dx * sensitivity;
264 pitch -= dy * sensitivity;
267 front.x = cos(pitch) * cos(yaw);
268 front.y = sin(pitch);
269 front.z = cos(pitch) * sin(yaw);
270 camFront = glm::normalize(front);
273 void mouse(int button, int state, int x, int y) {
274 if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
278 int main(int argc, char** argv) {
279 glutInit(&argc, argv);
280 glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
281 glutInitWindowSize(800, 600);
282 int win = glutCreateWindow("Hello Triangle");
283 glutDisplayFunc(display);
289 glutKeyboardFunc(keyboard);
290 glutKeyboardUpFunc(keyboardUp);
291 glutTimerFunc(16, timer, 0);
292 glutMotionFunc(motion);
293 glutMouseFunc(mouse);