X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=assignment1.cpp;h=4676882fe80ec1c061ead0589e7e547714bf3052;hp=43cd62629d323b3e3bc4cc3cebf6b2087d520d16;hb=616b478aff3a11f38ab379008c43a179718333f8;hpb=1dcbad027a4537b550766e9053a4418e8256c81c diff --git a/assignment1.cpp b/assignment1.cpp index 43cd626..4676882 100644 --- a/assignment1.cpp +++ b/assignment1.cpp @@ -1,21 +1,68 @@ #include #include +#include #include #include +#include +#include #ifdef __APPLE__ #include #else #include #endif #include +#include +#include +#include #pragma clang diagnostic ignored "-Wdeprecated-declarations" using namespace std; +GLuint* vaos; +GLuint progId; +glm::vec3 camPos = glm::vec3(0.0f, 0.0f, -5.0f); +glm::vec3 camFront = glm::vec3(0.0f, 0.0f, 1.0f); +glm::vec3 camUp = glm::vec3(0.0f, 1.0f, 0.0f); +float yaw = 1.57, pitch = 0; +bool doScale, doRotate, doTranslate; + void display() { - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLES, 0, 6); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glUseProgram(progId); + glBindVertexArray(vaos[0]); + for (int i = 0; i < 100; i++) { + + GLuint projId = glGetUniformLocation(progId, "projection"); + glm::mat4 proj = glm::perspective(glm::radians(45.f), 1.33f, 0.01f, 100.f); + glUniformMatrix4fv(projId, 1, GL_FALSE, glm::value_ptr(proj)); + + GLuint viewId = glGetUniformLocation(progId, "view"); + glm::mat4 view = glm::lookAt(camPos, camPos + camFront, camUp); + glUniformMatrix4fv(viewId, 1, GL_FALSE, glm::value_ptr(view)); + + GLuint modelId = glGetUniformLocation(progId, "model"); + float d = (float)glutGet(GLUT_ELAPSED_TIME) * 0.001f; + glm::mat4 model = glm::mat4(1.f); + + model = glm::translate(model, glm::vec3(sin(i * 30) * 2, cos(i * 30) * 2, i * 2)); + + if (doRotate) { + model = glm::rotate(model, d * glm::radians(30.f), glm::vec3(0.f, 1.f, 0.f)); + model = glm::rotate(model, d * glm::radians(20.f), glm::vec3(1.f, 0.f, 0.f)); + } + + if (doScale) + model = glm::scale(model, glm::vec3(1.f, 0.3f + 0.7f * (1 + sin(d * (i + 3))), 1.f)); + + if (doTranslate) + model = glm::translate(model, glm::vec3(sin(d), cos(d), sin(d))); + + + glUniformMatrix4fv(modelId, 1, GL_FALSE, glm::value_ptr(model)); + + glDrawArrays(GL_TRIANGLES, 0, 12); + } glutSwapBuffers(); } @@ -30,7 +77,8 @@ 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); @@ -45,11 +93,11 @@ void attachShader(GLuint progId, const char* filePath, GLenum type) { 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; @@ -61,68 +109,62 @@ GLuint compileShaders() { 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, + + 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 = 12; - GLuint VBO; - glGenBuffers(1, &VBO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, numVerts * 7 * sizeof(GLfloat), NULL, GL_STATIC_DRAW); + GLuint vbo; + glGenBuffers(1, &vbo); + + 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(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; @@ -135,17 +177,109 @@ void init() { } } +void init() { + GLfloat vertices[9*4] = { + -1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + 0.0f, 1.0f, 0.0f, + + -1.0f, -1.0f, 1.0f, + 1.0f, -1.0f, 1.0f, + 0.0f, 1.0f, 0.0f, + + -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, 1.0f, + 0.0f, 1.0f, 0.0f, + + 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, 1.0f, + 0.0f, 1.0f, 0.0f + + }; + + vaos = new GLuint[2]; + + progId = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl"); + glUseProgram(progId); + vaos[0] = setupBuffers(vertices, progId); + validateProgram(progId); + + glEnable(GL_DEPTH_TEST); +} + +void keyboard(unsigned char key, int x, int y) { + if (key == 'w') + camPos.z += 0.1f; + if (key == 's') + camPos.z -= 0.1f; + if (key == 'a') + camPos.x += 0.1f; + if (key == 'd') + camPos.x -= 0.1f; + if (key == 'q') + camPos.y += 0.1f; + if (key == 'e') + camPos.y -= 0.1f; + if (key == 'z') + doScale = !doScale; + if (key == 'x') + doRotate = !doRotate; + if (key == 'c') + doTranslate = !doTranslate; + glutPostRedisplay(); +} + +void idle(int _) { + glutPostRedisplay(); + glutTimerFunc(16, idle, 0); +} + +int prevMouseX, prevMouseY; +bool firstMouse = true; + +void motion(int x, int y) { + if (firstMouse) { + prevMouseX = x; + prevMouseY = y; + firstMouse = false; + } + int dx = x - prevMouseX, dy = y - prevMouseY; + + prevMouseX = x; + prevMouseY = y; + + const float sensitivity = 0.005f; + yaw += dx * sensitivity; + pitch -= dy * sensitivity; + + glm::vec3 front; + front.x = cos(pitch) * cos(yaw); + front.y = sin(pitch); + front.z = cos(pitch) * sin(yaw); + camFront = glm::normalize(front); +} + +void mouse(int button, int state, int x, int y) { + if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) + firstMouse = true; +} + int main(int argc, char** argv) { glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE); + glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE); glutInitWindowSize(800, 600); - glutCreateWindow("Hello Triangle"); + int win = glutCreateWindow("Hello Triangle"); glutDisplayFunc(display); glewInit(); init(); + glutKeyboardFunc(keyboard); + glutTimerFunc(16, idle, 0); + glutMotionFunc(motion); + glutMouseFunc(mouse); + glutMainLoop(); return 0;