diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/camera.cc | 22 | ||||
-rw-r--r-- | src/render/camera.h | 21 | ||||
-rw-r--r-- | src/render/draw.cc | 5 | ||||
-rw-r--r-- | src/render/render.cc | 207 | ||||
-rw-r--r-- | src/render/render.h | 3 |
5 files changed, 219 insertions, 39 deletions
diff --git a/src/render/camera.cc b/src/render/camera.cc index ae7cd43..108e4db 100644 --- a/src/render/camera.cc +++ b/src/render/camera.cc @@ -23,6 +23,9 @@ const float pitch_track = -15.0f; const float pitch_overview = -5.0f; float Camera::camera_aspect = 1.0f; +int Camera::camera_width = 0; +int Camera::camera_height = 0; + float Camera::camera_frustum_size = 0.5f; float Camera::camera_frustum_front = 1.0f; math::Vector3f Camera::camera_eye; @@ -45,6 +48,8 @@ float Camera::distance; void Camera::init() { camera_aspect = 1.0f; + camera_height = 0; + camera_width = 0; camera_frustum_size = 0.5f; camera_frustum_front = 1.0f; @@ -72,8 +77,10 @@ void Camera::shutdown() { } -void Camera::set_aspect(int width, int height) +void Camera::resize(int width, int height) { + camera_width = width; + camera_height = height; camera_aspect = (float) width / (float) height; } @@ -303,7 +310,7 @@ void Camera::frame(float seconds) camera_eye = camera_target - (distance * camera_axis.forward()); } -void Camera::draw() +void Camera::frustum() { // Change to the projection matrix and set our viewing volume large enough for the skysphere gl::matrixmode(GL_PROJECTION); @@ -325,6 +332,17 @@ void Camera::draw() gl::translate(-1.0f * camera_eye); } +void Camera::ortho() +{ + // switch to orthographic projection + gl::matrixmode(GL_PROJECTION); + gl::loadidentity(); + glOrtho(0, camera_width, camera_height, 0, -16.0f, 16.0f); + + gl::matrixmode(GL_MODELVIEW); + gl::loadidentity(); +} + void Camera::set_direction(float direction) { target_direction = direction; diff --git a/src/render/camera.h b/src/render/camera.h index db2db42..b19521e 100644 --- a/src/render/camera.h +++ b/src/render/camera.h @@ -46,8 +46,15 @@ public: /// progress the camera static void frame(float elapsed); - /// draw the OpenGL camera transformation - static void draw(); + /// enable frustum projection + /** The frustum projection is used to draw the world + */ + static void frustum(); + + /// enable orthographic projection + /** The ortographic projetion is used to draw the user interface + */ + static void ortho(); /// set target direction static void set_direction(float direction); @@ -64,8 +71,8 @@ public: /// set specified camera mode static void set_mode(Mode newmode); - /// set camera aspect ratio - static void set_aspect(int width, int height); + /// resize camera + static void resize(int width, int height); /// current frustum front static float frustum_front(); @@ -73,6 +80,10 @@ public: /// current frustum size (height); static float frustum_size(); + inline static int width() { return camera_width; } + + inline static int height() { return camera_height; } + private: static math::Vector3f camera_eye; static math::Vector3f camera_target; @@ -81,6 +92,8 @@ private: static float camera_aspect; static float camera_frustum_size; static float camera_frustum_front; + static int camera_width; + static int camera_height; // current and target yaw angle in XZ plane, positive is looking left static float direction_current; diff --git a/src/render/draw.cc b/src/render/draw.cc index 573587e..17c6fac 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -1024,11 +1024,6 @@ void draw_pass_spacegrid() void draw(float seconds) { zone = core::localplayer()->zone(); - if (!zone) - return; - - Camera::frame(seconds); - Camera::draw(); // draw the current camera transformation // calculate client state pass_prepare(seconds); diff --git a/src/render/render.cc b/src/render/render.cc index 3ba7e92..fbbaba1 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -9,15 +9,15 @@ #include <sstream> #include <iomanip> +#include "auxiliary/functions.h" +#include "core/core.h" +#include "filesystem/filesystem.h" +#include "model/model.h" #include "render/gl.h" #include "render/dust.h" #include "render/textures.h" #include "render/tga.h" #include "render/render.h" -#include "model/model.h" - -#include "core/core.h" -#include "filesystem/filesystem.h" #include "sys/sys.h" namespace render { @@ -28,6 +28,10 @@ core::Cvar *r_grid = 0; core::Cvar *r_radius = 0; core::Cvar *r_sky = 0; core::Cvar *r_wireframe = 0; +core::Cvar *screenshotformat = 0; +core::Cvar *screenshotquality = 0; + +int screenshot_number = 0; using model::VertexArray; VertexArray *vertexarray = 0; @@ -37,6 +41,62 @@ void func_list_textures(std::string const &args) Textures::list(); } +void reset_gl() +{ + // setup our viewport. + gl::viewport(0, 0, Camera::width(), Camera::height()); + + // set clear color + gl::clearcolor(0.0f, 0.0f, 0.0f, 1.0f); + + // load identity matrices + gl::matrixmode(GL_MODELVIEW); + gl::loadidentity(); + + gl::matrixmode(GL_MODELVIEW); + gl::loadidentity(); + + // shading model: Gouraud (smooth, the default) + gl::shademodel(GL_SMOOTH); + //gl::shademodel(GL_FLAT); + + // lighting settings for the default light GL_LIGHT0 + GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat ambient_light[] = { 0.01f, 0.01f, 0.01f, 1.0f }; + GLfloat diffuse_light[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + GLfloat specular_light[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + + glLightfv(GL_LIGHT0, GL_POSITION, light_position); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light); + + // GL_LIGHT0 is always enabled + gl::enable(GL_LIGHT0); + + // color tracking + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + + // material settings + GLfloat specular_reflectance[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + glMaterialfv(GL_FRONT, GL_SPECULAR, specular_reflectance); + glMateriali(GL_FRONT, GL_SHININESS, 128); // shininess 1-128 + + // alpha blending function + gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + gl::disable(GL_LIGHTING); + gl::disable(GL_COLOR_MATERIAL); + + gl::cullface(GL_BACK); + gl::frontface(GL_CCW); + gl::disable(GL_CULL_FACE); + gl::disable(GL_DEPTH_TEST); + gl::disable(GL_BLEND); + + gl::disable(GL_TEXTURE_2D); +} + void init() { con_print << "^BInitializing renderer..." << std::endl; @@ -72,6 +132,14 @@ void init() r_sky = core::Cvar::get("r_sky", "1", core::Cvar::Archive); r_sky->set_info("[bool] render the sky globe"); + screenshotformat = core::Cvar::get("screenshotformat", "jpg", core::Cvar::Archive); + screenshotformat->set_info("[string] screenshot format: jpg png tga"); + + screenshotquality = core::Cvar::get("screenshotquality", "85", core::Cvar::Archive); + screenshotquality->set_info("[int] screenshot jpg quality"); + + reset_gl(); + Camera::init(); Textures::init(); @@ -84,6 +152,32 @@ void init() func->set_info("list loaded textures"); } +// unload game assets (zone change) +void unload() +{ + // clear zone sky textures + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + core::Zone *zone = (*it).second; + if (zone->sky_texture()) { + render::Textures::unload(zone->sky_texture()); + zone->set_sky_texture(0); + } + } + + for (core::Entity::Registry::iterator it = core::Entity::registry().begin(); it != core::Entity::registry().end(); it++) { + core:: Entity *entity = (*it).second; + + if (entity->type() == core::Entity::Globe) { + core::EntityGlobe *globe = static_cast<core::EntityGlobe *>(entity); + if (globe->render_texture) { + render::Textures::unload(globe->render_texture); + globe->render_texture = 0; + } + } + } +} + +// clear all assets void clear() { // clear zone sky textures @@ -113,30 +207,7 @@ void clear() vertexarray = 0; } -void unload() -{ - // clear zone sky textures - for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { - core::Zone *zone = (*it).second; - if (zone->sky_texture()) { - render::Textures::unload(zone->sky_texture()); - zone->set_sky_texture(0); - } - } - - for (core::Entity::Registry::iterator it = core::Entity::registry().begin(); it != core::Entity::registry().end(); it++) { - core:: Entity *entity = (*it).second; - - if (entity->type() == core::Entity::Globe) { - core::EntityGlobe *globe = static_cast<core::EntityGlobe *>(entity); - if (globe->render_texture) { - render::Textures::unload(globe->render_texture); - globe->render_texture = 0; - } - } - } -} - +// reset render subsystem void reset() { clear(); @@ -151,6 +222,8 @@ void reset() (*r_arraysize) = (float) mb; vertexarray = new VertexArray(mb); + reset_gl(); + Dust::reset(); } void shutdown() @@ -170,5 +243,83 @@ void shutdown() Dust::shutdown(); } + +void screenshot() +{ + bool available = false; + std::string shortname; + std::string filename; + const int TYPETGA = 0; + const int TYPEPNG = 1; + const int TYPEJPG = 2; + int filetype = TYPETGA; + + // make sure the screenshots folder exists + filename.assign(filesystem::writedir()); + filename.append("screenshots/"); + sys::mkdir(filename); + + aux::lowercase(screenshotformat->str()); + + if ((screenshotformat->str().compare("jpg") == 0) || (screenshotformat->str().compare("jpeg") == 0)) { + filetype = TYPEJPG; + if (screenshotquality->value() < 10) { + (*screenshotquality) = 10; + } else if (screenshotquality->value() > 100) { + (*screenshotquality) = 100; + } + + } else if (screenshotformat->str().compare("png") == 0) { + filetype = TYPEPNG; + + } else if (screenshotformat->str().compare("tga") == 0) { + filetype = TYPETGA; + + } else { + filetype = TYPETGA; + (*screenshotformat) = "tga"; + } + + // find the first available screenshotxxxx + do { + std::stringstream nstr; + nstr << screenshot_number; + shortname.assign(nstr.str()); + + while(shortname.size() < 4) + shortname.insert(0, 1, '0'); + + shortname.insert(0, "screenshots/osirion"); + shortname.append("."); + shortname.append(screenshotformat->str()); + + filename.assign(filesystem::writedir()); + filename.append(shortname); + + FILE *handle = fopen(filename.c_str(), "r"); + if (handle) { + fclose(handle); + } else { + available = true; + } + screenshot_number++; + } while (!available); + + render::Image image(Camera::width(), Camera::height(), 3); + + glReadPixels(0, 0, (GLsizei) Camera::width(), (GLsizei) Camera::height(), + GL_RGB, GL_UNSIGNED_BYTE, (void *) image.data()); + + image.flip(); + + if (filetype == TYPEPNG) { + render::PNG::save(filename.c_str(), image); + } else if (filetype == TYPEJPG) { + render::JPG::save(filename.c_str(), image, (int) screenshotquality->value()); + } else if (filetype == TYPETGA) { + render::TGA::save(filename.c_str(), image); + } +} + } diff --git a/src/render/render.h b/src/render/render.h index 3faa097..cd90953 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -35,6 +35,9 @@ namespace render { /// unload game render data void unload(); + /// make a screenshot + void screenshot(); + extern core::Cvar *r_arraysize; extern core::Cvar *r_bbox; extern core::Cvar *r_grid; |