Skip to content

Commit

Permalink
renderer: initially integrated into the engine
Browse files Browse the repository at this point in the history
used for screenshots and resizing currently
  • Loading branch information
TheJJ committed Aug 12, 2015
1 parent 821c5e3 commit fb2d4b7
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 114 deletions.
1 change: 1 addition & 0 deletions libopenage/audio/dynamic_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "../engine.h"
#include "../log/log.h"
#include "../job/job_manager.h"

namespace openage {
namespace audio {
Expand Down
35 changes: 18 additions & 17 deletions libopenage/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@
#include <FTGL/ftgl.h>
#include <SDL2/SDL.h>

#include "error/error.h"
#include "log/log.h"

#include "config.h"
#include "error/error.h"
#include "font.h"
#include "game_main.h"
#include "generator.h"
#include "job/job_manager.h"
#include "log/log.h"
#include "texture.h"
#include "util/color.h"
#include "util/fps.h"
#include "util/opengl.h"
#include "util/strings.h"
#include "renderer/renderer.h"
#include "renderer/window.h"
#include "screenshot.h"


/**
Expand Down Expand Up @@ -88,14 +92,19 @@ Engine::Engine(util::Dir *data_dir, const char *windowtitle)
// register the engines input manager
this->register_input_action(&this->input_manager);

// create the graphical display
this->window = std::make_unique<renderer::Window>(windowtitle);
this->renderer = std::make_unique<renderer::Renderer>(this->window->get_context());

// renderer has to be notified of window size changes
this->register_resize_action(this->renderer.get());

// initialize job manager with cpucount-2 worker threads
int number_of_worker_threads = SDL_GetCPUCount() - 2;
if (number_of_worker_threads <= 0) {
number_of_worker_threads = 1;
}
this->job_manager = new job::JobManager{number_of_worker_threads};
this->job_manager = std::make_unique<job::JobManager>(number_of_worker_threads);

// initialize audio
auto devices = audio::AudioManager::get_devices();
Expand All @@ -112,7 +121,7 @@ Engine::Engine(util::Dir *data_dir, const char *windowtitle)
this->drawing_huds.value = !this->drawing_huds.value;
});
global_input_context.bind(input::action_t::SCREENSHOT, [this](const input::action_arg_t &) {
this->get_screenshot_manager().save_screenshot();
this->get_screenshot_manager()->save_screenshot();
});
global_input_context.bind(input::action_t::TOGGLE_DEBUG_OVERLAY, [this](const input::action_arg_t &) {
this->drawing_debug_overlay.value = !this->drawing_debug_overlay.value;
Expand Down Expand Up @@ -150,19 +159,14 @@ Engine::Engine(util::Dir *data_dir, const char *windowtitle)
bind_player_switch(input::action_t::SWITCH_TO_PLAYER_8, 8);
}

Engine::~Engine() {
delete this->job_manager;
}
Engine::~Engine() {}

bool Engine::on_resize(coord::window new_size) {
log::log(MSG(dbg) << "engine window resize to " << new_size.x << "x" << new_size.y);

// update engine window size
this->engine_coord_data->window_size = new_size;

// tell the screenshot manager about the new size
this->screenshot_manager.window_size = new_size;

// update camgame window position, set it to center.
this->engine_coord_data->camgame_window = this->engine_coord_data->window_size / 2;

Expand All @@ -173,9 +177,6 @@ bool Engine::on_resize(coord::window new_size) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// update OpenGL viewport: the renderin area
glViewport(0, 0, this->engine_coord_data->window_size.x, this->engine_coord_data->window_size.y);

// set orthographic projection: left, right, bottom, top, near_val, far_val
glOrtho(0, this->engine_coord_data->window_size.x, 0, this->engine_coord_data->window_size.y, 9001, -1);

Expand Down Expand Up @@ -387,15 +388,15 @@ Player *Engine::player_focus() const {
}

job::JobManager *Engine::get_job_manager() {
return this->job_manager;
return this->job_manager.get();
}

audio::AudioManager &Engine::get_audio_manager() {
return this->audio_manager;
}

ScreenshotManager &Engine::get_screenshot_manager() {
return this->screenshot_manager;
ScreenshotManager *Engine::get_screenshot_manager() {
return this->screenshot_manager.get();
}

input::InputManager &Engine::get_input_manager() {
Expand Down
30 changes: 20 additions & 10 deletions libopenage/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,33 @@
#include "coord/vec2f.h"
#include "coord/phys3.h"
#include "coord/window.h"
#include "font.h"
#include "handlers.h"
#include "options.h"
#include "input/input_manager.h"
#include "job/job_manager.h"
#include "renderer/window.h"
#include "util/externalprofiler.h"
#include "util/dir.h"
#include "util/fps.h"
#include "screenshot.h"

namespace openage {

class DrawHandler;
class TickHandler;
class ResizeHandler;

class Generator;
class GameSpec;
class Font;
class GameMain;
class GameSpec;
class Generator;
class Player;
class ScreenshotManager;

namespace job {
class JobManager;
}
namespace renderer {
class Renderer;
class Window;
}

struct coord_data {
coord::window window_size{800, 600};
Expand Down Expand Up @@ -204,7 +210,7 @@ class Engine : public ResizeHandler, public options::OptionNode {
/**
* return this engine's screenshot manager.
*/
ScreenshotManager &get_screenshot_manager();
ScreenshotManager *get_screenshot_manager();

/**
* return this engine's keybind manager.
Expand Down Expand Up @@ -317,7 +323,7 @@ class Engine : public ResizeHandler, public options::OptionNode {
/**
* the engine's screenshot manager.
*/
ScreenshotManager screenshot_manager;
std::unique_ptr<ScreenshotManager> screenshot_manager;

/**
* the engine's audio manager.
Expand All @@ -327,8 +333,7 @@ class Engine : public ResizeHandler, public options::OptionNode {
/**
* the engine's job manager, for asynchronous background task queuing.
*/
job::JobManager *job_manager;

std::unique_ptr<job::JobManager> job_manager;

/**
* the engine's keybind manager.
Expand All @@ -346,6 +351,11 @@ class Engine : public ResizeHandler, public options::OptionNode {
* Also contains the context.
*/
std::unique_ptr<renderer::Window> window;

/**
* The renderer. Accepts all tasks to be drawn on screen.
*/
std::unique_ptr<renderer::Renderer> renderer;
};

} // namespace openage
Expand Down
9 changes: 5 additions & 4 deletions libopenage/game_spec.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#include "assetmanager.h"
#include "engine.h"
#include "game_spec.h"
#include "gamedata/blending_mode.gen.h"
#include "gamedata/string_resource.gen.h"
#include "gamedata/terrain.gen.h"
#include "job/job_manager.h"
#include "rng/global_rng.h"
#include "unit/producer.h"
#include "util/strings.h"
#include "rng/global_rng.h"
#include "assetmanager.h"
#include "game_spec.h"
#include "engine.h"

namespace openage {

Expand Down
2 changes: 0 additions & 2 deletions libopenage/handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

namespace openage {

class Engine;

/**
* superclass for all possible drawing operations in the game.
*/
Expand Down
7 changes: 7 additions & 0 deletions libopenage/renderer/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@ std::unique_ptr<Context> Context::generate(context_type t) {
return nullptr;
}


void Context::resize(const coord::window &new_size) {
this->canvas_size = new_size;
this->resize_canvas(this->canvas_size);
}


}} // namespace openage::renderer
23 changes: 21 additions & 2 deletions libopenage/renderer/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#ifndef OPENAGE_RENDERER_CONTEXT_H_
#define OPENAGE_RENDERER_CONTEXT_H_

#include <SDL2/SDL.h>

#include <memory>
#include <SDL2/SDL.h>

#include "../coord/window.h"
#include "shader.h"
#include "texture.h"

Expand Down Expand Up @@ -77,6 +77,11 @@ class Context {
*/
virtual void set_feature(context_feature feature, bool on) = 0;

/**
* Save this context's framebuffer as a png screenshot.
*/
virtual void screenshot(const std::string &filename) = 0;

/**
* Register some texture data to the context.
* @returns the newly created Texture handle.
Expand All @@ -89,12 +94,26 @@ class Context {
*/
virtual std::shared_ptr<Program> register_program(const ProgramSource &data) = 0;

/**
* Resize the context because the surrounding window size was updated.
*/
void resize(const coord::window &new_size);

protected:
/**
* Perform context-specific calls to resize the drawing canvas.
*/
virtual void resize_canvas(const coord::window &new_size) = 0;

/**
* Type of this context, namely the backend variant.
*/
context_type type;

/**
* Render surface size.
*/
coord::window canvas_size;
};

}} // namespace openage::renderer
Expand Down
53 changes: 53 additions & 0 deletions libopenage/renderer/opengl/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <epoxy/gl.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

#include "program.h"
#include "texture.h"
Expand Down Expand Up @@ -121,6 +122,53 @@ void Context::set_feature(context_feature feature, bool on) {
}


void Context::screenshot(const std::string &filename) {
log::log(MSG(info) << "Saving screenshot to " << filename);

// surface color masks.
int32_t rmask, gmask, bmask, amask;
rmask = 0x000000FF;
gmask = 0x0000FF00;
bmask = 0x00FF0000;
amask = 0xFF000000;

// create output surface which will be stored later.
SDL_Surface *screen = SDL_CreateRGBSurface(
SDL_SWSURFACE,
this->canvas_size.x, this->canvas_size.y,
32, rmask, gmask, bmask, amask
);

size_t pxcount = screen->w * screen->h;

auto pxdata = std::make_unique<uint32_t[]>(pxcount);

// copy the whole framebuffer to our local buffer.
glReadPixels(0, 0,
this->canvas_size.x, this->canvas_size.y,
GL_RGBA, GL_UNSIGNED_BYTE, pxdata.get());

uint32_t *surface_pxls = reinterpret_cast<uint32_t *>(screen->pixels);

// now copy the raw data to the sdl surface.
// we need to invert all pixel rows, but leave column order the same.
for (ssize_t row = 0; row < screen->h; row++) {
ssize_t irow = screen->h - 1 - row;
for (ssize_t col = 0; col < screen->w; col++) {
uint32_t pxl = pxdata[irow * screen->w + col];

// TODO: store the alpha channels in the screenshot,
// is buggy at the moment..
surface_pxls[row * screen->w + col] = pxl | 0xFF000000;
}
}

// call sdl_image for saving the screenshot to png
IMG_SavePNG(screen, filename.c_str());
SDL_FreeSurface(screen);
}


std::shared_ptr<renderer::Texture> Context::register_texture(const TextureData &data) {
std::shared_ptr<renderer::Texture> txt = std::make_shared<opengl::Texture>(data);
return txt;
Expand All @@ -131,6 +179,11 @@ std::shared_ptr<renderer::Program> Context::register_program(const ProgramSource
return txt;
}

void Context::resize_canvas(const coord::window &new_size) {
log::log(MSG(dbg) << "opengl viewport resize to " << new_size.x << "x" << new_size.y);

glViewport(0, 0, new_size.x, new_size.y);
}


}}} // namespace openage::renderer::opengl
Expand Down
Loading

0 comments on commit fb2d4b7

Please sign in to comment.