From 773c1bafe0f1d8b706e0f72e235f8466e7a9ccf5 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 11 Nov 2008 19:11:57 +0000 Subject: cleanups --- src/client/chat.cc | 7 + src/client/chat.h | 2 + src/client/client.cc | 4 +- src/client/input.cc | 22 +-- src/client/targets.cc | 5 +- src/client/video.cc | 7 +- src/client/view.cc | 96 ++++++------ src/dedicated/dedicated.cc | 4 +- src/render/Makefile.am | 4 +- src/render/camera.cc | 21 +-- src/render/camera.h | 13 -- src/render/gl.cc | 7 +- src/render/gl.h | 4 - src/render/render.cc | 214 +++++--------------------- src/render/render.h | 12 +- src/render/screenshot.cc | 109 ++++++++++++++ src/render/screenshot.h | 27 ++++ src/render/state.cc | 91 +++++++++++ src/render/state.h | 34 +++++ src/render/textures.cc | 3 +- src/render/tga.cc | 367 --------------------------------------------- src/render/tga.h | 34 ----- src/render/tgafile.cc | 367 +++++++++++++++++++++++++++++++++++++++++++++ src/render/tgafile.h | 34 +++++ src/ui/console.cc | 2 +- src/ui/paint.cc | 42 +++--- src/ui/scrollpane.cc | 6 +- src/ui/ui.cc | 10 +- 28 files changed, 819 insertions(+), 729 deletions(-) create mode 100644 src/render/screenshot.cc create mode 100644 src/render/screenshot.h create mode 100644 src/render/state.cc create mode 100644 src/render/state.h delete mode 100644 src/render/tga.cc delete mode 100644 src/render/tga.h create mode 100644 src/render/tgafile.cc create mode 100644 src/render/tgafile.h (limited to 'src') diff --git a/src/client/chat.cc b/src/client/chat.cc index f123bbc..1983415 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -43,6 +43,13 @@ Chat::~Chat() history.clear(); } +void Chat::clear() +{ + chat_log.clear(); + chat_input->clear(); +} + + void Chat::set_small_view(bool small_chat_view) { chat_small = small_chat_view; diff --git a/src/client/chat.h b/src/client/chat.h index 8c52b4e..b7e1691 100644 --- a/src/client/chat.h +++ b/src/client/chat.h @@ -31,6 +31,8 @@ public: void set_small_view(bool small_view=true); + void clear(); + protected: virtual void event_draw(); virtual void resize(); diff --git a/src/client/client.cc b/src/client/client.cc index 617b569..42ee5a0 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -240,6 +240,7 @@ void Client::shutdown() void Client::notify_connect() { view()->notify()->clear(); + view()->chat()->clear(); ui::root()->hide_menu(); } @@ -249,7 +250,8 @@ void Client::notify_disconnect() render::reset(); input::reset(); - // TODO clear chat and notifications + view()->notify()->clear(); + view()->chat()->clear(); } void Client::notify_zonechange() diff --git a/src/client/input.cc b/src/client/input.cc index f8c756f..8236b9b 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -17,9 +17,11 @@ #include "core/core.h" #include "math/functions.h" #include "render/camera.h" +#include "render/state.h" #include "render/draw.h" #include "render/dust.h" #include "render/text.h" +#include "render/screenshot.h" #include "ui/ui.h" namespace client @@ -106,7 +108,7 @@ float joystick_lastmoved_time() void func_screenshot(std::string const & args) { - render::screenshot(); + render::Screenshot::save(); } void func_ui_control(std::string const &args) @@ -634,8 +636,8 @@ void reset() } mouse_pitch = 0.0f; mouse_direction = 0.0f; - mouse_x = render::Camera::width() / 2; - mouse_y = render::Camera::height() / 2; + mouse_x = render::State::width() / 2; + mouse_y = render::State::height() / 2; render::Camera::reset(); render::Dust::reset(); mouse_control_override = false; @@ -802,26 +804,26 @@ void frame() mouse_deadzone = true; // direction - int l = mouse_x - (render::Camera::width() >> 1); + int l = mouse_x - (render::State::width() >> 1); if (abs(l) < ( deadzone_size >> 1 )) { // dead zone mouse_direction = 0; } else { - l = (mouse_x - deadzone_size) - ((render::Camera::width() - deadzone_size) >> 1); - mouse_direction = float (-l) / (float) ((render::Camera::width() - deadzone_size) >> 1); + l = (mouse_x - deadzone_size) - ((render::State::width() - deadzone_size) >> 1); + mouse_direction = float (-l) / (float) ((render::State::width() - deadzone_size) >> 1); mouse_deadzone = false; } // pitch - int h = mouse_y - (render::Camera::height() >> 1); + int h = mouse_y - (render::State::height() >> 1); if (abs(h) < ( deadzone_size >> 1 )) { // dead zone mouse_pitch = 0; } else { - h = (mouse_y - deadzone_size) - ((render::Camera::height() - deadzone_size) >> 1); - mouse_pitch = float (-h) / (float) ((render::Camera::height() - deadzone_size) >> 1); + h = (mouse_y - deadzone_size) - ((render::State::height() - deadzone_size) >> 1); + mouse_pitch = float (-h) / (float) ((render::State::height() - deadzone_size) >> 1); mouse_deadzone = false; } @@ -852,7 +854,7 @@ void frame() core::localcontrol()->set_thrust(local_thrust); core::localcontrol()->set_direction(local_direction); - core::localcontrol()->set_pitch(local_pitch / render::Camera::aspect() ); + core::localcontrol()->set_pitch(local_pitch / render::State::aspect() ); core::localcontrol()->set_roll(local_roll); core::localcontrol()->set_strafe(local_strafe); core::localcontrol()->set_afterburner(local_afterburner); diff --git a/src/client/targets.cc b/src/client/targets.cc index 04a4463..8b77644 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -25,6 +25,7 @@ #include "math/axis.h" #include "math/vector3f.h" #include "render/camera.h" +#include "render/state.h" namespace client { @@ -413,8 +414,8 @@ void draw() x = 0; y = 0; } else { - x = (float)(input::mouse_position_x() - render::Camera::width() /2) / (float)render::Camera::width(); - y = (float)(input::mouse_position_y() - render::Camera::height() /2) / (float)render::Camera::height() / render::Camera::aspect(); + x = (float)(input::mouse_position_x() - render::State::width() /2) / (float)render::State::width(); + y = (float)(input::mouse_position_y() - render::State::height() /2) / (float)render::State::height() / render::State::aspect(); } Vector3f cursor = render::Camera::eye() + render::Camera::axis().forward() * (render::Camera::frustum_front() + 0.001); diff --git a/src/client/video.cc b/src/client/video.cc index 6e80af6..53e5dbc 100644 --- a/src/client/video.cc +++ b/src/client/video.cc @@ -8,11 +8,7 @@ #include "client/input.h" #include "client/view.h" #include "client/client.h" -#include "render/camera.h" #include "render/render.h" -#include "render/tga.h" -#include "render/pngfile.h" -#include "render/jpgfile.h" #include "core/core.h" #include "filesystem/filesystem.h" #include "sys/sys.h" @@ -161,8 +157,7 @@ bool init() } // initialize renderer - render::init(); - render::resize(width, height); + render::init(width, height); view::init(); diff --git a/src/client/view.cc b/src/client/view.cc index 42ace02..90a30ef 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -291,8 +291,6 @@ void shutdown() void draw_entity_world_target(core::Entity *entity) { - using namespace render; - model::Model *model = entity->model(); if (!model) return; @@ -380,35 +378,35 @@ void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target) const float r = 16; const float margin = 24; - cx = (0.5f - cx) * ((float) render::Camera::width() - margin*2); + cx = (0.5f - cx) * ((float) render::State::width() - margin*2); cx += margin; - cy = (0.5f - cy) * ((float) render::Camera::height() - margin*2); + cy = (0.5f - cy) * ((float) render::State::height() - margin*2); cy += margin; - render::gl::disable(GL_TEXTURE_2D); - render::gl::color(0, 0, 0, 1); - render::gl::begin(render::gl::LineLoop); + gl::disable(GL_TEXTURE_2D); + gl::color(0, 0, 0, 1); + gl::begin(gl::LineLoop); glVertex3f(cx+r, cy+2, 0); glVertex3f(cx, cy+r+2, 0); glVertex3f(cx-r, cy+2, 0); glVertex3f(cx, cy-r+2, 0); - render::gl::end(); + gl::end(); if (entity == core::localplayer()->mission_target()) { - render::gl::color(1, 0.5f, 1, 1); // FIXME mission color + gl::color(1, 0.5f, 1, 1); // FIXME mission color } else if (entity->type() == core::Entity::Controlable) { - render::gl::color(0, 1, 0, 1); // FIXME allegiance color + gl::color(0, 1, 0, 1); // FIXME allegiance color } else { - render::gl::color(1, 1, 1, 1); // FIXME neutral color + gl::color(1, 1, 1, 1); // FIXME neutral color } - render::gl::begin(render::gl::LineLoop); + gl::begin(gl::LineLoop); glVertex3f(cx+r, cy, 0); glVertex3f(cx, cy+r, 0); glVertex3f(cx-r, cy, 0); glVertex3f(cx, cy-r, 0); - render::gl::end(); - render::gl::enable(GL_TEXTURE_2D); + gl::end(); + gl::enable(GL_TEXTURE_2D); } void draw_entity_target(core::Entity *entity, bool is_active_target) @@ -433,10 +431,10 @@ void draw_entity_target(core::Entity *entity, bool is_active_target) float t = (render::Camera::frustum_front() + 0.001f) / target.x; Vector3f center(target *t); - float cx = render::Camera::width() * (0.5 - center.y); - float cy = render::Camera::height() * (0.5 - center.z * render::Camera::aspect()); + float cx = render::State::width() * (0.5 - center.y); + float cy = render::State::height() * (0.5 - center.z * render::State::aspect()); - if ((cx < 0 ) || (cy < 0) || (cx > render::Camera::width()) || (cy > render::Camera::height())) { + if ((cx < 0 ) || (cy < 0) || (cx > render::State::width()) || (cy > render::State::height())) { draw_entity_offscreen_target(entity, is_active_target); return; } @@ -445,51 +443,51 @@ void draw_entity_target(core::Entity *entity, bool is_active_target) if (!is_active_target) r *= 0.5; - render::gl::disable(GL_TEXTURE_2D); + gl::disable(GL_TEXTURE_2D); // outer square shadow - render::gl::color(0, 0, 0, 1); - render::gl::begin(render::gl::LineLoop); + gl::color(0, 0, 0, 1); + gl::begin(gl::LineLoop); glVertex3f(cx+r, cy+2, 0); glVertex3f(cx, cy+r+2, 0); glVertex3f(cx-r, cy+2, 0); glVertex3f(cx, cy-r+2, 0); - render::gl::end(); + gl::end(); if ((entity->flags() & core::Entity::Dockable) == core::Entity::Dockable) { - render::gl::begin(render::gl::LineLoop); + gl::begin(gl::LineLoop); glVertex3f(cx+ (r*0.25f), cy+2, 0); glVertex3f(cx, cy+(r*0.25f)+2, 0); glVertex3f(cx-(r*0.25f), cy+2, 0); glVertex3f(cx, cy-(r*0.25f)+2, 0); - render::gl::end(); + gl::end(); } if (entity == core::localplayer()->mission_target()) { - render::gl::color(1, 0.5f, 1, 1); // FIXME mission color + gl::color(1, 0.5f, 1, 1); // FIXME mission color } else if (entity->type() == core::Entity::Controlable) { - render::gl::color(0, 1, 0, 1); // FIXME allegiance color + gl::color(0, 1, 0, 1); // FIXME allegiance color } else { - render::gl::color(1, 1, 1, 1); // FIXME neutral color + gl::color(1, 1, 1, 1); // FIXME neutral color } // outer square0 - render::gl::begin(render::gl::LineLoop); + gl::begin(gl::LineLoop); glVertex3f(cx+r, cy, 0); glVertex3f(cx, cy+r, 0); glVertex3f(cx-r, cy, 0); glVertex3f(cx, cy-r, 0); - render::gl::end(); + gl::end(); if ((entity->flags() & core::Entity::Dockable) == core::Entity::Dockable) { - render::gl::begin(render::gl::LineLoop); + gl::begin(gl::LineLoop); glVertex3f(cx+(r*0.25f), cy, 0); glVertex3f(cx, cy+(r*0.25f), 0); glVertex3f(cx-(r*0.25f), cy, 0); glVertex3f(cx, cy-(r*0.25f), 0); - render::gl::end(); + gl::end(); } - render::gl::enable(GL_TEXTURE_2D); + gl::enable(GL_TEXTURE_2D); if (is_active_target) { // entity name and distance @@ -525,10 +523,10 @@ void draw_hud() // draw a basic HUD if(core::localplayer()->view()) { Text::setcolor('N'); //set normal color - Text::draw(render::Camera::width()-4-Text::fontwidth()*32, render::Camera::height()-Text::fontheight()*3-4, core::localcontrol()->zone()->name()); + Text::draw(render::State::width()-4-Text::fontwidth()*32, render::State::height()-Text::fontheight()*3-4, core::localcontrol()->zone()->name()); Text::setcolor('B'); //set bold color - Text::draw(render::Camera::width() - 4-Text::fontwidth()*32, render::Camera::height() - Text::fontheight()*2 -4, core::localplayer()->view()->name()); + Text::draw(render::State::width() - 4-Text::fontwidth()*32, render::State::height() - Text::fontheight()*2 -4, core::localplayer()->view()->name()); } else if (core::localcontrol() && core::localcontrol()->zone()) { core::Zone *zone = core::localcontrol()->zone(); @@ -562,7 +560,7 @@ void draw_hud() statestr << "^FJumping..."; } - Text::draw(4, render::Camera::height() - Text::fontheight()*3-4, statestr); + Text::draw(4, render::State::height() - Text::fontheight()*3-4, statestr); } core::Entity *target = targets::current(); @@ -588,28 +586,28 @@ void draw_hud() strtarget << " --"; } strtarget << '\n'; - Text::draw(render::Camera::width() - 4-Text::fontwidth()*32, render::Camera::height() - Text::fontheight()*2 -4, strtarget); + Text::draw(render::State::width() - 4-Text::fontwidth()*32, render::State::height() - Text::fontheight()*2 -4, strtarget); y = 3.0f; } Text::setcolor('N'); //set normal color - Text::draw(render::Camera::width()-4-Text::fontwidth()*32, render::Camera::height()-Text::fontheight()*y-4, core::localcontrol()->zone()->name()); + Text::draw(render::State::width()-4-Text::fontwidth()*32, render::State::height()-Text::fontheight()*y-4, core::localcontrol()->zone()->name()); Textures::bind("bitmaps/hud/thruster_base"); // 316 x 32 bitmap gl::color(1, 1, 1, 1); - gl::begin(render::gl::Quads); + gl::begin(gl::Quads); glTexCoord2f(0, 0); - gl::vertex(4, render::Camera::height() - 4 - 32, 0); + gl::vertex(4, render::State::height() - 4 - 32, 0); glTexCoord2f(1, 0); - gl::vertex(4 + 316, render::Camera::height() - 4 - 32, 0); + gl::vertex(4 + 316, render::State::height() - 4 - 32, 0); glTexCoord2f(1, 1); - gl::vertex(4 + 316, render::Camera::height() - 4 , 0); + gl::vertex(4 + 316, render::State::height() - 4 , 0); glTexCoord2f(0, 1); - gl::vertex(4, render::Camera::height() - 4 , 0); + gl::vertex(4, render::State::height() - 4 , 0); gl::end(); @@ -630,18 +628,18 @@ void draw_hud() gl::color(1, 1, .5f + d * 5.0f); } Textures::bind("bitmaps/hud/thruster_indicator"); // 316 x 32 bitmap - gl::begin(render::gl::Quads); + gl::begin(gl::Quads); glTexCoord2f(0, 0); - gl::vertex(4, render::Camera::height() - 4 - 32, 0); + gl::vertex(4, render::State::height() - 4 - 32, 0); glTexCoord2f(u, 0); - gl::vertex(4.0f + u * 316.0f, render::Camera::height() - 4 - 32, 0); + gl::vertex(4.0f + u * 316.0f, render::State::height() - 4 - 32, 0); glTexCoord2f(u, 1); - gl::vertex(4.0f + u * 316.0f, render::Camera::height() - 4 , 0); + gl::vertex(4.0f + u * 316.0f, render::State::height() - 4 , 0); glTexCoord2f(0, 1); - gl::vertex(4, render::Camera::height() - 4 , 0); + gl::vertex(4, render::State::height() - 4 , 0); gl::end(); } @@ -651,7 +649,7 @@ void draw_hud() std::stringstream speedstr; speedstr << "^B" << roundf(core::localcontrol()->speed() * 100.0f); - Text::draw( 316+4+10, render::Camera::height() - 6 -16 - render::Text::fontwidth() /2, speedstr); + Text::draw( 316+4+10, render::State::height() - 6 -16 - render::Text::fontwidth() /2, speedstr); Text::setfont("gui", 12, 18); Text::setcolor('N'); //set normal color @@ -680,7 +678,7 @@ void draw_cursor() ui::root()->set_pointer("target", ui::Palette::Active, true); if (input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) { - ui::root()->input_mouse(render::Camera::width()/2, render::Camera::height() /2); + ui::root()->input_mouse(render::State::width()/2, render::State::height() /2); } } else if (input::mouse_control) { @@ -688,7 +686,7 @@ void draw_cursor() ui::root()->set_pointer("control", ui::Palette::Pointer); if (input::mouse_deadzone) { - ui::root()->input_mouse(render::Camera::width()/2, render::Camera::height() /2); + ui::root()->input_mouse(render::State::width()/2, render::State::height() /2); } } else if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && diff --git a/src/dedicated/dedicated.cc b/src/dedicated/dedicated.cc index 387fcbe..8f47180 100644 --- a/src/dedicated/dedicated.cc +++ b/src/dedicated/dedicated.cc @@ -33,7 +33,7 @@ void run(int count, char **arguments) void Dedicated::init(int count, char **arguments) { - con_print << "^BInitializing server..." << std::endl; + con_print << "^BInitializing dedicated server..." << std::endl; core::Cvar::set("sv_dedicated", "1", core::Cvar::ReadOnly); @@ -68,7 +68,7 @@ void Dedicated::run() void Dedicated::shutdown() { - con_print << "^BShutting down server..." << std::endl; + con_print << "^BShutting down dedicated server..." << std::endl; float ratio = 0; if (core::Stats::network_uncompressed_bytes_sent > 0) diff --git a/src/render/Makefile.am b/src/render/Makefile.am index 27ad8bb..7919ee2 100644 --- a/src/render/Makefile.am +++ b/src/render/Makefile.am @@ -10,6 +10,6 @@ endif librender_la_LDFLAGS = -avoid-version -no-undefined @GL_LIBS@ librender_la_LIBADD = $(top_builddir)/src/math/libmath.la librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc jpgfile.cc \ - pngfile.cc render.cc text.cc textures.cc tga.cc + pngfile.cc render.cc screenshot.cc state.cc text.cc textures.cc tgafile.cc noinst_HEADERS = camera.h draw.h dust.h gl.h image.h render.h text.h textures.h \ - tga.h pngfile.h jpgfile.h + tgafile.h pngfile.h jpgfile.h screenshot.h state.h diff --git a/src/render/camera.cc b/src/render/camera.cc index c7749c4..875b147 100644 --- a/src/render/camera.cc +++ b/src/render/camera.cc @@ -9,6 +9,7 @@ #include "math/matrix4f.h" #include "render/camera.h" #include "render/gl.h" +#include "render/state.h" #include "sys/sys.h" using math::degrees360f; @@ -22,12 +23,9 @@ const float MIN_DELTA = 10e-10; 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; math::Vector3f Camera::camera_target; math::Axis Camera::camera_axis; @@ -48,10 +46,6 @@ 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; @@ -80,13 +74,6 @@ void Camera::shutdown() { } -void Camera::resize(int width, int height) -{ - camera_width = width; - camera_height = height; - camera_aspect = (float) width / (float) height; -} - void Camera::set_mode(Mode newmode) { direction_target = 0; @@ -344,7 +331,7 @@ void Camera::frustum() gl::matrixmode(GL_PROJECTION); gl::loadidentity(); - gl::frustum(-camera_frustum_size, camera_frustum_size, -camera_frustum_size/Camera::aspect(), camera_frustum_size/Camera::aspect(), camera_frustum_front, 1023.0f); + gl::frustum(-camera_frustum_size, camera_frustum_size, -camera_frustum_size/State::aspect(), camera_frustum_size/State::aspect(), camera_frustum_front, 1023.0f); gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); @@ -365,7 +352,7 @@ void Camera::ortho() // switch to orthographic projection gl::matrixmode(GL_PROJECTION); gl::loadidentity(); - glOrtho(0, camera_width, camera_height, 0, -16.0f, 16.0f); + glOrtho(0, State::width(), State::height(), 0, -16.0f, 16.0f); gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); diff --git a/src/render/camera.h b/src/render/camera.h index 5394d1b..3f30ff6 100644 --- a/src/render/camera.h +++ b/src/render/camera.h @@ -37,9 +37,6 @@ public: /// current camera mode static inline Mode mode() { return camera_mode; } - /// current aspect ratio - static inline float aspect() { return camera_aspect; } - /// reset the current mode static void reset(); @@ -71,30 +68,20 @@ public: /// set specified camera mode static void set_mode(Mode newmode); - /// resize camera - static void resize(int width, int height); - /// current frustum front static float frustum_front(); /// 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; static math::Axis camera_axis; static Mode camera_mode; static Mode camera_previous_mode; - 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/gl.cc b/src/render/gl.cc index 47a0420..31c473f 100644 --- a/src/render/gl.cc +++ b/src/render/gl.cc @@ -7,14 +7,12 @@ #include "render/gl.h" #include "math/matrix4f.h" +namespace gl { + using math::Vector2f; using math::Vector3f; using math::Color; -namespace render { - -namespace gl { - std::string renderer() { return std::string ((char *)glGetString(GL_RENDERER)); @@ -185,4 +183,3 @@ void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdou } // namespace gl -} // namespace render diff --git a/src/render/gl.h b/src/render/gl.h index 6e32e35..a858c5b 100644 --- a/src/render/gl.h +++ b/src/render/gl.h @@ -20,8 +20,6 @@ #define GL_RESCALE_NORMAL 0x803A #endif -namespace render { - /// wrapper namespace for OpenGL operations /** The gl namespace provides a wrapper to the OpenGL library functions. * All methods take floats or Vector3f and Color as parameters. @@ -184,6 +182,4 @@ namespace gl void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble znear, GLdouble zfar); } -} - #endif // __INCLUDED_RENDER_GL_H__ diff --git a/src/render/render.cc b/src/render/render.cc index 02bd586..9afa179 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -14,93 +14,47 @@ #include "filesystem/filesystem.h" #include "model/model.h" #include "render/gl.h" +#include "render/state.h" #include "render/dust.h" -#include "render/textures.h" -#include "render/tga.h" #include "render/render.h" +#include "render/screenshot.h" +#include "render/textures.h" #include "sys/sys.h" namespace render { +model::VertexArray *vertexarray = 0; + core::Cvar *r_arraysize = 0; core::Cvar *r_bbox = 0; 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; void func_list_textures(std::string const &args) { Textures::list(); } -void reset_gl() +void init(int width, int 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 + con_print << "^BInitializing renderer..." << std::endl; - // alpha blending function - gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + con_print << " renderer ^B" << gl::renderer() << std::endl; + con_print << " vendor ^B" << gl::vendor() << std::endl; + con_print << " version ^B" << gl::version() << std::endl; - gl::disable(GL_LIGHTING); - gl::disable(GL_COLOR_MATERIAL); + // initialize render state + State::init(width, height); - gl::cullface(GL_BACK); - gl::frontface(GL_CCW); - gl::disable(GL_CULL_FACE); - gl::disable(GL_DEPTH_TEST); - gl::disable(GL_BLEND); + Camera::init(); - gl::disable(GL_TEXTURE_2D); -} + Textures::init(); -void init() -{ - con_print << "^BInitializing renderer..." << std::endl; + Text::init(); - con_print << " renderer ^B" << gl::renderer() << std::endl; - con_print << " vendor ^B" << gl::vendor() << std::endl; - con_print << " version ^B" << gl::version() << std::endl; + Dust::init(); // size of the vertex array in megabytes r_arraysize = core::Cvar::get("r_arraysize", 0.0f , core::Cvar::Archive); @@ -112,8 +66,9 @@ void init() if (mb > 256) mb = 256; (*r_arraysize) = (float) mb; - vertexarray = new VertexArray(mb); + vertexarray = new model::VertexArray(mb); + // engine variables r_radius = core::Cvar::get("r_radius", "0", core::Cvar::Archive); r_radius->set_info("[bool] render entity radius"); @@ -129,33 +84,17 @@ 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(); + Screenshot::screenshotformat = core::Cvar::get("screenshotformat", "jpg", core::Cvar::Archive); + Screenshot::screenshotformat->set_info("[string] screenshot format: jpg png tga"); - Text::init(); + Screenshot::screenshotquality = core::Cvar::get("screenshotquality", "85", core::Cvar::Archive); + Screenshot::screenshotquality->set_info("[int] screenshot jpg quality"); - Dust::init(); - + // engine functions core::Func *func = core::Func::add("list_textures", func_list_textures); func->set_info("list loaded textures"); } -void resize(int width, int height) -{ - // setup our viewport. - gl::viewport(0, 0, width, height); - Camera::resize(width, height); -} - // unload game assets (zone change) void unload() { @@ -184,7 +123,8 @@ void unload() // clear all assets void clear() { - con_debug << "Clearing render data...\n"; + //con_debug << " vclearing render data...\n"; + // 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; @@ -204,7 +144,7 @@ void clear() } } - // clear models + // clear model refistry model::Model::clear(); // clear vertex array @@ -212,25 +152,33 @@ void clear() vertexarray = 0; } -// reset render subsystem +// reset render subsystem (module disconnect) void reset() { clear(); + State::clear(); + Textures::shutdown(); + Textures::init(); + size_t mb = (size_t) r_arraysize->value(); if (mb < 4 * sizeof(float)) mb = 4 * sizeof(float); if (mb > 256) mb = 256; (*r_arraysize) = (float) mb; - vertexarray = new VertexArray(mb); + vertexarray = new model::VertexArray(mb); - reset_gl(); Dust::reset(); } +void resize(int width, int height) +{ + State::resize(width, height); +} + void shutdown() { con_print << "^BShutting down renderer..." << std::endl; @@ -246,92 +194,8 @@ void shutdown() Camera::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) { -/* if ((Camera::width() % 8 != 0 ) || (Camera::height() % 8 != 0 )) { - image.pad(); - }*/ - render::PNG::save(filename.c_str(), image); - } else if (filetype == TYPEJPG) { -/* if ((Camera::width() % 8 != 0 ) || (Camera::height() % 8 != 0 )) { - image.pad(); - } -*/ - render::JPG::save(filename.c_str(), image, (int) screenshotquality->value()); - } else if (filetype == TYPETGA) { - render::TGA::save(filename.c_str(), image); - } -} + State::shutdown(); } +} // namespace render diff --git a/src/render/render.h b/src/render/render.h index a7aec70..4317540 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -11,20 +11,17 @@ #include "model/vertexarray.h" #include "render/camera.h" +#include "render/state.h" #include "render/draw.h" #include "render/dust.h" #include "render/gl.h" -#include "render/jpgfile.h" -#include "render/pngfile.h" -#include "render/image.h" #include "render/text.h" #include "render/textures.h" -#include "render/tga.h" namespace render { /// initialize the render subsystem - void init(); + void init(int width, int height); /// shutdown the render subsystem void shutdown(); @@ -35,11 +32,8 @@ namespace render { /// unload game render data void unload(); - /// make a screenshot - void screenshot(); - /// resize viewport - void resize(int w, int h); + void resize(int width, int height); extern core::Cvar *r_arraysize; extern core::Cvar *r_bbox; diff --git a/src/render/screenshot.cc b/src/render/screenshot.cc new file mode 100644 index 0000000..c2ee88a --- /dev/null +++ b/src/render/screenshot.cc @@ -0,0 +1,109 @@ +/* + render/screenshot.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "auxiliary/functions.h" +#include "core/core.h" +#include "filesystem/filesystem.h" +#include "render/state.h" +#include "render/screenshot.h" +#include "render/image.h" +#include "render/jpgfile.h" +#include "render/pngfile.h" +#include "render/tgafile.h" +#include "render/gl.h" + +namespace render { + +core::Cvar *Screenshot::screenshotformat = 0; +core::Cvar *Screenshot::screenshotquality = 0; + +int Screenshot::number = 0; + +void Screenshot::save() +{ + 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 << 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; + } + number++; + } while (!available); + + render::Image image(State::width(), State::height(), 3); + + glReadPixels(0, 0, (GLsizei) State::width(), (GLsizei) State::height(), + GL_RGB, GL_UNSIGNED_BYTE, (void *) image.data()); + + image.flip(); + + if (filetype == TYPEPNG) { +/* if ((Camera::width() % 8 != 0 ) || (Camera::height() % 8 != 0 )) { + image.pad(); + }*/ + render::PNG::save(filename.c_str(), image); + } else if (filetype == TYPEJPG) { +/* if ((Camera::width() % 8 != 0 ) || (Camera::height() % 8 != 0 )) { + image.pad(); + } +*/ + render::JPG::save(filename.c_str(), image, (int) screenshotquality->value()); + } else if (filetype == TYPETGA) { + render::TGA::save(filename.c_str(), image); + } +} + +} // namsepace render \ No newline at end of file diff --git a/src/render/screenshot.h b/src/render/screenshot.h new file mode 100644 index 0000000..bf61ef6 --- /dev/null +++ b/src/render/screenshot.h @@ -0,0 +1,27 @@ +/* + render/screenshot.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_RENDER_SCREENSHOT_H__ +#define __INCLUDED_RENDER_SCREENSHOT_H__ + +#include "core/cvar.h" + +namespace render { + +class Screenshot { +public: + static void save(); + + static core::Cvar *screenshotformat; + static core::Cvar *screenshotquality; + +private: + static int number; +}; + +} + +#endif // __INCLUDED_RENDER_SCREENSHOT_H__ \ No newline at end of file diff --git a/src/render/state.cc b/src/render/state.cc new file mode 100644 index 0000000..41ef158 --- /dev/null +++ b/src/render/state.cc @@ -0,0 +1,91 @@ +/* + render/state.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "render/state.h" +#include "render/gl.h" + +namespace render { + +int State::render_width; +int State::render_height; +float State::render_aspect; + +void State::init(int width, int height) +{ + resize(width, height); +} + +void State::shutdown() +{ +} + +void State::resize(int width, int height) +{ + render_width = width; + render_height = height; + + render_aspect = (float) width / (float) height; + + clear(); +} + +void State::clear() +{ + // set viewport + gl::viewport(0, 0, render_width, render_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); +} + +} // namespace render diff --git a/src/render/state.h b/src/render/state.h new file mode 100644 index 0000000..59626c4 --- /dev/null +++ b/src/render/state.h @@ -0,0 +1,34 @@ +/* + render/state.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_RENDER_STATE_H__ +#define __INCLUDED_RENDER_STATE_H__ + + +namespace render { + +class State { +public: + static void init(int width, int height); + static void shutdown(); + + static void resize(int width, int height); + static void clear(); + + inline static int width() { return render_width; } + inline static int height() { return render_height; } + inline static float aspect() { return render_aspect; } + +private: + static int render_width; + static int render_height; + + static float render_aspect; +}; +} // namespace render + +#endif // __INCLUDED_RENDER_STATE_H__ + diff --git a/src/render/textures.cc b/src/render/textures.cc index fd2367d..60c82c2 100644 --- a/src/render/textures.cc +++ b/src/render/textures.cc @@ -7,8 +7,9 @@ #include #include "render/gl.h" +#include "render/image.h" #include "render/textures.h" -#include "render/tga.h" +#include "render/tgafile.h" #include "render/pngfile.h" #include "render/jpgfile.h" diff --git a/src/render/tga.cc b/src/render/tga.cc deleted file mode 100644 index a7a2356..0000000 --- a/src/render/tga.cc +++ /dev/null @@ -1,367 +0,0 @@ -/* - render/tga.cc - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2 -*/ - -/* - Documentation and examples on the TGA file format: - - http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf - http://www.fileformat.info/format/tga/egff.htm - http://www.morrowland.com/apron/tut_gl.php - - Notes - - TGA image type Colormap RLE - 0 No image data included in file No No - 1 Colormapped image data Yes No - 2 Truecolor image data No No - 3 Monochrome image data No No - 9 Colormapped image data Yes Yes - 10 Truecolor image data No Yes - 11 Monochrome image data No Yes - - TGA multi-byte integer values have LSB first -*/ - -#include - -#include -#include -#include - -#include "filesystem/filesystem.h" -#include "render/tga.h" -#include "sys/sys.h" - -const unsigned char TGA_NONE = 0; -const unsigned char TGA_TRUECOLOR = 2; -const unsigned char TGA_TRUECOLOR_RLE = 10; - -namespace render -{ - -Image *TGA::load(const char *filename) -{ - Image *image = 0; - - if (!filename) - return 0; - - filesystem::File *tga_file = filesystem::open(filename); - if (!tga_file) { - //con_warn << "Could not open " << filename << std::endl; - return 0; - } - - // TGA header - unsigned char header[18]; - memset(header, 0, sizeof(header)); - - if (!tga_file->read(header, 18)) { - con_warn << "Error reading " << filename << std::endl; - filesystem::close(tga_file); - return 0; - } - - // byte 0 - image ID field length - unsigned int tga_idlength = header[0]; - - // byte 1 - color map type - unsigned int tga_colormap = header[1]; - - // byte 2 - image type - unsigned int tga_type = header[2]; - - // byte 3+4 - color map first entry index - //unsigned int tga_colormap_first = header[3] + (header[4] << 8 ); - - // byte 5+6 - color map length (in bits) - unsigned int tga_color_map_length = header[5] +(header[6] << 8 ); - - // byte 7 - color map entry length - unsigned int tga_colormap_entry = header[7]; - - // byte 8+9 - image x origin - // byte 10+11 - image y origin - // byte 12+13 - image width (LSB first) - unsigned int tga_width = header[12] + (header[13] << 8); - - // byte 14+15 - image height (LSB first) - unsigned int tga_height = header[14] + (header[15] << 8); - - // byte 16 - image color depth (in bits) - unsigned int tga_depth = header[16]; - - // byte 17 - image descriptor byte - unsigned int tga_descriptor = header[17]; - - // read the image id if there is one - if (tga_idlength) - tga_file->skip(tga_idlength); - - // read color map data (even for non-color mapped images) - if (tga_colormap) { - if (tga_colormap > 1) - con_warn << filename << ": invalid color map type!" << std::endl; - - tga_file->skip(tga_color_map_length*tga_colormap_entry); - } - - unsigned int index = 0; - unsigned int channels = tga_depth / 8; - - switch(tga_type) { - - case TGA_NONE: - con_warn << "Error reading " << filename - << ": no image data!" << std::endl; - filesystem::close(tga_file); - return 0; - break; - - case TGA_TRUECOLOR: - if ((tga_depth == 24) || (tga_depth == 32)) { - - image = new Image(tga_width, tga_height, channels); - - for (size_t i = 0; i < tga_width * tga_height; i++) { - tga_file->read((void *)(*image)[i*(size_t)channels], channels); - } - - image->swap_channels(); - - } else if (tga_depth == 16) { - - channels = 3; - image = new Image(tga_width, tga_height,channels); - - for (size_t i =0; i < tga_width * tga_height; i++) { - // unpack one pixel - unsigned char pixel_data[2]; - tga_file->read((void *)pixel_data, 2); - unsigned int unpacked = pixel_data[0] + pixel_data[1]* 0xff; - - unsigned int b = (unpacked & 0x1f) << 3; - unsigned int g = ((unpacked >> 5) & 0x1f) << 3; - unsigned int r = ((unpacked >> 10) & 0x1f) << 3; - - // store it - image->data()[i * channels] = (unsigned char) b; - image->data()[i * channels+1] = (unsigned char) g; - image->data()[i * channels+2] = (unsigned char) r; - } - } else { - con_warn << "Error reading " << filename - << ": unsupported image depth '" << tga_depth << "'!" << std::endl; - filesystem::close(tga_file); - return 0; - } - - break; - - case TGA_TRUECOLOR_RLE: - - image = new Image(tga_width, tga_height, channels); - - while (index < tga_width * tga_height) { - unsigned char rle = 0; - unsigned char pixel_data[3]; - - // read RLE packet byte - tga_file->read(&rle, 1); - - if (rle < 128) { - rle++; // rle contains the number of pixels-1 - tga_file->read((void *)(*image)[index*channels], rle*channels); - index += rle; - - } else { - rle -= 127; // rle contains 128 + the number of identical pixels-1 - tga_file->read(pixel_data, channels); - - while (rle) { - memcpy((void *)(*image)[index*channels], (void *)pixel_data, channels); - index++; - rle--; - } - } - } - - image->swap_channels(); - - break; - - default: - con_warn << "Error reading " << filename - << ": unsupported TGA type '" << (int) tga_type << "'!" << std::endl; - filesystem::close(tga_file); - return 0; - } - - filesystem::close(tga_file); - - if ((tga_descriptor & 0x20) == 0x0) { - // origin at bottom left - image->flip(); - } - - if ((tga_descriptor & 0x10) == 0x10) { - con_warn << filename << ": descriptor bit 4 (left-right) set!" << std::endl; - } - - con_debug << " " << filename << " " << image->width() << "x" << image->height() << "x" << image->bpp() << "bpp" << std::endl; - return image; -} - -void TGA::save(const char *filename, Image & image) -{ - if (!filename) - return; - - std::ofstream ofs(filename, std::ios_base::out | std::ios_base::binary ); - - if (!ofs.is_open()) { - con_warn << "Could not write " << filename << std::endl; - return; - } - - // write TGA header - unsigned char header[18]; - memset(header, 0, sizeof(header)); - - // byte 0 - image ID field length = 0 (no image ID field present) - // byte 1 - color map type = 0 (no palette present) - // byte 2 - image type = 10 (truecolor RLE encoded) - header[2] = TGA_TRUECOLOR_RLE; - // byte 3-11 - palette data (not used) - // byte 12+13 - image width - header[12] = (image.width() & 0xff); - header[13] = ((image.width() >> 8) & 0xff); - // byte 14+15 - image height - header[14] = (image.height() & 0xff); - header[15] = ((image.height() >> 8) & 0xff); - // byte 16 - image color depth = 24 (RGB) or 32 (RGBA) - header[16] = image.channels() * 8; - // byte 17 - image descriptor byte = 0x20 (origin at bottom left) - header[17] = 0x20; - - // write header - ofs.write((char *)header, sizeof(header)); - - // write image data - // TGA has the R and B channels switched - unsigned char pixel_data[image.channels()]; - unsigned char block_data[image.channels()*128]; - unsigned char rle_packet; - bool compress = false; - size_t block_length = 0; - - for (int y = image.height()-1; y >= 0; y--) { - for (size_t x = 0; x < image.width(); x++) { - size_t index = y*image.width()*image.channels() + x * image.channels(); - - pixel_data[0] = *image[index+2]; - pixel_data[1] = *image[index+1]; - pixel_data[2] = *image[index]; - if (image.channels() == 4) - pixel_data[3] = *image[index+3]; - - if (block_length == 0) { - memcpy(block_data, pixel_data, image.channels()); - block_length++; - compress = false; - } else { - if (!compress) { - - // uncompressed block and pixel_data differs from the last pixel - if (memcmp(&block_data[(block_length-1)*image.channels()], pixel_data, image.channels()) != 0) { - // append pixel - memcpy(&block_data[block_length*image.channels()], pixel_data, image.channels()); - - block_length++; - } else { - - // uncompressed block and pixel data is identical - if (block_length > 1 ) { - // write the uncompressed block - rle_packet = block_length - 2; - ofs.write((char *)&rle_packet, 1); - ofs.write((char *)block_data, (block_length-1) * image.channels()); - block_length = 1; - } - memcpy(block_data, pixel_data, image.channels()); - block_length++; - compress = true; - } - - } else { - - // compressed block and pixel data is identical - if (memcmp(block_data, pixel_data, image.channels()) == 0) { - block_length++; - - } else { - - // compressed block and pixel data differs - if (block_length > 1) { - // write the compressed block - rle_packet = block_length + 127; - ofs.write((char *)&rle_packet, 1); - ofs.write((char *)block_data, image.channels()); - block_length = 0; - } - memcpy(&block_data[block_length * image.channels()], pixel_data, image.channels()); - block_length++; - compress = false; - } - } - } - - if (block_length == 128) { - rle_packet = block_length - 1; - if (!compress) { - ofs.write((char *)&rle_packet, 1); - ofs.write((char *)block_data, 128 * image.channels()); - } else { - rle_packet += 128; - ofs.write((char *)&rle_packet, 1); - ofs.write((char *)block_data, image.channels()); - } - - block_length = 0; - compress = false; - } - } - } - - // write remaining bytes - if (block_length) { - rle_packet = block_length - 1; - if (!compress) { - ofs.write((char *)&rle_packet, 1); - ofs.write((char *)block_data, block_length * image.channels()); - } else { - rle_packet += 128; - ofs.write((char *)&rle_packet, 1); - ofs.write((char *)block_data, image.channels()); - } - } - - - // write footer (optional, but the specification recommends it) - char footer[26]; - memset(footer, 0, sizeof(footer)); - strncpy(&footer[8] , "TRUEVISION-XFILE", 16); - footer[24] = '.'; - footer[25] = 0; - ofs.write(footer, sizeof(footer)); - - // close file - ofs.close(); - - con_print << "Wrote " << filename << std::endl; -} - -} diff --git a/src/render/tga.h b/src/render/tga.h deleted file mode 100644 index 767a871..0000000 --- a/src/render/tga.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - render/tga.h - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2 -*/ - - -#ifndef _INCLUDED_RENDER_TGA_H__ -#define _INCLUDED_RENDER_TGA_H__ - -#include "render/image.h" - -namespace render -{ - -/// a class for loading and saving .tga files -class TGA { - -public: - /// load a TGA image file from disk - /** @param filename short path to the filename to be loaded - */ - static Image *load(const char * filename); - - /// write an image to a TGA file - /** @param filename short path to the file to write the image data to - */ - static void save(const char *filename, Image & image); -}; - -} - -#endif //_INCLUDED_RENDER_TGA_H__ - diff --git a/src/render/tgafile.cc b/src/render/tgafile.cc new file mode 100644 index 0000000..5a27648 --- /dev/null +++ b/src/render/tgafile.cc @@ -0,0 +1,367 @@ +/* + render/tgafile.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +/* + Documentation and examples on the TGA file format: + + http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf + http://www.fileformat.info/format/tga/egff.htm + http://www.morrowland.com/apron/tut_gl.php + + Notes + + TGA image type Colormap RLE + 0 No image data included in file No No + 1 Colormapped image data Yes No + 2 Truecolor image data No No + 3 Monochrome image data No No + 9 Colormapped image data Yes Yes + 10 Truecolor image data No Yes + 11 Monochrome image data No Yes + + TGA multi-byte integer values have LSB first +*/ + +#include + +#include +#include +#include + +#include "filesystem/filesystem.h" +#include "render/tgafile.h" +#include "sys/sys.h" + +const unsigned char TGA_NONE = 0; +const unsigned char TGA_TRUECOLOR = 2; +const unsigned char TGA_TRUECOLOR_RLE = 10; + +namespace render +{ + +Image *TGA::load(const char *filename) +{ + Image *image = 0; + + if (!filename) + return 0; + + filesystem::File *tga_file = filesystem::open(filename); + if (!tga_file) { + //con_warn << "Could not open " << filename << std::endl; + return 0; + } + + // TGA header + unsigned char header[18]; + memset(header, 0, sizeof(header)); + + if (!tga_file->read(header, 18)) { + con_warn << "Error reading " << filename << std::endl; + filesystem::close(tga_file); + return 0; + } + + // byte 0 - image ID field length + unsigned int tga_idlength = header[0]; + + // byte 1 - color map type + unsigned int tga_colormap = header[1]; + + // byte 2 - image type + unsigned int tga_type = header[2]; + + // byte 3+4 - color map first entry index + //unsigned int tga_colormap_first = header[3] + (header[4] << 8 ); + + // byte 5+6 - color map length (in bits) + unsigned int tga_color_map_length = header[5] +(header[6] << 8 ); + + // byte 7 - color map entry length + unsigned int tga_colormap_entry = header[7]; + + // byte 8+9 - image x origin + // byte 10+11 - image y origin + // byte 12+13 - image width (LSB first) + unsigned int tga_width = header[12] + (header[13] << 8); + + // byte 14+15 - image height (LSB first) + unsigned int tga_height = header[14] + (header[15] << 8); + + // byte 16 - image color depth (in bits) + unsigned int tga_depth = header[16]; + + // byte 17 - image descriptor byte + unsigned int tga_descriptor = header[17]; + + // read the image id if there is one + if (tga_idlength) + tga_file->skip(tga_idlength); + + // read color map data (even for non-color mapped images) + if (tga_colormap) { + if (tga_colormap > 1) + con_warn << filename << ": invalid color map type!" << std::endl; + + tga_file->skip(tga_color_map_length*tga_colormap_entry); + } + + unsigned int index = 0; + unsigned int channels = tga_depth / 8; + + switch(tga_type) { + + case TGA_NONE: + con_warn << "Error reading " << filename + << ": no image data!" << std::endl; + filesystem::close(tga_file); + return 0; + break; + + case TGA_TRUECOLOR: + if ((tga_depth == 24) || (tga_depth == 32)) { + + image = new Image(tga_width, tga_height, channels); + + for (size_t i = 0; i < tga_width * tga_height; i++) { + tga_file->read((void *)(*image)[i*(size_t)channels], channels); + } + + image->swap_channels(); + + } else if (tga_depth == 16) { + + channels = 3; + image = new Image(tga_width, tga_height,channels); + + for (size_t i =0; i < tga_width * tga_height; i++) { + // unpack one pixel + unsigned char pixel_data[2]; + tga_file->read((void *)pixel_data, 2); + unsigned int unpacked = pixel_data[0] + pixel_data[1]* 0xff; + + unsigned int b = (unpacked & 0x1f) << 3; + unsigned int g = ((unpacked >> 5) & 0x1f) << 3; + unsigned int r = ((unpacked >> 10) & 0x1f) << 3; + + // store it + image->data()[i * channels] = (unsigned char) b; + image->data()[i * channels+1] = (unsigned char) g; + image->data()[i * channels+2] = (unsigned char) r; + } + } else { + con_warn << "Error reading " << filename + << ": unsupported image depth '" << tga_depth << "'!" << std::endl; + filesystem::close(tga_file); + return 0; + } + + break; + + case TGA_TRUECOLOR_RLE: + + image = new Image(tga_width, tga_height, channels); + + while (index < tga_width * tga_height) { + unsigned char rle = 0; + unsigned char pixel_data[3]; + + // read RLE packet byte + tga_file->read(&rle, 1); + + if (rle < 128) { + rle++; // rle contains the number of pixels-1 + tga_file->read((void *)(*image)[index*channels], rle*channels); + index += rle; + + } else { + rle -= 127; // rle contains 128 + the number of identical pixels-1 + tga_file->read(pixel_data, channels); + + while (rle) { + memcpy((void *)(*image)[index*channels], (void *)pixel_data, channels); + index++; + rle--; + } + } + } + + image->swap_channels(); + + break; + + default: + con_warn << "Error reading " << filename + << ": unsupported TGA type '" << (int) tga_type << "'!" << std::endl; + filesystem::close(tga_file); + return 0; + } + + filesystem::close(tga_file); + + if ((tga_descriptor & 0x20) == 0x0) { + // origin at bottom left + image->flip(); + } + + if ((tga_descriptor & 0x10) == 0x10) { + con_warn << filename << ": descriptor bit 4 (left-right) set!" << std::endl; + } + + con_debug << " " << filename << " " << image->width() << "x" << image->height() << "x" << image->bpp() << "bpp" << std::endl; + return image; +} + +void TGA::save(const char *filename, Image & image) +{ + if (!filename) + return; + + std::ofstream ofs(filename, std::ios_base::out | std::ios_base::binary ); + + if (!ofs.is_open()) { + con_warn << "Could not write " << filename << std::endl; + return; + } + + // write TGA header + unsigned char header[18]; + memset(header, 0, sizeof(header)); + + // byte 0 - image ID field length = 0 (no image ID field present) + // byte 1 - color map type = 0 (no palette present) + // byte 2 - image type = 10 (truecolor RLE encoded) + header[2] = TGA_TRUECOLOR_RLE; + // byte 3-11 - palette data (not used) + // byte 12+13 - image width + header[12] = (image.width() & 0xff); + header[13] = ((image.width() >> 8) & 0xff); + // byte 14+15 - image height + header[14] = (image.height() & 0xff); + header[15] = ((image.height() >> 8) & 0xff); + // byte 16 - image color depth = 24 (RGB) or 32 (RGBA) + header[16] = image.channels() * 8; + // byte 17 - image descriptor byte = 0x20 (origin at bottom left) + header[17] = 0x20; + + // write header + ofs.write((char *)header, sizeof(header)); + + // write image data + // TGA has the R and B channels switched + unsigned char pixel_data[image.channels()]; + unsigned char block_data[image.channels()*128]; + unsigned char rle_packet; + bool compress = false; + size_t block_length = 0; + + for (int y = image.height()-1; y >= 0; y--) { + for (size_t x = 0; x < image.width(); x++) { + size_t index = y*image.width()*image.channels() + x * image.channels(); + + pixel_data[0] = *image[index+2]; + pixel_data[1] = *image[index+1]; + pixel_data[2] = *image[index]; + if (image.channels() == 4) + pixel_data[3] = *image[index+3]; + + if (block_length == 0) { + memcpy(block_data, pixel_data, image.channels()); + block_length++; + compress = false; + } else { + if (!compress) { + + // uncompressed block and pixel_data differs from the last pixel + if (memcmp(&block_data[(block_length-1)*image.channels()], pixel_data, image.channels()) != 0) { + // append pixel + memcpy(&block_data[block_length*image.channels()], pixel_data, image.channels()); + + block_length++; + } else { + + // uncompressed block and pixel data is identical + if (block_length > 1 ) { + // write the uncompressed block + rle_packet = block_length - 2; + ofs.write((char *)&rle_packet, 1); + ofs.write((char *)block_data, (block_length-1) * image.channels()); + block_length = 1; + } + memcpy(block_data, pixel_data, image.channels()); + block_length++; + compress = true; + } + + } else { + + // compressed block and pixel data is identical + if (memcmp(block_data, pixel_data, image.channels()) == 0) { + block_length++; + + } else { + + // compressed block and pixel data differs + if (block_length > 1) { + // write the compressed block + rle_packet = block_length + 127; + ofs.write((char *)&rle_packet, 1); + ofs.write((char *)block_data, image.channels()); + block_length = 0; + } + memcpy(&block_data[block_length * image.channels()], pixel_data, image.channels()); + block_length++; + compress = false; + } + } + } + + if (block_length == 128) { + rle_packet = block_length - 1; + if (!compress) { + ofs.write((char *)&rle_packet, 1); + ofs.write((char *)block_data, 128 * image.channels()); + } else { + rle_packet += 128; + ofs.write((char *)&rle_packet, 1); + ofs.write((char *)block_data, image.channels()); + } + + block_length = 0; + compress = false; + } + } + } + + // write remaining bytes + if (block_length) { + rle_packet = block_length - 1; + if (!compress) { + ofs.write((char *)&rle_packet, 1); + ofs.write((char *)block_data, block_length * image.channels()); + } else { + rle_packet += 128; + ofs.write((char *)&rle_packet, 1); + ofs.write((char *)block_data, image.channels()); + } + } + + + // write footer (optional, but the specification recommends it) + char footer[26]; + memset(footer, 0, sizeof(footer)); + strncpy(&footer[8] , "TRUEVISION-XFILE", 16); + footer[24] = '.'; + footer[25] = 0; + ofs.write(footer, sizeof(footer)); + + // close file + ofs.close(); + + con_print << "Wrote " << filename << std::endl; +} + +} diff --git a/src/render/tgafile.h b/src/render/tgafile.h new file mode 100644 index 0000000..767a871 --- /dev/null +++ b/src/render/tgafile.h @@ -0,0 +1,34 @@ +/* + render/tga.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + + +#ifndef _INCLUDED_RENDER_TGA_H__ +#define _INCLUDED_RENDER_TGA_H__ + +#include "render/image.h" + +namespace render +{ + +/// a class for loading and saving .tga files +class TGA { + +public: + /// load a TGA image file from disk + /** @param filename short path to the filename to be loaded + */ + static Image *load(const char * filename); + + /// write an image to a TGA file + /** @param filename short path to the file to write the image data to + */ + static void save(const char *filename, Image & image); +}; + +} + +#endif //_INCLUDED_RENDER_TGA_H__ + diff --git a/src/ui/console.cc b/src/ui/console.cc index 0b7c278..60eecef 100644 --- a/src/ui/console.cc +++ b/src/ui/console.cc @@ -192,7 +192,7 @@ void Console::draw() version += ' '; version.append(core::version()); - render::gl::color(0.0f, 1.0f, 0.0f, 0.5f); + gl::color(0.0f, 1.0f, 0.0f, 0.5f); s.assign(version.size() * font()->width(), font()->height()); math::Vector2f l(global_location()); diff --git a/src/ui/paint.cc b/src/ui/paint.cc index 45b7eea..86058cf 100644 --- a/src/ui/paint.cc +++ b/src/ui/paint.cc @@ -19,12 +19,12 @@ namespace paint { void color(float r, float g, float b, float a) { - render::gl::color(r, g, b, a); + gl::color(r, g, b, a); } void color(math::Color const & color) { - render::gl::color(color); + gl::color(color); } void color_code(const char c) @@ -34,7 +34,7 @@ void color_code(const char c) void border(const math::Vector2f &location, const math::Vector2f &size) { - using namespace render::gl; + using namespace gl; begin(LineLoop); vertex(location.x +1 , location.y); @@ -46,7 +46,7 @@ void border(const math::Vector2f &location, const math::Vector2f &size) void rectangle(const math::Vector2f &location, const math::Vector2f &size) { - using namespace render::gl; + using namespace gl; begin(Quads); vertex(location.x +1 , location.y); @@ -59,27 +59,25 @@ void rectangle(const math::Vector2f &location, const math::Vector2f &size) // draw a bitmap void bitmap(const math::Vector2f &location, const math::Vector2f &size, std::string const &texture) { - using namespace render::gl; - render::Textures::bind("bitmaps/" + texture); - enable(GL_TEXTURE_2D); + gl::enable(GL_TEXTURE_2D); - begin(Quads); + gl::begin(gl::Quads); glTexCoord2f(0.0f, 0.0f); - vertex(location.x +1 , location.y); + gl::vertex(location.x +1 , location.y); glTexCoord2f(1.0f, 0.0f); - vertex(location.x + size.x, location.y); + gl::vertex(location.x + size.x, location.y); glTexCoord2f(1.0f, 1.0f); - vertex(location.x + size.x, location.y + size.y -1); + gl::vertex(location.x + size.x, location.y + size.y -1); glTexCoord2f(0.0f, 1.0f); - vertex(location.x +1, location.y + size.y - 1); - end(); + gl::vertex(location.x +1, location.y + size.y - 1); + gl::end(); - disable(GL_TEXTURE_2D); + gl::disable(GL_TEXTURE_2D); } // draw aligned text @@ -94,11 +92,10 @@ void label(const math::Vector2f &location, const math::Vector2f &size, const Fon align_vertical = AlignTop; // apply text font - using namespace render::gl; render::Text::setfont(font->name().c_str(), font->width(), font->height()); // enable OpenGL textures - enable(GL_TEXTURE_2D); + gl::enable(GL_TEXTURE_2D); // determine the width and height of the text // FIXME support multiline text @@ -135,38 +132,37 @@ void label(const math::Vector2f &location, const math::Vector2f &size, const Fon render::Text::draw(v.x, v.y, text); // disable OpenGL textures - disable(GL_TEXTURE_2D); + gl::disable(GL_TEXTURE_2D); } // draw unaligned text void text(const math::Vector2f &location, const math::Vector2f &size, const Font *font, const std::string &text) { - using namespace render::gl; render::Text::setfont(font->name().c_str(), font->width(), font->height()); // enable OpenGL textures - enable(GL_TEXTURE_2D); + gl::enable(GL_TEXTURE_2D); render::Text::draw(location.x, location.y, text); // disable OpenGL textures - disable(GL_TEXTURE_2D); + gl::disable(GL_TEXTURE_2D); } // draw unaligned text void text(const math::Vector2f &location, const math::Vector2f &size, const Font *font, std::stringstream & textstream) { - using namespace render::gl; + render::Text::setfont(font->name().c_str(), font->width(), font->height()); // enable OpenGL textures - enable(GL_TEXTURE_2D); + gl::enable(GL_TEXTURE_2D); render::Text::draw(location.x, location.y, textstream); // disable OpenGL textures - disable(GL_TEXTURE_2D); + gl::disable(GL_TEXTURE_2D); } } diff --git a/src/ui/scrollpane.cc b/src/ui/scrollpane.cc index a1de7d5..b4d08d6 100644 --- a/src/ui/scrollpane.cc +++ b/src/ui/scrollpane.cc @@ -57,7 +57,7 @@ void ScrollPane::dec_scroll(int scroll) void ScrollPane::draw() { render::Text::setfont(font()->name().c_str(), font()->width(), font()->height()); - render::gl::enable(GL_TEXTURE_2D); + gl::enable(GL_TEXTURE_2D); // text size int text_height = (int) floorf(height() / font()->height()); @@ -161,7 +161,7 @@ void ScrollPane::draw() current_line++; } - render::gl::color(palette()->text()); + gl::color(palette()->text()); const math ::Vector2f gl(global_location()); float y = 0; @@ -181,7 +181,7 @@ void ScrollPane::draw() y -= font()->height(); } } - render::gl::disable(GL_TEXTURE_2D); + gl::disable(GL_TEXTURE_2D); } } diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 7d57ce0..bc6f544 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -597,19 +597,19 @@ void UI::draw_pointer() texture.append(mouse_pointer_bitmap); if (mouse_pointer_animated) { - render::gl::push(); - render::gl::translate(mouse_cursor.x, mouse_cursor.y, 0); + gl::push(); + gl::translate(mouse_cursor.x, mouse_cursor.y, 0); float angle = core::application()->time()* 0.75f - floorf(core::application()->time() * 0.75f); angle *= 360.0f; - render::gl::rotate(angle, math::Vector3f(0, 0, 1.0f)); - render::gl::translate(-mouse_cursor.x, -mouse_cursor.y, 0); + gl::rotate(angle, math::Vector3f(0, 0, 1.0f)); + gl::translate(-mouse_cursor.x, -mouse_cursor.y, 0); } paint::bitmap(pos, s, texture); if (mouse_pointer_animated) { - render::gl::pop(); + gl::pop(); } } -- cgit v1.2.3