这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libopenage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ add_subdirectory("testing")
add_subdirectory("unit")
add_subdirectory("util")
add_subdirectory("rng")
add_subdirectory("renderer")

# run codegen, add files to executable
codegen_run()
Expand Down
11 changes: 10 additions & 1 deletion libopenage/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ Engine::Engine(util::Dir *data_dir, const char *windowtitle)
bind_player_switch(input::action_t::SWITCH_TO_PLAYER_6, 6);
bind_player_switch(input::action_t::SWITCH_TO_PLAYER_7, 7);
bind_player_switch(input::action_t::SWITCH_TO_PLAYER_8, 8);

this->text_renderer = std::make_unique<renderer::TextRenderer>();
}

Engine::~Engine() {
Expand Down Expand Up @@ -426,6 +428,8 @@ void Engine::loop() {
}
}
}

this->text_renderer->render();
}
glPopMatrix();

Expand Down Expand Up @@ -496,6 +500,10 @@ input::InputManager &Engine::get_input_manager() {
return this->input_manager;
}

renderer::TextRenderer *Engine::get_text_renderer() {
return this->text_renderer.get();
}

int64_t Engine::lastframe_duration_nsec() {
return this->fps_counter.nsec_lastframe;
}
Expand All @@ -514,7 +522,8 @@ void Engine::render_text(coord::window position, size_t size, const char *format
util::vsformat(format, vl, buf);
va_end(vl);

font->render_static(position.x, position.y, buf.c_str());
this->text_renderer->set_font(font);
this->text_renderer->draw(position.x, position.y, buf);
}

void Engine::move_phys_camera(float x, float y, float amount) {
Expand Down
8 changes: 8 additions & 0 deletions libopenage/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "util/fps.h"
#include "util/profiler.h"
#include "screenshot.h"
#include "renderer/text_renderer.h"

namespace openage {

Expand Down Expand Up @@ -213,6 +214,11 @@ class Engine : public ResizeHandler, public options::OptionNode {
*/
input::InputManager &get_input_manager();

/**
* return this engine's text renderer.
*/
renderer::TextRenderer *get_text_renderer();

/**
* return the number of nanoseconds that have passed
* for rendering the last frame.
Expand Down Expand Up @@ -358,6 +364,8 @@ class Engine : public ResizeHandler, public options::OptionNode {
* the engines profiler
*/
util::Profiler profiler;

std::unique_ptr<renderer::TextRenderer> text_renderer;
};

} // namespace openage
Expand Down
4 changes: 4 additions & 0 deletions libopenage/renderer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_sources(libopenage
color.cpp
text_renderer.cpp
)
54 changes: 54 additions & 0 deletions libopenage/renderer/color.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#include "color.h"

namespace openage {
namespace renderer {

Color::Color()
:
r{0},
g{0},
b{0},
a{255} {
// Empty
}

Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
:
r{r},
g{g},
b{b},
a{a} {
// Empty
}

Color::Color(const Color &other)
:
r{other.r},
g{other.g},
b{other.b},
a{other.a} {
// Empty
}

Color &Color::operator=(const Color &other) {
if (this != &other) {
this->r = other.r;
this->g = other.g;
this->b = other.b;
this->a = other.a;
}

return *this;
}

bool Color::operator==(const Color &other) const {
return this->r == other.r && this->g == other.g && this->b == other.b && this->a == other.a;
}

bool Color::operator!=(const Color &other) const {
return this->r != other.r || this->g != other.g || this->b != other.b || this->a != other.a;
}

}} // openage::renderer
34 changes: 34 additions & 0 deletions libopenage/renderer/color.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#ifndef OPENAGE_RENDERER_COLOR_H_
#define OPENAGE_RENDERER_COLOR_H_

#include <cstdint>

namespace openage {
namespace renderer {

class Color {
public:
Color();

Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a);

Color(const Color &other);

Color &operator=(const Color &other);

bool operator==(const Color &other) const;

bool operator!=(const Color &other) const;

uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;

};

}} // openage::renderer

#endif
107 changes: 107 additions & 0 deletions libopenage/renderer/text_renderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#include "text_renderer.h"

#include <algorithm>
#include <epoxy/gl.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no opengl call in that file, so no need for the epoxy header.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glColor4f is being used in the render method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, sorry.


#include "../log/log.h"
#include "../util/strings.h"
#include "../font.h"

namespace openage {
namespace renderer {

TextRenderer::TextRenderer()
:
current_font{nullptr},
current_color{255, 255, 255, 255},
is_dirty{true} {
// Empty
}

TextRenderer::~TextRenderer() {
// Empty
}

void TextRenderer::set_font(openage::Font *font) {
if (this->current_font == font) {
return;
}

this->current_font = font;
this->is_dirty = true;
}

void TextRenderer::set_color(const Color &color) {
if (this->current_color == color) {
return;
}

this->current_color = color;
this->is_dirty = true;
}

void TextRenderer::draw(coord::window position, const char *format, ...) {
std::string text;
va_list vl;
va_start(vl, format);
util::vsformat(format, vl, text);
va_end(vl);

this->draw(position.x, position.y, text);
}

void TextRenderer::draw(coord::window position, const std::string &text) {
this->draw(position.x, position.y, text);
}

void TextRenderer::draw(int x, int y, const std::string &text) {
if (this->is_dirty) {
this->render_batches.emplace_back(this->current_font, this->current_color);
this->is_dirty = false;
}

this->render_batches.back().passes.emplace_back(x, y, text);
}

void TextRenderer::render() {
// Sort the batches by font
std::sort(std::begin(this->render_batches), std::end(this->render_batches),
[](const text_render_batch &a, const text_render_batch &b) -> bool {
return a.font < b.font;
});

// Merge consecutive batches if font and color values are same
for (auto current_batch = std::begin(this->render_batches); current_batch != std::end(this->render_batches); ) {
auto next_batch = current_batch;
next_batch++;
if (next_batch != std::end(this->render_batches) &&
current_batch->font == next_batch->font &&
current_batch->color == next_batch->color) {
// Merge the render passes of current and next batches and remove the next batch
std::move(std::begin(next_batch->passes),
std::end(next_batch->passes),
std::back_inserter(current_batch->passes));
this->render_batches.erase(next_batch);
} else {
current_batch++;
}
}

// Render all the batches
for (auto &batch : this->render_batches) {
glColor4f(batch.color.r / 255.f,
batch.color.g / 255.f,
batch.color.b / 255.f,
batch.color.a / 255.f);
for (auto &pass : batch.passes) {
batch.font->render_static(pass.x, pass.y, pass.text.c_str());
}
}

// Clear the render batches for next frame
this->render_batches.clear();
}

}} // openage::renderer
110 changes: 110 additions & 0 deletions libopenage/renderer/text_renderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright 2015-2015 the openage authors. See copying.md for legal info.

#ifndef OPENAGE_RENDERER_TEXT_RENDERER_H_
#define OPENAGE_RENDERER_TEXT_RENDERER_H_

#include <vector>
#include <string>

#include "../coord/window.h"
#include "color.h"

namespace openage {

class Font;

namespace renderer {

class TextRenderer {

public:
TextRenderer();

virtual ~TextRenderer();

/**
* Set the font to be used for the future text draw calls.
*
* @param font: the font to be used.
*/
void set_font(Font *font);

/**
* Set the color to be used for the future text draw calls.
*
* @param color: the color to be used.
*/
void set_color(const Color &color);

/**
* Draw a formatted string at the specified position.
*
* @param position: where the text should be displayed.
* @param format: the text format
*/
void draw(coord::window position, const char *format, ...);

/**
* Draw text at the specified position.
*
* @param position: where the text should be displayed.
* @param text: the text to be displayed.
*/
void draw(coord::window position, const std::string &text);

/**
* Draw text at the specified position.
*
* @param x: the position in x-direction.
* @param y: the position in y-direction.
* @param text: the text to be displayed.
*/
void draw(int x, int y, const std::string &text);

/**
* Render all the text draw requests made during the frame.
*/
void render();

private:
/**
* A single text draw request containing the text and position.
*/
struct text_render_batch_pass {
int x;
int y;
std::string text;

text_render_batch_pass(int x, int y, const std::string &text)
:
x{x},
y{y},
text{text} {
}
};

/**
* The set of text draw requests with the same font and color.
*/
struct text_render_batch {
openage::Font *font;
Color color;
std::vector<text_render_batch_pass> passes;

text_render_batch(openage::Font *font, const Color &color)
:
font{font},
color{color} {
}
};

Font *current_font;
Color current_color;
bool is_dirty;
std::vector<text_render_batch> render_batches;

};

}} // openage::renderer

#endif