✨ Draw textures.
parent
92887779ba
commit
a9567e703c
Binary file not shown.
After Width: | Height: | Size: 657 B |
|
@ -0,0 +1,19 @@
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
in vec4 _color;
|
||||||
|
in vec2 _tex_coord;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
uniform int has_texture;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if (has_texture == 1)
|
||||||
|
{
|
||||||
|
frag_color = _color * texture(sampler, _tex_coord);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frag_color = _color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
in vec3 pos;
|
||||||
|
in vec4 color;
|
||||||
|
in vec2 tex_coord;
|
||||||
|
|
||||||
|
out vec4 _color;
|
||||||
|
out vec2 _tex_coord;
|
||||||
|
|
||||||
|
uniform mat4 proj;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = proj * vec4(pos, 1.0);
|
||||||
|
_color = color;
|
||||||
|
_tex_coord = tex_coord;
|
||||||
|
}
|
17
meson.build
17
meson.build
|
@ -24,8 +24,25 @@ executable(
|
||||||
'rest-in-dust',
|
'rest-in-dust',
|
||||||
sources: [
|
sources: [
|
||||||
'src/main.cpp',
|
'src/main.cpp',
|
||||||
|
|
||||||
|
# game
|
||||||
|
'src/Game.cpp',
|
||||||
|
'src/BaseScene.cpp',
|
||||||
|
|
||||||
|
# arena
|
||||||
|
'src/arena/Arena.cpp',
|
||||||
|
|
||||||
|
# gfx
|
||||||
|
'src/gfx/Window.cpp',
|
||||||
|
'src/gfx/Shaders.cpp',
|
||||||
|
'src/gfx/Canvas.cpp',
|
||||||
|
'src/gfx/Texture.cpp',
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
dependency('glew'),
|
||||||
|
dependency('sdl2'),
|
||||||
|
dependency('SDL2_image'),
|
||||||
|
dependency('glm'),
|
||||||
],
|
],
|
||||||
install: true
|
install: true
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "BaseScene.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ BaseScene::BaseScene(Game& game)
|
||||||
|
: m_game { game }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ BaseScene::~BaseScene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef rid_BASESCENE_HPP
|
||||||
|
#define rid_BASESCENE_HPP
|
||||||
|
|
||||||
|
#include "gfx/Window.hpp"
|
||||||
|
#include "Game.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
class BaseScene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit BaseScene(Game& game);
|
||||||
|
virtual ~BaseScene();
|
||||||
|
|
||||||
|
virtual void update(float) {};
|
||||||
|
virtual void draw(Window const&) {};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Game& m_game;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "Game.hpp"
|
||||||
|
#include "BaseScene.hpp"
|
||||||
|
#include "arena/Arena.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ Game::Game()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Game::~Game()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int Game::exec()
|
||||||
|
{
|
||||||
|
m_window = std::make_unique<Window>(640, 480);
|
||||||
|
SDL_Event event;
|
||||||
|
float dt = 0.0f;
|
||||||
|
|
||||||
|
set_scene(std::make_unique<Arena>(*this));
|
||||||
|
|
||||||
|
while (m_window->is_open())
|
||||||
|
{
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
if (event.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
m_window->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_current_scene)
|
||||||
|
{
|
||||||
|
m_current_scene->update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_window->clear();
|
||||||
|
|
||||||
|
if (m_current_scene)
|
||||||
|
{
|
||||||
|
m_current_scene->draw(*m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_window->update();
|
||||||
|
|
||||||
|
if (m_next_scene)
|
||||||
|
{
|
||||||
|
m_current_scene = std::move(m_next_scene);
|
||||||
|
m_next_scene.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto elapsed = std::chrono::steady_clock::now() - now;
|
||||||
|
dt = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count() / 1000000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::set_scene(std::unique_ptr<BaseScene> scene)
|
||||||
|
{
|
||||||
|
m_next_scene = std::move(scene);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef rid_GAME_HPP
|
||||||
|
#define rid_GAME_HPP
|
||||||
|
|
||||||
|
#include "conf.hpp"
|
||||||
|
#include "gfx/Window.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
class BaseScene;
|
||||||
|
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Game();
|
||||||
|
virtual ~Game();
|
||||||
|
|
||||||
|
int exec();
|
||||||
|
|
||||||
|
// Scenes management
|
||||||
|
// -----------------
|
||||||
|
void set_scene(std::unique_ptr<BaseScene> scene);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Window> m_window;
|
||||||
|
std::unique_ptr<BaseScene> m_current_scene;
|
||||||
|
std::unique_ptr<BaseScene> m_next_scene;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "Arena.hpp"
|
||||||
|
#include "conf.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ Arena::Arena(Game& game)
|
||||||
|
: BaseScene(game)
|
||||||
|
, m_canvas { std::make_unique<Canvas>() }
|
||||||
|
{
|
||||||
|
auto tex = std::make_unique<Texture>();
|
||||||
|
tex->load(RID_DATADIR / "assets" / "images" / "walk_0.png");
|
||||||
|
m_canvas->set_texture(std::move(tex));
|
||||||
|
|
||||||
|
m_canvas->draw_tex(glm::vec2 {512.0f, 512.0f},
|
||||||
|
glm::vec2 {96.0f, 96.0f},
|
||||||
|
glm::vec4 {1.0f, 1.0f, 1.0f, 1.0f},
|
||||||
|
glm::vec2 {0.f, 0.0f},
|
||||||
|
glm::vec2 {32.0f, 32.0f});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Arena::~Arena()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Arena::update(float) /*override*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Arena::draw(Window const& win) /*override*/
|
||||||
|
{
|
||||||
|
win.draw(*m_canvas);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef rid_ARENA_HPP
|
||||||
|
#define rid_ARENA_HPP
|
||||||
|
|
||||||
|
#include "conf.hpp"
|
||||||
|
#include "../BaseScene.hpp"
|
||||||
|
#include "../gfx/Canvas.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
class Arena: public BaseScene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Arena(Game& game);
|
||||||
|
virtual ~Arena();
|
||||||
|
|
||||||
|
void update(float dt) override;
|
||||||
|
void draw(Window const& win) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Canvas> m_canvas;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,10 +1,26 @@
|
||||||
#ifndef rid_CONF_HPP
|
#ifndef rid_CONF_HPP
|
||||||
#define rid_CONF_HPP
|
#define rid_CONF_HPP
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#define RID_VERSION std::string("@version@")
|
#define RID_VERSION std::string("@version@")
|
||||||
#define RID_DATADIR std::filesystem::path("@datadir@")
|
#define RID_DATADIR std::filesystem::path("@datadir@")
|
||||||
|
|
||||||
#include <filesystem>
|
#define RID_ERROR(NAME) \
|
||||||
#include <string>
|
struct NAME : public std::runtime_error { \
|
||||||
|
explicit NAME (std::string const& what) : std::runtime_error { what } {} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
#include "Canvas.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ Canvas::Canvas()
|
||||||
|
: m_shaders { std::make_unique<Shaders>("canvas") }
|
||||||
|
{
|
||||||
|
glGenVertexArrays(1, &m_vao);
|
||||||
|
use();
|
||||||
|
glGenBuffers(1, &m_vbo);
|
||||||
|
|
||||||
|
m_shaders->use();
|
||||||
|
m_shaders->set_int("has_texture", 0);
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Canvas::~Canvas()
|
||||||
|
{
|
||||||
|
glDeleteVertexArrays(1, &m_vao);
|
||||||
|
glDeleteBuffers(1, &m_vbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::set_texture(std::unique_ptr<Texture> texture)
|
||||||
|
{
|
||||||
|
m_shaders->use();
|
||||||
|
m_shaders->set_int("has_texture", 1);
|
||||||
|
m_texture = std::move(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::draw_tex(glm::vec2 pos,
|
||||||
|
glm::vec2 size,
|
||||||
|
glm::vec4 color,
|
||||||
|
glm::vec2 tex_pos,
|
||||||
|
glm::vec2 tex_size)
|
||||||
|
{
|
||||||
|
// A -- B
|
||||||
|
// | |
|
||||||
|
// D -- C
|
||||||
|
|
||||||
|
float tx = tex_pos.x;
|
||||||
|
float ty = tex_pos.y;
|
||||||
|
float tw = tex_size.x;
|
||||||
|
float th = tex_size.y;
|
||||||
|
|
||||||
|
if (m_texture)
|
||||||
|
{
|
||||||
|
tx /= static_cast<float>(m_texture->width());
|
||||||
|
ty /= static_cast<float>(m_texture->height());
|
||||||
|
tw /= static_cast<float>(m_texture->width());
|
||||||
|
th /= static_cast<float>(m_texture->height());
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex a {
|
||||||
|
pos.x - size.x/2.0f, pos.y - size.y/2.0f, 0.0f,
|
||||||
|
color.x, color.y, color.z, color.w,
|
||||||
|
tx, ty
|
||||||
|
};
|
||||||
|
|
||||||
|
Vertex b {
|
||||||
|
pos.x + size.x/2.0f, pos.y - size.y/2.0f, 0.0f,
|
||||||
|
color.x, color.y, color.z, color.w,
|
||||||
|
tx + tw, ty
|
||||||
|
};
|
||||||
|
|
||||||
|
Vertex c {
|
||||||
|
pos.x + size.x/2.0f, pos.y + size.y/2.0f, 0.0f,
|
||||||
|
color.x, color.y, color.z, color.w,
|
||||||
|
tx + tw, ty + th
|
||||||
|
};
|
||||||
|
|
||||||
|
Vertex d {
|
||||||
|
pos.x - size.x/2.0f, pos.y + size.y/2.0f, 0.0f,
|
||||||
|
color.x, color.y, color.z, color.w,
|
||||||
|
tx, ty + th
|
||||||
|
};
|
||||||
|
|
||||||
|
m_vertices.push_back(a);
|
||||||
|
m_vertices.push_back(b);
|
||||||
|
m_vertices.push_back(c);
|
||||||
|
|
||||||
|
m_vertices.push_back(a);
|
||||||
|
m_vertices.push_back(c);
|
||||||
|
m_vertices.push_back(d);
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::draw(glm::mat4 transform) const
|
||||||
|
{
|
||||||
|
use();
|
||||||
|
m_shaders->set_mat4("proj", transform);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::use() const
|
||||||
|
{
|
||||||
|
glBindVertexArray(m_vao);
|
||||||
|
m_shaders->use();
|
||||||
|
|
||||||
|
if (m_texture)
|
||||||
|
{
|
||||||
|
m_texture->use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::update() const
|
||||||
|
{
|
||||||
|
use();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
sizeof(Vertex) * m_vertices.size(),
|
||||||
|
m_vertices.data(),
|
||||||
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Position
|
||||||
|
// --------
|
||||||
|
GLint pos = m_shaders->attrib("pos");
|
||||||
|
glEnableVertexAttribArray(pos);
|
||||||
|
glVertexAttribPointer(pos,
|
||||||
|
3,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(Vertex),
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
// Color
|
||||||
|
// -----
|
||||||
|
GLint color = m_shaders->attrib("color");
|
||||||
|
glEnableVertexAttribArray(color);
|
||||||
|
glVertexAttribPointer(color,
|
||||||
|
4,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(Vertex),
|
||||||
|
reinterpret_cast<void*>(offsetof(Vertex, r)));
|
||||||
|
|
||||||
|
// Tex coord
|
||||||
|
// ---------
|
||||||
|
GLint tex = m_shaders->attrib("tex_coord");
|
||||||
|
glEnableVertexAttribArray(tex);
|
||||||
|
glVertexAttribPointer(tex,
|
||||||
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(Vertex),
|
||||||
|
reinterpret_cast<void*>(offsetof(Vertex, u)));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef rid_CANVAS_HPP
|
||||||
|
#define rid_CANVAS_HPP
|
||||||
|
|
||||||
|
#include "conf.hpp"
|
||||||
|
#include "Shaders.hpp"
|
||||||
|
#include "Texture.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
float x; float y; float z;
|
||||||
|
float r; float g; float b; float a;
|
||||||
|
float u; float v;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Canvas
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Canvas();
|
||||||
|
virtual ~Canvas();
|
||||||
|
|
||||||
|
void set_texture(std::unique_ptr<Texture> texture);
|
||||||
|
|
||||||
|
// Draw stuff
|
||||||
|
// ----------
|
||||||
|
void draw_tex(glm::vec2 pos,
|
||||||
|
glm::vec2 size,
|
||||||
|
glm::vec4 color,
|
||||||
|
glm::vec2 tex_pos,
|
||||||
|
glm::vec2 tex_size);
|
||||||
|
|
||||||
|
void draw(glm::mat4 transform) const;
|
||||||
|
void clear() { m_vertices.clear(); update(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Shaders> m_shaders;
|
||||||
|
std::vector<Vertex> m_vertices;
|
||||||
|
std::unique_ptr<Texture> m_texture;
|
||||||
|
GLuint m_vao;
|
||||||
|
GLuint m_vbo;
|
||||||
|
|
||||||
|
void use() const;
|
||||||
|
void update() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include "Shaders.hpp"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ Shaders::Shaders(std::string const& name)
|
||||||
|
: m_program { glCreateProgram() }
|
||||||
|
{
|
||||||
|
use();
|
||||||
|
|
||||||
|
load_shader(GL_VERTEX_SHADER, RID_DATADIR / "assets" / "shaders" / (name + "_vertex.glsl"));
|
||||||
|
load_shader(GL_FRAGMENT_SHADER, RID_DATADIR / "assets" / "shaders" / (name + "_fragment.glsl"));
|
||||||
|
|
||||||
|
glLinkProgram(m_program);
|
||||||
|
|
||||||
|
GLint status = GL_FALSE;
|
||||||
|
glGetProgramiv(m_program, GL_LINK_STATUS, &status);
|
||||||
|
|
||||||
|
if (status == GL_FALSE)
|
||||||
|
{
|
||||||
|
size_t const SZ = 256;
|
||||||
|
char msg[SZ];
|
||||||
|
|
||||||
|
glGetProgramInfoLog(m_program, SZ, nullptr, msg);
|
||||||
|
|
||||||
|
throw shaders_error {std::string() + "Cannot link shader program '" + name + "': " + msg};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Shaders::~Shaders()
|
||||||
|
{
|
||||||
|
glDeleteProgram(m_program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shaders::use() const
|
||||||
|
{
|
||||||
|
glUseProgram(m_program);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Shaders::attrib(std::string const& name) const
|
||||||
|
{
|
||||||
|
GLint value = glGetAttribLocation(m_program, name.c_str());
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
throw shaders_error {"Cannot find attribute '" + name + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Shaders::uniform(std::string const& name) const
|
||||||
|
{
|
||||||
|
GLint value = glGetUniformLocation(m_program, name.c_str());
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
throw shaders_error {"Cannot find uniform '" + name + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shaders::set_mat4(std::string const& name, glm::mat4 mat)
|
||||||
|
{
|
||||||
|
GLint loc = uniform(name);
|
||||||
|
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(mat));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shaders::set_int(std::string const& name, int value)
|
||||||
|
{
|
||||||
|
GLint loc = uniform(name);
|
||||||
|
glUniform1i(loc, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Shaders::load_shader(GLenum shader_type,
|
||||||
|
std::filesystem::path const& shader_path)
|
||||||
|
{
|
||||||
|
GLuint shader = glCreateShader(shader_type);
|
||||||
|
|
||||||
|
if (!std::filesystem::is_regular_file(shader_path))
|
||||||
|
{
|
||||||
|
throw shaders_error {"Cannot load shader: '"
|
||||||
|
+ shader_path.string() + "' is not a regular file."};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file {shader_path};
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
throw shaders_error {"Cannot load shader: cannot open '"
|
||||||
|
+ shader_path.string() + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << file.rdbuf();
|
||||||
|
|
||||||
|
std::string source = ss.str();
|
||||||
|
char const* sources[] = { source.c_str() };
|
||||||
|
|
||||||
|
glShaderSource(shader, 1, sources, nullptr);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint status = GL_FALSE;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||||
|
|
||||||
|
if (status == GL_FALSE)
|
||||||
|
{
|
||||||
|
size_t const SZ = 256;
|
||||||
|
char msg[SZ];
|
||||||
|
|
||||||
|
glGetShaderInfoLog(shader, SZ, nullptr, msg);
|
||||||
|
|
||||||
|
throw shaders_error {"Cannot compile shader '" + shader_path.string() + "': " + msg};
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(m_program, shader);
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef rid_SHADERS_HPP
|
||||||
|
#define rid_SHADERS_HPP
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "conf.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
RID_ERROR(shaders_error);
|
||||||
|
|
||||||
|
class Shaders
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Shaders(std::string const& name);
|
||||||
|
virtual ~Shaders();
|
||||||
|
|
||||||
|
void use() const;
|
||||||
|
GLint attrib(std::string const& name) const;
|
||||||
|
GLint uniform(std::string const& name) const;
|
||||||
|
|
||||||
|
void set_mat4(std::string const& name, glm::mat4 mat);
|
||||||
|
void set_int(std::string const& name, int value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint m_program;
|
||||||
|
|
||||||
|
GLuint load_shader(GLenum shader_type, std::filesystem::path const& shader_path);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "Texture.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ Texture::Texture()
|
||||||
|
{
|
||||||
|
glGenTextures(1, &m_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Texture::~Texture()
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &m_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::load(std::filesystem::path const& tex_path)
|
||||||
|
{
|
||||||
|
SDL_Surface* surface = IMG_Load(tex_path.c_str());
|
||||||
|
|
||||||
|
surface = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
|
||||||
|
|
||||||
|
if (!surface)
|
||||||
|
{
|
||||||
|
throw texture_error {"Cannot load texture '" + tex_path.string() + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
m_width = surface->w;
|
||||||
|
m_height = surface->h;
|
||||||
|
|
||||||
|
use();
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_RGBA,
|
||||||
|
surface->w,
|
||||||
|
surface->h,
|
||||||
|
0,
|
||||||
|
GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
surface->pixels);
|
||||||
|
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::use() const
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef rid_TEXTURE_HPP
|
||||||
|
#define rid_TEXTURE_HPP
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
|
||||||
|
#include "conf.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
RID_ERROR(texture_error);
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Texture();
|
||||||
|
virtual ~Texture();
|
||||||
|
|
||||||
|
int width() const { return m_width; }
|
||||||
|
int height() const { return m_height; }
|
||||||
|
|
||||||
|
void load(std::filesystem::path const& tex_path);
|
||||||
|
void use() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint m_texture;
|
||||||
|
int m_width = 0;
|
||||||
|
int m_height = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include "Window.hpp"
|
||||||
|
#include "SDL_image.h"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
/*explicit*/ Window::Window(int width, int height)
|
||||||
|
: m_width { width }
|
||||||
|
, m_height { height }
|
||||||
|
{
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
|
{
|
||||||
|
throw display_error {"Cannot initialize SDL 2."};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init SDL2 image
|
||||||
|
{
|
||||||
|
int flags = IMG_INIT_PNG;
|
||||||
|
int status = IMG_Init(flags);
|
||||||
|
|
||||||
|
if ( (status & flags) != flags )
|
||||||
|
{
|
||||||
|
throw display_error {"Cannot initialize sdl2 image."};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const title = "Rest In Dust v" + RID_VERSION;
|
||||||
|
|
||||||
|
m_window = SDL_CreateWindow(title.c_str(),
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
m_width, m_height,
|
||||||
|
SDL_WINDOW_SHOWN
|
||||||
|
| SDL_WINDOW_OPENGL
|
||||||
|
| SDL_WINDOW_MAXIMIZED);
|
||||||
|
|
||||||
|
if (!m_window)
|
||||||
|
{
|
||||||
|
throw display_error {"Cannot create SDL2 window."};
|
||||||
|
}
|
||||||
|
|
||||||
|
m_context = SDL_GL_CreateContext(m_window);
|
||||||
|
|
||||||
|
if (!m_context)
|
||||||
|
{
|
||||||
|
throw display_error {"Cannot create SDL2 GL context."};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glewInit() != GLEW_OK)
|
||||||
|
{
|
||||||
|
throw display_error {"Cannot initialize GLEW."};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Window::~Window()
|
||||||
|
{
|
||||||
|
SDL_GL_DeleteContext(m_context);
|
||||||
|
IMG_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::draw(Canvas const& canvas) const
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
SDL_GetWindowSize(m_window, &w, &h);
|
||||||
|
glm::mat4 proj = glm::ortho(0.0f, static_cast<float>(w),
|
||||||
|
static_cast<float>(h), 0.0f);
|
||||||
|
|
||||||
|
|
||||||
|
canvas.draw(proj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::clear(glm::vec4 const& color) const
|
||||||
|
{
|
||||||
|
glClearColor(color.x, color.y, color.z, color.w);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::update() const
|
||||||
|
{
|
||||||
|
SDL_GL_SwapWindow(m_window);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef rid_WINDOW_HPP
|
||||||
|
#define rid_WINDOW_HPP
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include "conf.hpp"
|
||||||
|
#include "Canvas.hpp"
|
||||||
|
|
||||||
|
namespace rid
|
||||||
|
{
|
||||||
|
RID_ERROR(display_error);
|
||||||
|
|
||||||
|
class Window
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Window(int width, int height);
|
||||||
|
virtual ~Window();
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
// -------
|
||||||
|
void draw(Canvas const& canvas) const;
|
||||||
|
|
||||||
|
// Update
|
||||||
|
// ------
|
||||||
|
void clear(glm::vec4 const& color = {0.0f, 0.0f, 0.0f, 1.0f}) const;
|
||||||
|
void update() const;
|
||||||
|
|
||||||
|
// State
|
||||||
|
// -----
|
||||||
|
bool is_open() const { return m_is_open; }
|
||||||
|
void close() { m_is_open = false; }
|
||||||
|
|
||||||
|
// Dimensions
|
||||||
|
// ----------
|
||||||
|
int width() const { return m_width; }
|
||||||
|
int height() const { return m_height; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Window* m_window = nullptr;
|
||||||
|
SDL_GLContext m_context = nullptr;
|
||||||
|
int m_width;
|
||||||
|
int m_height;
|
||||||
|
bool m_is_open = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,8 +1,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "conf.hpp"
|
#include "Game.hpp"
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
std::cout << "Rest In Dust V" << RID_VERSION << std::endl;
|
rid::Game game;
|
||||||
return 0;
|
return game.exec();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue