Question: add the following functionalities to the engine: 1. Make all boxes move up and down (oscillate) and rotate in place at all times. Let the
add the following functionalities to the engine:
1. Make all boxes move up and down (oscillate) and rotate in place at all times. Let the oscillation domain to be 0.5 unit.
2. By pressing B, the player will have a view of his back. Notice that the player can keep moving forward when look back is activated. Pressing B one more time will change the view to forward (deactivate the look back). Also, do NOT change the camera view instantly, instead, create a smooth rotation of the camera with time.
3. Oscillate the camera up and down as the player takes steps in the world (WASD) just to make the walking action to look more realistic.
Code:
using namespace std;
#include "vgl.h" #include "LoadShaders.h" #include "glm\glm.hpp" #include "glm\gtc\matrix_transform.hpp" #include "glm\gtx otate_vector.hpp" #include
enum VAO_IDs { Triangles, NumVAOs }; enum Buffer_IDs { ArrayBuffer, NumBuffers }; enum Attrib_IDs { vPosition = 0 };
GLuint VAOs[NumVAOs]; GLuint Buffers[NumBuffers]; GLuint location; GLuint cam_mat_location; GLuint proj_mat_location;
const GLuint NumVertices = 16;
//Player motion speed and key controls float height = 0.8f; float yaw_speed = 0.1f; float travel_speed = 60.0f; float mouse_sensitivity = 0.01f;
//Used for tracking mouse cursor position on screen int x0 = 0; int y_0 = 0;
//Transformation matrices and camera vectors glm::mat4 model_view; glm::vec3 cam_pos = glm::vec3(0.0f, 0.0f, height); glm::vec3 forward_vector = glm::vec3(1, 1, 0); glm::vec3 up_vector = glm::vec3(0, 0, 1); glm::vec3 side_vector = glm::cross(up_vector, forward_vector);
//Used to measure time between two frames int oldTimeSinceStart = 0; int deltaTime;
//Creating and rendering bunch of objects on the scene to interact with const int Num_Obstacles = 100; float obstacle_data[Num_Obstacles][3];
//Helper function to generate a random float number within a range float randomFloat(float a, float b) { float random = ((float)rand()) / (float)RAND_MAX; float diff = b - a; float r = random * diff; return a + r; }
// inititializing buffers, coordinates, setting up pipeline, etc. void init(void) { glEnable(GL_DEPTH_TEST);
//Randomizing the position and scale of obstacles for (int i = 0; i < Num_Obstacles; i++) { obstacle_data[i][0] = randomFloat(-50, 50); //X obstacle_data[i][1] = randomFloat(-50, 50); //Y obstacle_data[i][2] = randomFloat(0.1, 10.0); //Scale }
ShaderInfo shaders[] = { { GL_VERTEX_SHADER, "triangles.vert" }, { GL_FRAGMENT_SHADER, "triangles.frag" }, { GL_NONE, NULL } };
GLuint program = LoadShaders(shaders); glUseProgram(program); //My Pipeline is set up
GLfloat vertices[NumVertices][3] = { { -0.45, -0.45 ,0.45 }, // Cube { 0.45, -0.45 ,0.45 }, { 0.45, 0.45 ,0.45 }, { -0.45, 0.45 ,0.45 }, { -0.45, -0.45 ,-0.45 }, { 0.45, -0.45 ,-0.45 }, { 0.45, 0.45 ,-0.45 }, { -0.45, 0.45 ,-0.45 },
{ -100.0, -100.0, 0.0 }, //Plane to walk on and a sky { 100.0, -100.0, 0.0 }, { 100.0, 100.0, 0.0 }, { -100.0, 100.0, 0.0 }, { -100.0, -100.0, 10.0 }, { 100.0, -100.0, 10.0 }, { 100.0, 100.0, 10.0 }, { -100.0, 100.0, 10.0 }
};
GLfloat colorData[NumVertices][3] = { { 0,1,1 }, // color for cube vertices { 1,1,0 }, { 1,0,0 }, { 0,1,0 }, { 0,1,0 }, { 0,0,1 }, { 1,1,1 }, { 1,0,1 },
{ 0,1,0 }, // color for plane vertices { 0,1,0 }, { 0,1,0 }, { 0,1,0 }, { 0,0,1 }, { 0,0,1 }, { 0,0,1 }, { 0,0,1 }
};
glGenBuffers(2, Buffers); glBindBuffer(GL_ARRAY_BUFFER, Buffers[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindAttribLocation(program, 0, "vPosition"); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW); glBindAttribLocation(program, 1, "vertexColor"); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(1);
location = glGetUniformLocation(program, "model_matrix"); cam_mat_location = glGetUniformLocation(program, "camera_matrix"); proj_mat_location = glGetUniformLocation(program, "projection_matrix"); }
//Helper function to draw a cube void drawCube(float scale) { GLubyte top_face[] = { 0, 1, 2, 3 }; GLubyte bottom_face[] = { 4, 5, 6, 7 }; GLubyte left_face[] = { 0, 4, 7, 3 }; GLubyte right_face[] = { 1, 5, 6, 2 }; GLubyte front_face[] = { 2, 3, 7, 6 }; GLubyte back_face[] = { 2, 3, 7, 6 }; model_view = glm::scale(model_view, glm::vec3(scale, scale, scale)); glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, top_face); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, bottom_face); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, left_face); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, right_face); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, front_face); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, back_face); }
//Renders level void draw_level() { //Drawing the floor and the sky GLubyte ground[] = { 8, 9, 10, 11 }; GLubyte sky[] = { 12, 13, 14, 15 }; glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, ground); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, sky);
//Rendering obstacles obstacles for (int i = 0; i < Num_Obstacles; i++) { model_view = glm::translate(model_view, glm::vec3(obstacle_data[i][0], obstacle_data[i][1], 0.0)); glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]); drawCube(obstacle_data[i][2]); model_view = glm::mat4(1.0); } }
//--------------------------------------------------------------------- // // display // void display(void) { int currentTime = glutGet(GLUT_ELAPSED_TIME); deltaTime = currentTime - oldTimeSinceStart; oldTimeSinceStart = currentTime;
// Clear the color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate the rotation angle based on the time float angle = currentTime * 0.01f;
// Calculate the sine of the time to oscillate the objects float offset = sin(currentTime * 0.002f) * 0.5f;
// Update the model-view matrix with rotation and translation model_view = glm::mat4(1.0f); model_view = glm::rotate(model_view, angle, up_vector); model_view = glm::translate(model_view, glm::vec3(0.0f, 0.0f, offset));
// Send the model-view and projection matrices to the shader program glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]); glUniformMatrix4fv(cam_mat_location, 1, GL_FALSE, &glm::lookAt(cam_pos, cam_pos + forward_vector, up_vector)[0][0]); glUniformMatrix4fv(proj_mat_location, 1, GL_FALSE, &glm::perspective(45.0f, 1.0f, 0.1f, 100.0f)[0][0]);
// Draw the cubes glBindVertexArray(VAOs[Triangles]); for (int i = 0; i < Num_Obstacles; i++) { model_view = glm::mat4(1.0f); model_view = glm::rotate(model_view, angle, up_vector); model_view = glm::translate(model_view, glm::vec3(obstacle_data[i][0], obstacle_data[i][1], offset)); model_view = glm::scale(model_view, glm::vec3(obstacle_data[i][2], obstacle_data[i][2], obstacle_data[i][2])); glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]); glDrawArrays(GL_TRIANGLE_FAN, 0, 8); }
// Swap the front and back frame buffers (double buffering) glutSwapBuffers(); }
void keyboard(unsigned char key, int x, int y) { if (key == 'a') { //Moving camera along opposit direction of side vector cam_pos += glm::cross(up_vector, forward_vector) * travel_speed * ((float)deltaTime) / 1000.0f; } if (key == 'd') { //Moving camera along side vector cam_pos -= glm::cross(up_vector, forward_vector) * travel_speed * ((float)deltaTime) / 1000.0f; } if (key == 'w') { //Moving camera along forward vector. To be more realistic, we use X=V.T equation in physics cam_pos += forward_vector * travel_speed * ((float)deltaTime) / 1000.0f; } if (key == 's') { //Moving camera along backward vector. To be more realistic, we use X=V.T equation in physics cam_pos -= forward_vector * travel_speed * ((float)deltaTime) / 1000.0f; } }
void mouse(int x, int y) { int delta_x = x - x0; forward_vector = glm::rotate(forward_vector, -delta_x * mouse_sensitivity, up_vector); side_vector = glm::cross(up_vector, forward_vector); //cout << x0 << " " << x << " " << delta_x << endl; x0 = x; }
void idle() { //Calculating the delta time between two frames //We will use this delta time when moving forward (in keyboard function) int timeSinceStart = glutGet(GLUT_ELAPSED_TIME); deltaTime = timeSinceStart - oldTimeSinceStart; oldTimeSinceStart = timeSinceStart; //cout << timeSinceStart << " " << oldTimeSinceStart << " " << deltaTime << endl; glutPostRedisplay(); }
//--------------------------------------------------------------------- // // main //
int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(1024, 1024); glutCreateWindow("Camera and Projection");
glewInit(); //Initializes the glew and prepares the drawing pipeline.
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glutPassiveMotionFunc(mouse);
glutMainLoop();
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
