const char* editpane(int x, int y, int width, int height, char* text, int maxlen, int fg, int bg) { if(kb_buf) { if(kb_buf==27) return text; // ESC if(kb_buf=='\b') { text[strlen(text)-1]=0; kb_buf=0; } else if(strlen(text)<(maxlen-2)) { text[strlen(text)+1]='\0'; text[strlen(text)]=kb_buf; kb_buf=0; } else puts("\a"); // bell } text[strlen(text)+1]=0; text[strlen(text)]=15; // input cursor shadowbox(x, y, width, height, text, fg, bg); text[strlen(text)-1]=0; return 0; }
void GraphicsGL2::SetupScene( float fov, float new_view_distance, const Vec3 cam_position, const Quat & cam_rotation, const Vec3 & dynamic_reflection_sample_pos) { // setup the default camera from the passed-in parameters { GraphicsCamera & cam = cameras["default"]; cam.fov = fov; cam.pos = cam_position; cam.orient = cam_rotation; cam.view_distance = new_view_distance; cam.w = w; cam.h = h; } // create a camera for the skybox with a long view distance { GraphicsCamera & cam = cameras["skybox"]; cam = cameras["default"]; cam.view_distance = 10000; cam.pos = Vec3(0); } // create a camera for the dynamic reflections { GraphicsCamera & cam = cameras["dynamic_reflection"]; cam.pos = dynamic_reflection_sample_pos; cam.fov = 90; // this gets automatically overridden with the correct fov (which is 90 anyway) cam.orient.LoadIdentity(); // this gets automatically rotated for each cube side cam.view_distance = 100; cam.w = 1; // this gets automatically overridden with the cubemap dimensions cam.h = 1; // this gets automatically overridden with the cubemap dimensions } // create a camera for the dynamic reflection skybox { GraphicsCamera & cam = cameras["dynamic_reflection_skybox"]; cam = cameras["dynamic_reflection"]; cam.view_distance = 10000; cam.pos = Vec3(0); } // create an ortho camera for 2d drawing { GraphicsCamera & cam = cameras["2d"]; // this is the glOrtho call we want: glOrtho( 0, 1, 1, 0, -1, 1 ); cam.orthomode = true; cam.orthomin = Vec3(0, 1, -1); cam.orthomax = Vec3(1, 0, 1); } // put the default camera transform into texture3, needed by shaders only Mat4 viewMatrix; cam_rotation.GetMatrix4(viewMatrix); float translate[4] = {-cam_position[0], -cam_position[1], -cam_position[2], 0}; viewMatrix.MultiplyVector4(translate); viewMatrix.Translate(translate[0], translate[1], translate[2]); glMatrixMode(GL_TEXTURE); glActiveTexture(GL_TEXTURE3); glLoadMatrixf(viewMatrix.GetArray()); // create cameras for shadow passes if (shadows) { Mat4 viewMatrixInv = viewMatrix.Inverse(); // derive light rotation quaternion from light direction vector Quat light_rotation; Vec3 up(0, 0, 1); float cosa = up.dot(light_direction); if (cosa * cosa < 1.0f) { float a = -acosf(cosa); Vec3 x = up.cross(light_direction).Normalize(); light_rotation.SetAxisAngle(a, x[0], x[1], x[2]); } std::vector <std::string> shadow_names; shadow_names.push_back("near"); shadow_names.push_back("medium"); shadow_names.push_back("far"); for (int i = 0; i < 3; i++) { float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60 Vec3 shadowbox(1,1,1); shadowbox = shadowbox * (shadow_radius*sqrt(2.0)); Vec3 shadowoffset(0,0,-1); shadowoffset = shadowoffset * shadow_radius; (-cam_rotation).RotateVector(shadowoffset); shadowbox[2] += 60.0; GraphicsCamera & cam = cameras["shadows_"+shadow_names[i]]; cam = cameras["default"]; cam.orthomode = true; cam.orthomin = -shadowbox; cam.orthomax = shadowbox; cam.pos = cam.pos + shadowoffset; cam.orient = light_rotation; // go through and extract the clip matrix, storing it in a texture matrix // premultiply the clip matrix with default camera view inverse matrix renderscene.SetOrtho(cam.orthomin, cam.orthomax); renderscene.SetCameraInfo(cam.pos, cam.orient, cam.fov, cam.view_distance, cam.w, cam.h); Mat4 clipmat; clipmat.Scale(0.5f); clipmat.Translate(0.5f, 0.5f, 0.5f); clipmat = renderscene.GetProjMatrix().Multiply(clipmat); clipmat = renderscene.GetViewMatrix().Multiply(clipmat); clipmat = viewMatrixInv.Multiply(clipmat); glActiveTexture(GL_TEXTURE4+i); glLoadMatrixf(clipmat.GetArray()); } } glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_MODELVIEW); }
void GraphicsGL3::SetupScene( float fov, float new_view_distance, const Vec3 cam_position, const Quat & cam_rotation, const Vec3 & /*dynamic_reflection_sample_pos*/, std::ostream & error_output) { lastCameraPosition = cam_position; const float nearDistance = 0.1; setCameraPerspective("default", cam_position, cam_rotation, fov, nearDistance, new_view_distance, w, h); Vec3 skyboxCamPosition(0,0,0); if (fixed_skybox) skyboxCamPosition[2] = cam_position[2]; setCameraPerspective("skybox", skyboxCamPosition, cam_rotation, fov, nearDistance, 10000.f, w, h); // derive light rotation quaternion from light direction vector Quat light_rotation; Vec3 up(0, 0, 1); float cosa = up.dot(light_direction); if (cosa * cosa < 1.0f) { float a = -acosf(cosa); Vec3 x = up.cross(light_direction).Normalize(); light_rotation.SetAxisAngle(a, x[0], x[1], x[2]); } // shadow cameras for (int i = 0; i < 3; i++) { //float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60 float shadow_radius = (1<<(2-i))*closeshadow+(2-i)*20.0; Vec3 shadowbox(1,1,1); //shadowbox = shadowbox * (shadow_radius*sqrt(2.0)); shadowbox = shadowbox * (shadow_radius*1.5); Vec3 shadowoffset(0,0,-1); shadowoffset = shadowoffset * shadow_radius; (-cam_rotation).RotateVector(shadowoffset); if (i == 2) shadowbox[2] += 25.0; Vec3 shadowPosition = cam_position+shadowoffset; // snap the shadow camera's location to shadow map texels // this can be commented out to minimize car aliasing at the expense of scenery aliasing const float shadowMapResolution = 512; float snapToGridSize = 2.f*shadowbox[0]/shadowMapResolution; Vec3 cameraSpaceShadowPosition = shadowPosition; light_rotation.RotateVector(cameraSpaceShadowPosition); for (int n = 0; n < 3; n++) { float pos = cameraSpaceShadowPosition[n]; float gridpos = pos / snapToGridSize; gridpos = floor(gridpos); cameraSpaceShadowPosition[n] = gridpos*snapToGridSize; } (-light_rotation).RotateVector(cameraSpaceShadowPosition); shadowPosition = cameraSpaceShadowPosition; std::string suffix = Utils::tostr(i+1); CameraMatrices & shadowcam = setCameraOrthographic("shadow"+suffix, shadowPosition, light_rotation, -shadowbox, shadowbox); std::string matrixName = "shadowMatrix"; // create and send shadow reconstruction matrices // the reconstruction matrix should transform from view to world, then from world to shadow view, then from shadow view to shadow clip space const CameraMatrices & defaultcam = cameras.find("default")->second; Mat4 shadowReconstruction = defaultcam.inverseViewMatrix.Multiply(shadowcam.viewMatrix).Multiply(shadowcam.projectionMatrix); /*//Mat4 shadowReconstruction = shadowcam.projectionMatrix.Multiply(shadowcam.viewMatrix.Multiply(defaultcam.inverseViewMatrix)); std::cout << "shadowcam.projectionMatrix: " << std::endl; shadowcam.projectionMatrix.DebugPrint(std::cout); std::cout << "defaultcam.inverseViewMatrix: " << std::endl; defaultcam.inverseViewMatrix.DebugPrint(std::cout); std::cout << "shadowcam.viewMatrix: " << std::endl; shadowcam.viewMatrix.DebugPrint(std::cout); std::cout << "defaultcam.inverseViewMatrix.Multiply(shadowcam.viewMatrix): " << std::endl; defaultcam.inverseViewMatrix.Multiply(shadowcam.viewMatrix).DebugPrint(std::cout); std::cout << matrixName << ":" << std::endl; shadowReconstruction.DebugPrint(std::cout);*/ //renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId(matrixName), shadowReconstruction.GetArray(),16)); // examine the user-defined fields to find out which shadow matrix to send to a pass std::vector <StringId> passes = renderer.getPassNames(); for (std::vector <StringId>::const_iterator i = passes.begin(); i != passes.end(); i++) { std::map <std::string, std::string> fields = renderer.getUserDefinedFields(*i); std::map <std::string, std::string>::const_iterator field = fields.find(matrixName); if (field != fields.end() && field->second == suffix) { renderer.setPassUniform(*i, RenderUniformEntry(stringMap.addStringId(matrixName), shadowReconstruction.GetArray(),16)); } } } // send cameras to passes for (std::map <std::string, std::string>::const_iterator i = passNameToCameraName.begin(); i != passNameToCameraName.end(); i++) { renderer.setPassUniform(stringMap.addStringId(i->first), RenderUniformEntry(stringMap.addStringId("viewMatrix"), cameras[i->second].viewMatrix.GetArray(),16)); renderer.setPassUniform(stringMap.addStringId(i->first), RenderUniformEntry(stringMap.addStringId("projectionMatrix"), cameras[i->second].projectionMatrix.GetArray(),16)); } // send matrices for the default camera const CameraMatrices & defaultCamera = cameras.find("default")->second; renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("invProjectionMatrix"), defaultCamera.inverseProjectionMatrix.GetArray(),16)); renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("invViewMatrix"), defaultCamera.inverseViewMatrix.GetArray(),16)); renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("defaultViewMatrix"), defaultCamera.viewMatrix.GetArray(),16)); renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("defaultProjectionMatrix"), defaultCamera.projectionMatrix.GetArray(),16)); // send sun light direction for the default camera // transform to eyespace (view space) MathVector <float, 4> lightDirection4; for (int i = 0; i < 3; i++) lightDirection4[i] = light_direction[i]; lightDirection4[3] = 0; defaultCamera.viewMatrix.MultiplyVector4(&lightDirection4[0]); // upload to the shaders RenderUniformEntry lightDirectionUniform(stringMap.addStringId("eyespaceLightDirection"), &lightDirection4[0], 3); renderer.setGlobalUniform(lightDirectionUniform); // set the reflection strength // TODO: read this from the track definition float reflectedLightColor[4]; for (int i = 0; i < 3; i++) reflectedLightColor[i] = 0.5; reflectedLightColor[3] = 1.; renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("reflectedLightColor"), reflectedLightColor, 4)); // set the ambient strength // TODO: read this from the track definition float ambientLightColor[4]; for (int i = 0; i < 3; i++) ambientLightColor[i] = 1.56; ambientLightColor[3] = 1.; renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("ambientLightColor"), ambientLightColor, 4)); // set the sun strength // TODO: read this from the track definition float directionalLightColor[4]; for (int i = 0; i < 3; i++) directionalLightColor[i] = 8.3; directionalLightColor[3] = 1.; renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("directionalLightColor"), directionalLightColor, 4)); AssembleDrawMap(error_output); }
void GRAPHICS_GL2::SetupScene( float fov, float new_view_distance, const MATHVECTOR <float, 3> cam_position, const QUATERNION <float> & cam_rotation, const MATHVECTOR <float, 3> & dynamic_reflection_sample_pos) { // setup the default camera from the passed-in parameters { GRAPHICS_CAMERA & cam = cameras["default"]; cam.fov = fov; cam.pos = cam_position; cam.orient = cam_rotation; cam.view_distance = new_view_distance; cam.w = w; cam.h = h; } // create a camera for the skybox with a long view distance { GRAPHICS_CAMERA & cam = cameras["skybox"]; cam = cameras["default"]; cam.view_distance = 10000.0; } // create a camera for 3d ui elements that has a fixed FOV { GRAPHICS_CAMERA & cam = cameras["ui3d"]; cam.fov = 45; cam.pos = cam_position; cam.orient = cam_rotation; cam.view_distance = new_view_distance; cam.w = w; cam.h = h; } // create a camera for the dynamic reflections { GRAPHICS_CAMERA & cam = cameras["dynamic_reflection"]; cam.pos = dynamic_reflection_sample_pos; cam.fov = 90; // this gets automatically overridden with the correct fov (which is 90 anyway) cam.orient.LoadIdentity(); // this gets automatically rotated for each cube side cam.view_distance = 100.f; cam.w = 1.f; // this gets automatically overridden with the cubemap dimensions cam.h = 1.f; // this gets automatically overridden with the cubemap dimensions } // create a camera for the dynamic reflection skybox { GRAPHICS_CAMERA & cam = cameras["dynamic_reflection_skybox"]; cam = cameras["dynamic_reflection"]; cam.view_distance = 10000.f; } // create an ortho camera for 2d drawing { GRAPHICS_CAMERA & cam = cameras["2d"]; // this is the glOrtho call we want: glOrtho( 0, 1, 1, 0, -1, 1 ); cam.orthomode = true; cam.orthomin = MATHVECTOR <float, 3> (0, 1, -1); cam.orthomax = MATHVECTOR <float, 3> (1, 0, 1); } // put the default camera transform into texture3, needed by shaders only MATRIX4<float> viewMatrix; cam_rotation.GetMatrix4(viewMatrix); float translate[4] = {-cam_position[0], -cam_position[1], -cam_position[2], 0}; viewMatrix.MultiplyVector4(translate); viewMatrix.Translate(translate[0], translate[1], translate[2]); glActiveTexture(GL_TEXTURE3); glMatrixMode(GL_TEXTURE); glLoadMatrixf(viewMatrix.GetArray()); // create cameras for shadow passes if (shadows) { MATRIX4<float> viewMatrixInv = viewMatrix.Inverse(); std::vector <std::string> shadow_names; shadow_names.push_back("near"); shadow_names.push_back("medium"); shadow_names.push_back("far"); for (int i = 0; i < 3; i++) { float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60 MATHVECTOR <float, 3> shadowbox(1,1,1); shadowbox = shadowbox * (shadow_radius*sqrt(2.0)); MATHVECTOR <float, 3> shadowoffset(0,0,-1); shadowoffset = shadowoffset * shadow_radius; (-cam_rotation).RotateVector(shadowoffset); shadowbox[2] += 60.0; GRAPHICS_CAMERA & cam = cameras["shadows_"+shadow_names[i]]; cam = cameras["default"]; cam.orthomode = true; cam.orthomin = -shadowbox; cam.orthomax = shadowbox; cam.pos = cam.pos + shadowoffset; cam.orient = lightdirection; // go through and extract the clip matrix, storing it in a texture matrix // premultiply the clip matrix with default camera view inverse matrix renderscene.SetOrtho(cam.orthomin, cam.orthomax); renderscene.SetCameraInfo(cam.pos, cam.orient, cam.fov, cam.view_distance, cam.w, cam.h); MATRIX4<float> clipmat; clipmat.Scale(0.5f); clipmat.Translate(0.5f, 0.5f, 0.5f); clipmat = renderscene.GetProjMatrix().Multiply(clipmat); clipmat = renderscene.GetViewMatrix().Multiply(clipmat); clipmat = viewMatrixInv.Multiply(clipmat); glActiveTexture(GL_TEXTURE4+i); glLoadMatrixf(clipmat.GetArray()); } } glMatrixMode(GL_MODELVIEW); glActiveTexture(GL_TEXTURE0); }
void GraphicsGL2::SetupScene( float fov, float new_view_distance, const Vec3 cam_position, const Quat & cam_rotation, const Vec3 & dynamic_reflection_sample_pos, std::ostream & error_output) { // setup the default camera from the passed-in parameters { GraphicsCamera & cam = cameras["default"]; cam.fov = fov; cam.pos = cam_position; cam.rot = cam_rotation; cam.view_distance = new_view_distance; cam.w = w; cam.h = h; } // create a camera for the skybox with a long view distance { GraphicsCamera & cam = cameras["skybox"]; cam = cameras["default"]; cam.view_distance = 10000; cam.pos = Vec3(0); if (fixed_skybox) cam.pos[2] = cam_position[2]; } // create a camera for the dynamic reflections { GraphicsCamera & cam = cameras["dynamic_reflection"]; cam.pos = dynamic_reflection_sample_pos; cam.fov = 90; // this gets automatically overridden with the correct fov (which is 90 anyway) cam.rot.LoadIdentity(); // this gets automatically rotated for each cube side cam.view_distance = 100; cam.w = 1; // this gets automatically overridden with the cubemap dimensions cam.h = 1; // this gets automatically overridden with the cubemap dimensions } // create a camera for the dynamic reflection skybox { GraphicsCamera & cam = cameras["dynamic_reflection_skybox"]; cam = cameras["dynamic_reflection"]; cam.view_distance = 10000; cam.pos = Vec3(0); } // create an ortho camera for 2d drawing { GraphicsCamera & cam = cameras["2d"]; // this is the glOrtho call we want: glOrtho( 0, 1, 1, 0, -1, 1 ); cam.orthomode = true; cam.orthomin = Vec3(0, 1, -1); cam.orthomax = Vec3(1, 0, 1); } // create cameras for shadow passes if (shadows) { Mat4 view_matrix; cam_rotation.GetMatrix4(view_matrix); float translate[4] = {-cam_position[0], -cam_position[1], -cam_position[2], 0}; view_matrix.MultiplyVector4(translate); view_matrix.Translate(translate[0], translate[1], translate[2]); Mat4 view_matrix_inv = view_matrix.Inverse(); // derive light rotation quaternion from light direction vector Quat light_rotation; Vec3 up(0, 0, 1); float cosa = up.dot(light_direction); if (cosa * cosa < 1.0f) { float a = -acosf(cosa); Vec3 x = up.cross(light_direction).Normalize(); light_rotation.SetAxisAngle(a, x[0], x[1], x[2]); } std::vector <std::string> shadow_names; shadow_names.push_back("near"); shadow_names.push_back("medium"); shadow_names.push_back("far"); for (int i = 0; i < 3; i++) { float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60 Vec3 shadowbox(1,1,1); shadowbox = shadowbox * (shadow_radius*sqrt(2.0)); Vec3 shadowoffset(0,0,-1); shadowoffset = shadowoffset * shadow_radius; (-cam_rotation).RotateVector(shadowoffset); shadowbox[2] += 60.0; GraphicsCamera & cam = cameras["shadows_"+shadow_names[i]]; cam = cameras["default"]; cam.orthomode = true; cam.orthomin = -shadowbox; cam.orthomax = shadowbox; cam.pos = cam.pos + shadowoffset; cam.rot = light_rotation; // get camera clip matrix const Mat4 cam_proj_mat = GetProjMatrix(cam); const Mat4 cam_view_mat = GetViewMatrix(cam); Mat4 clip_matrix; clip_matrix.Scale(0.5f); clip_matrix.Translate(0.5f, 0.5f, 0.5f); clip_matrix = cam_proj_mat.Multiply(clip_matrix); clip_matrix = cam_view_mat.Multiply(clip_matrix); // premultiply the clip matrix with default camera view inverse matrix clip_matrix = view_matrix_inv.Multiply(clip_matrix); shadow_matrix[i] = clip_matrix; } assert(shadow_distance < 3); renderscene.SetShadowMatrix(shadow_matrix, shadow_distance + 1); postprocess.SetShadowMatrix(shadow_matrix, shadow_distance + 1); } else { renderscene.SetShadowMatrix(NULL, 0); postprocess.SetShadowMatrix(NULL, 0); } // sort the two dimentional drawlist so we get correct ordering std::sort(dynamic_drawlist.twodim.begin(), dynamic_drawlist.twodim.end(), &SortDraworder); // do fast culling queries for static geometry per pass ClearCulledDrawLists(); for (std::vector <GraphicsConfigPass>::const_iterator i = config.passes.begin(); i != config.passes.end(); i++) { CullScenePass(*i, error_output); } renderscene.SetFSAA(fsaa); renderscene.SetContrast(contrast); renderscene.SetSunDirection(light_direction); postprocess.SetContrast(contrast); postprocess.SetSunDirection(light_direction); }