void ArcballNavigation::updateArcball() { glm::vec3 va = getArcballVector(m_mouse_last); glm::vec3 vb = getArcballVector(m_mouse_cur); float angle = glm::acos(std::min(1.0f, glm::dot(va, vb))); glm::vec3 axis_in_camera_coord = glm::cross(va, vb); glm::mat3 camera2world = glm::mat3(glm::inverse(m_viewmatrix)); glm::vec3 axis_in_world_coord = camera2world * axis_in_camera_coord; m_viewmatrix = m_viewmatrix * glm::rotate(glm::degrees(angle), axis_in_world_coord); }
void assignment1_app::render(double currentTime) { const float f = (float)currentTime; glUseProgram(per_vertex ? per_vertex_program : per_fragment_program); #pragma region Calculations for mouse interaction camera rotation and translation matrix float fAngle = 0.0f; vmath::vec3 axis_in_camera_coord = (0.0f, 1.0f, 0.0f); if (iCurMouseX != iPrevMouseX || iCurMouseY != iPrevMouseY) { // Arcball Rotation if (bRotate) { vmath::vec3 va = getArcballVector(iPrevMouseX, iPrevMouseY); vmath::vec3 vb = getArcballVector(iCurMouseX, iCurMouseY); fAngle = acos(fmin(1.0f, vmath::dot(va, vb))); axis_in_camera_coord = vmath::cross(va, vb); axis_in_camera_coord = vmath::normalize(axis_in_camera_coord); iPrevMouseX = iCurMouseX; iPrevMouseY = iCurMouseY; rotationMatrix *= vmath::rotate(vmath::degrees(fAngle), axis_in_camera_coord); } // Zoom in and out if (bZoom) { fZpos += (iCurMouseY - iPrevMouseY); if (fZpos > 500) { fZpos = 500; } else if (fZpos < 10) { fZpos = 10; } iPrevMouseY = iCurMouseY; iPrevMouseX = iCurMouseX; } // Pan camera left, right, up, and down if (bPan) { fXpos += (iCurMouseX - iPrevMouseX); fYpos += (iCurMouseY - iPrevMouseY); iPrevMouseY = iCurMouseY; iPrevMouseX = iCurMouseX; translationMatrix = vmath::translate(fXpos / (info.windowWidth / fZpos), -fYpos / (info.windowWidth / fZpos), 0.0f); } //Light position tracks with the camera lightPos = vmath::vec4(iLightPosX * translationMatrix[0][0] + iLightPosX * translationMatrix[0][1] + iLightPosX * translationMatrix[0][2], iLightPosY * translationMatrix[1][0] + iLightPosY * translationMatrix[1][1] + iLightPosY * translationMatrix[1][2], iLightPosZ * translationMatrix[2][0] + iLightPosZ * translationMatrix[2][1] + iLightPosZ * translationMatrix[2][2], 1.0f ); lightPos = vmath::vec4(lightPos[0] * rotationMatrix[0][0] + lightPos[0] * rotationMatrix[0][1] + lightPos[0] * rotationMatrix[0][2], lightPos[1] * rotationMatrix[1][0] + lightPos[1] * rotationMatrix[1][1] + lightPos[1] * rotationMatrix[1][2], lightPos[2] * rotationMatrix[2][0] + lightPos[2] * rotationMatrix[2][1] + lightPos[2] * rotationMatrix[2][2], 1.0f ); } #pragma endregion glViewport(0, 0, info.windowWidth, info.windowHeight); // Create sky blue background glClearBufferfv(GL_COLOR, 0, skyBlue); glClearBufferfv(GL_DEPTH, 0, ones); // Set up view and perspective matrix vmath::vec3 view_position = vmath::vec3(0.0f, 0.0f, fZpos); vmath::mat4 view_matrix = vmath::lookat(view_position, vmath::vec3(0.0f, 0.0f, 0.0f), vmath::vec3(0.0f, 1.0f, 0.0f)); view_matrix *= translationMatrix; view_matrix *= rotationMatrix; vmath::mat4 perspective_matrix = vmath::perspective(50.0f, (float)info.windowWidth / (float)info.windowHeight, 0.1f, 1000.0f); glUnmapBuffer(GL_UNIFORM_BUFFER); //release the mapping of a buffer object's data store into the client's address space glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer); uniforms_block * block = (uniforms_block *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(uniforms_block), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); #pragma region Uniforms that remain constant for all geometery block->proj_matrix = perspective_matrix; block->lightPos = lightPos; #pragma endregion #pragma region Draw Sphere glBindVertexArray(sphere_vao); glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer); block = (uniforms_block *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(uniforms_block), GL_MAP_WRITE_BIT); vmath::mat4 model_matrix = vmath::translate(-9.3f, -16.0f, 1.0f) * vmath::scale(6.0f); block->mv_matrix = view_matrix * model_matrix; block->view_matrix = view_matrix; block->uni_color = purple; block->useUniformColor = useUniformColor; block->invertNormals = falseVec; block->isSphere = trueVec; glCullFace(GL_BACK); object.render(); #pragma endregion glUnmapBuffer(GL_UNIFORM_BUFFER); //release the mapping of a buffer object's data store into the client's address space glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer); block = (uniforms_block *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(uniforms_block), GL_MAP_WRITE_BIT); #pragma region Uniforms that remain constant for cubes block->uni_color = orange; block->useUniformColor = falseVec; block->isSphere = falseVec; #pragma endregion #pragma region bind cube vertex data glBindVertexArray(cube_vao); glBindBuffer(GL_ARRAY_BUFFER, buffer); glEnableVertexAttribArray(0); //enable or disable a generic vertex attribute array glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); //define an array of generic vertex attribute data void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer); glEnableVertexAttribArray(1); //enable or disable a generic vertex attribute array glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); //define an array of generic vertex attribute data void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) glBindBuffer(GL_ARRAY_BUFFER, colorBuffer); glEnableVertexAttribArray(2); //enable or disable a generic vertex attribute array glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, 0); //define an array of generic vertex attribute data void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer); block = (uniforms_block *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(uniforms_block), GL_MAP_WRITE_BIT); #pragma endregion #pragma region Draw Room model_matrix = //vmath::rotate((float)currentTime * 14.5f, 0.0f, 1.0f, 0.0f) * //used to constantly rotate vmath::rotate(45.0f, 0.0f, 1.0f, 0.0f)* vmath::scale(22.0f); block->mv_matrix = view_matrix * model_matrix; block->view_matrix = view_matrix; block->invertNormals = falseVec; glCullFace(GL_FRONT); glDrawArrays(GL_TRIANGLES, 0, numberOfCubeVertices); #pragma endregion #pragma region Draw Cube glUnmapBuffer(GL_UNIFORM_BUFFER); //release the mapping of a buffer object's data store into the client's address space glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer); block = (uniforms_block *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(uniforms_block), GL_MAP_WRITE_BIT); model_matrix = vmath::rotate(0.0f, 0.0f, 1.0f, 0.0f) * vmath::translate(10.0f, -17.3f, -1.0f) * vmath::scale(5.0f); block->mv_matrix = view_matrix * model_matrix; block->view_matrix = view_matrix; block->useUniformColor = falseVec; block->invertNormals = trueVec; glCullFace(GL_BACK); glDrawArrays(GL_TRIANGLES, 0, numberOfCubeVertices); #pragma endregion }