int main(int argc, char** argv) { /* Initialize logging. */ START_EASYLOGGINGPP(argc, argv); LOG(TRACE) << "Logging initialized."; /* Initialize SDL. */ LOG(TRACE) << "Initializing SDL..."; int result = SDL_Init(SDL_INIT_VIDEO); if (result != 0) { LOG(FATAL) << "Could not initialize SDL: " << SDL_GetError(); } window = SDL_CreateWindow(argv[0], 0, 0, (int)window_width, (int)window_height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (window == nullptr) { LOG(FATAL) << "Could not create window: " << SDL_GetError(); } SDL_ShowCursor(SDL_DISABLE); SDL_SetRelativeMouseMode(SDL_TRUE); frequency = SDL_GetPerformanceFrequency(); time_last_frame = SDL_GetPerformanceCounter(); LOG(INFO) << "Performance counter frequency: " << frequency; /* Initialize OpenGL. */ LOG(TRACE) << "Initializing OpenGL..."; SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GLContext gl_context = SDL_GL_CreateContext(window); if (gl_context == nullptr) { LOG(FATAL) << SDL_GetError(); } glewExperimental = GL_TRUE; GLenum glewError = glewInit(); if (glewError != GLEW_OK) { LOG(FATAL) << "Could not initialize GLEW: " << glewGetErrorString(glewError); } glEnable(GL_BLEND); glEnable(GL_DEPTH_TEST); glEnable(GL_VERTEX_ARRAY); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); /* Load assets. */ LOG(TRACE) << "Loading assets..."; shaders = new ShaderManager(); { shader_terrain = shaders->get("terrain"); shader_terrain->apply(); glActiveTexture(GL_TEXTURE0); texture_terrain = new Texture("terrain"); shader_terrain->updateUniform("tex", 0); terrain = new Terrain("heightmap.png"); shader_terrain->updateUniform("max_height", terrain->getMaxHeight()); auto world = mat4(); world = translate(world, vec3(-terrain->getWidth() / 2.f, -terrain->getMaxHeight() / 2.f, -terrain->getDepth() / 2.f)); shader_terrain->updateUniform("K_a", 0.1f); shader_terrain->updateUniform("K_d", 0.9f); shader_terrain->updateWorldMatrix(world); LOG(INFO) << "Maximum terrain height: " << terrain->getMaxHeight(); LOG(INFO) << "Terrain width: " << terrain->getWidth(); LOG(INFO) << "Terrain depth: " << terrain->getDepth(); } { shader_skybox = shaders->get("skybox"); shader_skybox->apply(); glActiveTexture(GL_TEXTURE2); environment_map = new CubeMap("terrain_"); shader_skybox->updateUniform("cubeMap", 2); auto world = mat4(); world = scale(world, vec3(terrain->getWidth(), terrain->getWidth(), terrain->getDepth())); skybox = new Cube(); shader_terrain->apply(); shader_skybox->updateWorldMatrix(world); } { auto world = mat4(); world = scale(world, vec3(terrain->getWidth() / 2.f, terrain->getMaxHeight() * 2.f, terrain->getDepth() / 2.f)); shader_colour = shaders->get("colour"); shader_colour->apply(); shader_colour->updateWorldMatrix(world); origin = new Origin(); } { auto world = mat4(); world = translate(world, vec3(-terrain->getWidth() / 2.f, -terrain->getMaxHeight() / 2.f + 25.f, -terrain->getDepth() / 2.f)); shader_water = shaders->get("water"); shader_water->apply(); shader_water->updateUniform("K_a", 0.1f); shader_water->updateUniform("K_d", 0.0f); shader_water->updateUniform("K_s", 0.9f); shader_water->updateWorldMatrix(world); water = new Grid(terrain->getDepth(), 1000.f); } /* Set up light. */ auto light = Camera(); light.eye = vec3(1024.0f, 1024.f, 1024.f); light.at = vec3(0.0f, 0.0f, 0.0f); light.up = vec3(0.0f, 0.0f, -1.0f); auto light_dir = normalize(vec3(0.f, 0.25f, -1.f)); shader_terrain->apply(); shader_terrain->updateUniform("light_dir", light_dir); shader_water->apply(); shader_water->updateUniform("light_dir", light_dir); /* Set up view. */ auto camera = Camera(); auto camera_height = terrain->getMaxHeight() * 3.f; camera.eye = glm::vec3(0.f, camera_height, -terrain->getDepth() / 2.f); camera.at = glm::vec3(0, 0, 0); camera.up = glm::vec3(0, 1, 0); auto view = glm::lookAt(camera.eye, camera.at, camera.up); shaders->updateViewMatrices(view); /* Set up projection. */ auto proj = glm::perspective(45.f, window_width / window_height, 100.f, 25000.f); shaders->updateProjectionMatrices(proj); /* Set up frame buffers. */ frame_buffer_color = new ColorFrameBuffer(window_width, window_height); /* Main loop. */ float angle = 0.0f; bool done = false; SDL_Event event; LOG(TRACE) << "Entering main loop..."; while (!done) { while (SDL_PollEvent(&event) != 0) { if (event.type == SDL_QUIT) { done = true; } else if (event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { case SDLK_ESCAPE: LOG(INFO) << "Exiting normally at user request..."; done = true; break; case SDLK_PRINTSCREEN: LOG(INFO) << "Rendering screen shot..."; frame_buffer_color->bind(); draw(); frame_buffer_color->write(); frame_buffer_color->unbind(); break; default: break; } } else if (event.type == SDL_MOUSEMOTION) { const GLfloat X_SCALED = -(GLfloat)event.motion.xrel / window_width; const GLfloat Y_SCALED = -(GLfloat)event.motion.yrel / window_height; const GLfloat LEFT_RIGHT_ROT = X_SCALED * ANGLE_DELTA; const GLfloat UP_DOWN_ROT = Y_SCALED * ANGLE_DELTA; vec3 tempD(camera.at - camera.eye); vec4 d(tempD.x, tempD.y, tempD.z, 0.0f); vec3 right = cross(tempD, camera.up); mat4 rot; rot = rotate(rot, UP_DOWN_ROT, right); rot = rotate(rot, LEFT_RIGHT_ROT, camera.up); d = rot * d; camera.at.x = camera.eye.x + d.x; camera.at.y = camera.eye.y + d.y; camera.at.z = camera.eye.z + d.z; } } glm::vec3 direction = STEP * glm::normalize(camera.at - camera.eye); glm::vec3 right = STEP * glm::normalize(glm::cross(direction, camera.up)); auto keys = SDL_GetKeyboardState(nullptr); if (keys[SDL_SCANCODE_W]) { camera.eye += direction; camera.at += direction; } if (keys[SDL_SCANCODE_S]) { camera.eye -= direction; camera.at -= direction; } if (keys[SDL_SCANCODE_D]) { camera.eye += right; camera.at += right; } if (keys[SDL_SCANCODE_A]) { camera.eye -= right; camera.at -= right; } if (keys[SDL_SCANCODE_SPACE]) { camera.eye += STEP * camera.up; camera.at += STEP * camera.up; } if (keys[SDL_SCANCODE_LCTRL]) { camera.eye -= STEP * camera.up; camera.at -= STEP * camera.up; } view = glm::lookAt(camera.eye, camera.at, camera.up); shaders->updateViewMatrices(view); draw(); angle += 0.01f; } delete shaders; delete environment_map; delete frame_buffer_color; SDL_DestroyWindow(window); SDL_Quit(); return 0; }
bool loadMap(const char* filename, list<ExportObject> &map) { FILE * file = fopen(filename, "r"); if (NULL == file) { fprintf(stderr, "Couldn't open %s for reading the map\n", filename); return false; } int num_objs = 0; fscanf(file, "%d ", &num_objs); list<ExportObject>::iterator it; ExportObject reconstructedObject; char name[100]; int matnum; mat4 rotmat; while (num_objs--) { fscanf(file, "%s %d\n", name, &matnum); read3f(reconstructedObject.t, file); printf("read t:\n"); fprint3f(reconstructedObject.t, stdout); read3f(reconstructedObject.s, file); printf("read s:\n"); fprint3f(reconstructedObject.s, stdout); read3f(reconstructedObject.r, file); printf("read r:\n"); fprint3f(reconstructedObject.r, stdout); reconstructedObject.materialIndex = matnum; reconstructedObject.name = name; reconstructedObject.xt = scale(mat4(1.0), reconstructedObject.s) * translate(mat4(1.0), reconstructedObject.t); map.push_back(reconstructedObject); } /* with mats while (num_objs--) { fscanf(file, "%s %d\n", name, &matnum); readMat4(reconstructedObject.xt, file); printf("read mat4\n"); printMat4(reconstructedObject.xt, stdout); reconstructedObject.materialIndex = matnum; reconstructedObject.name = name; map.push_back(reconstructedObject); } */ fclose(file); return true; }
/// <summary> /// Adds a mirror box of a given size, centered at 0, with no back. /// </summary> /// <param name="wallSize">Size of the walls.</param> void Scene::addMirrorBox(const float wallSize) { using glm::translate; using glm::scale; using glm::rotate; int matIdx = materialsVec.size(); materialsVec.push_back(Material(vec3(1.0f, 1.0f, 0.8f), 0.7f)); //white (+0) materialsVec.push_back(Material(vec3(1.0f, 0.0f, 0.0f), 0.7f)); //red (+1) materialsVec.push_back(Material(vec3(0.0f, 1.0f, 0.0f), 0.7f)); //green (+2) materialsVec.push_back(Material(vec3(1.0f, 1.0f, 1.0f))); //white light (+3) materialsVec.push_back(Material(vec3(0.0f, 0.0f, 0.0f), 0.0f, vec3(1, 1, 1), INFINITY, .9f, 5.8f)); //mirror (+4) materialsVec[matIdx + 4].flags |= MAT_FLAG_PURE_REFLECTION; materialsVec.push_back(Material(vec3(1.0f, 0.6f, 1.0f))); //violet light const float offset = wallSize / 2; const mat4 scaleToWall = scale(vec3(wallSize, wallSize, wallSize)); //floor mat4 trans = translate(vec3(0, -offset, -offset)) * rotate(-(glm::mediump_float)90, vec3(1, 0, 0)) * scaleToWall; addRectangularModel(trans, matIdx); //ceiling trans = translate(vec3(0, offset, -offset)) * rotate((glm::mediump_float)90, vec3(1, 0, 0)) * scaleToWall; addRectangularModel(trans, matIdx + 4); //left wall trans = translate(vec3(-offset + .2 * offset, 0, -offset)) * rotate((glm::mediump_float)88, vec3(0, 1, 0)) * scaleToWall; addRectangularModel(trans, matIdx + 4); //right wall trans = translate(vec3(offset, 0, -offset)) * rotate((glm::mediump_float) - 90, vec3(0, 1, 0)) * scaleToWall; addRectangularModel(trans, matIdx + 4); //back wall trans = translate(vec3(0, 0, -wallSize)) * // rotate((glm::mediump_float)90, vec3(1, 0, 0)) * scaleToWall; addRectangularModel(trans, matIdx); //front wall s trans = translate(vec3(0, 0, 0)) * rotate((glm::mediump_float)180, vec3(0, 1, 0)) * scaleToWall; addRectangularModel(trans, matIdx); //light float power = 400; trans = translate(vec3(0, offset - 0.01f, -offset)) * rotate((glm::mediump_float) 90, vec3(1, 0, 0)) * scale(vec3(2.5f, 2.5f, 2.5f)); addAreaLight(trans, matIdx + 3, vec3(power / 4, power, power)); trans = translate(vec3(0, -offset + 0.01f, -offset)) * rotate((glm::mediump_float) -90, vec3(1, 0, 0)) * scale(vec3(1.5f, 1.5f, 1.5f)); addAreaLight(trans, matIdx + 5, vec3(power / 3, 0, power / 3)); }