Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/camera.cc22
-rw-r--r--src/render/camera.h21
-rw-r--r--src/render/draw.cc5
-rw-r--r--src/render/render.cc207
-rw-r--r--src/render/render.h3
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;