✨ 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',
|
||||
sources: [
|
||||
'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: [
|
||||
dependency('glew'),
|
||||
dependency('sdl2'),
|
||||
dependency('SDL2_image'),
|
||||
dependency('glm'),
|
||||
],
|
||||
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
|
||||
#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_DATADIR std::filesystem::path("@datadir@")
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#define RID_ERROR(NAME) \
|
||||
struct NAME : public std::runtime_error { \
|
||||
explicit NAME (std::string const& what) : std::runtime_error { what } {} \
|
||||
}
|
||||
|
||||
|
||||
#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 "conf.hpp"
|
||||
#include "Game.hpp"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::cout << "Rest In Dust V" << RID_VERSION << std::endl;
|
||||
return 0;
|
||||
rid::Game game;
|
||||
return game.exec();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue