mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-04-20 01:43:12 +02:00
Added a small opengl test app that I wrote a while ago, to be further processed into an opengl renderer.
This commit is contained in:
parent
19a70a5507
commit
70ffbbae20
117
core/renderer/opengl/application.cpp
Normal file
117
core/renderer/opengl/application.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "application.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
Application *Application::_instance = nullptr;
|
||||
|
||||
void Application::event(const SDL_Event &ev) {
|
||||
if (ev.type == SDL_QUIT) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
scene->event(ev);
|
||||
}
|
||||
|
||||
void Application::update(float delta) {
|
||||
scene->update(delta);
|
||||
}
|
||||
|
||||
void Application::render() {
|
||||
scene->render();
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
void Application::main_loop() {
|
||||
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
//handle input
|
||||
SDL_Event current_event;
|
||||
|
||||
while (SDL_PollEvent(¤t_event)) {
|
||||
event(current_event);
|
||||
}
|
||||
|
||||
//update world
|
||||
update(frame_delta);
|
||||
|
||||
//render
|
||||
render();
|
||||
|
||||
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> elapsed_seconds = end - start;
|
||||
|
||||
double t = elapsed_seconds.count();
|
||||
double tfps = 1.0 / static_cast<float>(target_fps);
|
||||
double remaining = tfps - t;
|
||||
|
||||
if (remaining > 0) {
|
||||
Uint32 fms = static_cast<Uint32>(remaining * 1000.0);
|
||||
|
||||
frame_delta = tfps;
|
||||
|
||||
SDL_Delay(fms);
|
||||
} else {
|
||||
frame_delta = t;
|
||||
}
|
||||
}
|
||||
|
||||
Application *Application::get_singleton() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
Application::Application() {
|
||||
_instance = this;
|
||||
|
||||
running = true;
|
||||
target_fps = 60;
|
||||
|
||||
scene = nullptr;
|
||||
|
||||
frame_delta = 0;
|
||||
|
||||
SDL_SetMainReady();
|
||||
int error = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
|
||||
if (error) {
|
||||
SDL_Log("SDL_Init: %s", SDL_GetError());
|
||||
|
||||
running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
#if _WIN64
|
||||
//Use OpenGl 2.1
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
#else
|
||||
//Use OpenGl ES 2.0
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow("SDL + OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
|
||||
if (!window) {
|
||||
SDL_Log("SDL_CreateWindow: %s", SDL_GetError());
|
||||
|
||||
running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
context = SDL_GL_CreateContext(window);
|
||||
|
||||
#ifdef _WIN64
|
||||
gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
window = nullptr;
|
||||
|
||||
SDL_Quit();
|
||||
}
|
38
core/renderer/opengl/application.h
Normal file
38
core/renderer/opengl/application.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
#include "sdl.inc.h"
|
||||
#include "opengl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "scene.h"
|
||||
|
||||
class Application {
|
||||
public:
|
||||
bool running;
|
||||
int target_fps;
|
||||
|
||||
virtual void event(const SDL_Event &ev);
|
||||
virtual void update(float delta);
|
||||
virtual void render();
|
||||
|
||||
void main_loop();
|
||||
|
||||
Application();
|
||||
virtual ~Application();
|
||||
|
||||
Scene *scene;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_GLContext context;
|
||||
|
||||
static Application* get_singleton();
|
||||
|
||||
double frame_delta;
|
||||
|
||||
protected:
|
||||
static Application* _instance;
|
||||
};
|
||||
|
||||
#endif
|
95
core/renderer/opengl/camera.cpp
Normal file
95
core/renderer/opengl/camera.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include "camera.h"
|
||||
|
||||
#include "./glm/gtc/matrix_transform.hpp"
|
||||
|
||||
Camera *Camera::current_camera = nullptr;
|
||||
|
||||
void Camera::bind() {
|
||||
make_current();
|
||||
|
||||
model_view_matrix = glm::mat4(1);
|
||||
}
|
||||
|
||||
void Camera::make_current() {
|
||||
current_camera = this;
|
||||
}
|
||||
|
||||
Camera::Camera() {
|
||||
width = 2;
|
||||
height = 2;
|
||||
fov = glm::radians(45.0);
|
||||
|
||||
position = glm::vec3(0, 0, 0);
|
||||
rotation = glm::vec3(0, 0, 0);
|
||||
scale = glm::vec3(1, 1, 1);
|
||||
}
|
||||
Camera::~Camera() {
|
||||
}
|
||||
|
||||
void OrthographicCamera::bind() {
|
||||
Camera::bind();
|
||||
|
||||
//fixed function pipeline
|
||||
//glMatrixMode(GL_PROJECTION);
|
||||
//glLoadIdentity();
|
||||
|
||||
//glOrtho(bottom_left.x, top_right.x, bottom_left.y, top_right.y, near, far);
|
||||
|
||||
//glTranslatef(position.x, position.y, 0);
|
||||
//glRotatef(rotation.x, 1, 0, 0);
|
||||
//glRotatef(rotation.y, 0, 1, 0);
|
||||
//glRotatef(rotation.z, 0, 0, 1);
|
||||
|
||||
//glScalef(scale.x, scale.y, scale.z);
|
||||
|
||||
projection_matrix = glm::ortho<float>(-(width / 2.0), width / 2.0, -(height / 2.0), height / 2.0);
|
||||
|
||||
projection_matrix = glm::translate(projection_matrix, -position);
|
||||
|
||||
projection_matrix = glm::rotate(projection_matrix, rotation.x, glm::vec3(1, 0, 0));
|
||||
projection_matrix = glm::rotate(projection_matrix, rotation.y, glm::vec3(0, 1, 0));
|
||||
projection_matrix = glm::rotate(projection_matrix, rotation.z, glm::vec3(0, 0, 1));
|
||||
|
||||
projection_matrix = glm::scale(projection_matrix, scale);
|
||||
}
|
||||
|
||||
OrthographicCamera::OrthographicCamera() : Camera() {
|
||||
}
|
||||
|
||||
OrthographicCamera::~OrthographicCamera() {
|
||||
}
|
||||
|
||||
void PerspectiveCamera::bind() {
|
||||
Camera::bind();
|
||||
|
||||
//fixed fucntion pipeline
|
||||
//glMatrixMode(GL_PROJECTION);
|
||||
//glLoadIdentity();
|
||||
|
||||
//glFrustum(bottom_left.x, top_right.x, bottom_left.y, top_right.y, near, far);
|
||||
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
//glRotatef(rotation.x, 1, 0, 0);
|
||||
//glRotatef(rotation.y, 0, 1, 0);
|
||||
//glRotatef(rotation.z, 0, 0, 1);
|
||||
|
||||
//glScalef(scale.x, scale.y, scale.z);
|
||||
|
||||
projection_matrix = glm::perspectiveFov<float>(fov, width, height, near, far);
|
||||
|
||||
projection_matrix = glm::translate(projection_matrix, -position);
|
||||
|
||||
projection_matrix = glm::rotate(projection_matrix, rotation.x, glm::vec3(1, 0, 0));
|
||||
projection_matrix = glm::rotate(projection_matrix, rotation.y, glm::vec3(0, 1, 0));
|
||||
projection_matrix = glm::rotate(projection_matrix, rotation.z, glm::vec3(0, 0, 1));
|
||||
|
||||
projection_matrix = glm::scale(projection_matrix, scale);
|
||||
}
|
||||
|
||||
PerspectiveCamera::PerspectiveCamera() : Camera() {
|
||||
near = 0.1;
|
||||
far = 10;
|
||||
}
|
||||
|
||||
PerspectiveCamera::~PerspectiveCamera() {
|
||||
}
|
52
core/renderer/opengl/camera.h
Normal file
52
core/renderer/opengl/camera.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include "opengl.h"
|
||||
|
||||
#include "./glm/vec3.hpp"
|
||||
#include "./glm/matrix.hpp"
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
virtual void bind();
|
||||
|
||||
void make_current();
|
||||
|
||||
Camera();
|
||||
virtual ~Camera();
|
||||
|
||||
float width;
|
||||
float height;
|
||||
float fov;
|
||||
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
|
||||
static Camera *current_camera;
|
||||
|
||||
glm::mat4x4 projection_matrix;
|
||||
glm::mat4x4 model_view_matrix;
|
||||
};
|
||||
|
||||
class OrthographicCamera : public Camera {
|
||||
public:
|
||||
|
||||
void bind();
|
||||
|
||||
OrthographicCamera();
|
||||
~OrthographicCamera();
|
||||
};
|
||||
|
||||
class PerspectiveCamera : public Camera {
|
||||
public:
|
||||
float near;
|
||||
float far;
|
||||
|
||||
void bind();
|
||||
|
||||
PerspectiveCamera();
|
||||
~PerspectiveCamera();
|
||||
};
|
||||
|
||||
#endif
|
68
core/renderer/opengl/color_material.h
Normal file
68
core/renderer/opengl/color_material.h
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef COLOR_MATERIAL_H
|
||||
#define COLOR_MATERIAL_H
|
||||
|
||||
#include "material.h"
|
||||
#include "glm/vec4.hpp"
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "./glm/gtc/type_ptr.hpp"
|
||||
|
||||
class ColorMaterial : public Material {
|
||||
|
||||
public:
|
||||
int get_material_id() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void bind_uniforms() {
|
||||
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
|
||||
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
|
||||
}
|
||||
|
||||
void setup_uniforms() {
|
||||
projection_matrix_location = get_uniform("u_proj_matrix");
|
||||
model_view_matrix_location = get_uniform("u_model_view_matrix");
|
||||
}
|
||||
|
||||
const GLchar** get_vertex_shader_source() {
|
||||
static const GLchar *vertex_shader_source[] = {
|
||||
"uniform mat4 u_proj_matrix;\n"
|
||||
"uniform mat4 u_model_view_matrix;\n"
|
||||
"\n"
|
||||
"attribute vec4 a_position;\n"
|
||||
"attribute vec4 a_color;\n"
|
||||
"\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" v_color = a_color;\n"
|
||||
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
return vertex_shader_source;
|
||||
}
|
||||
|
||||
const GLchar** get_fragment_shader_source() {
|
||||
static const GLchar *fragment_shader_source[] = {
|
||||
"precision mediump float;"
|
||||
"varying vec4 v_color;\n"
|
||||
"\n"
|
||||
"void main() { gl_FragColor = v_color; }\n"
|
||||
};
|
||||
|
||||
return fragment_shader_source;
|
||||
}
|
||||
|
||||
ColorMaterial() {
|
||||
color = glm::vec4(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
GLint projection_matrix_location;
|
||||
GLint model_view_matrix_location;
|
||||
|
||||
glm::vec4 color;
|
||||
};
|
||||
|
||||
#endif
|
66
core/renderer/opengl/colored_material.h
Normal file
66
core/renderer/opengl/colored_material.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef COLORED_MATERIAL_H
|
||||
#define COLORED_MATERIAL_H
|
||||
|
||||
#include "material.h"
|
||||
#include "glm/vec4.hpp"
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "./glm/gtc/type_ptr.hpp"
|
||||
|
||||
class ColoredMaterial : public Material {
|
||||
|
||||
public:
|
||||
int get_material_id() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void bind_uniforms() {
|
||||
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
|
||||
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
|
||||
|
||||
glUniform4f(tri_color_uniform_location, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void setup_uniforms() {
|
||||
projection_matrix_location = get_uniform("u_proj_matrix");
|
||||
model_view_matrix_location = get_uniform("u_model_view_matrix");
|
||||
|
||||
tri_color_uniform_location = get_uniform("fragment_color");
|
||||
}
|
||||
|
||||
const GLchar** get_vertex_shader_source() {
|
||||
static const GLchar *vertex_shader_source[] = {
|
||||
"uniform mat4 u_proj_matrix;\n"
|
||||
"uniform mat4 u_model_view_matrix;\n"
|
||||
"\n"
|
||||
"attribute vec4 a_position;\n"
|
||||
"void main() { gl_Position = u_proj_matrix * u_model_view_matrix * a_position; }"
|
||||
};
|
||||
|
||||
return vertex_shader_source;
|
||||
}
|
||||
|
||||
const GLchar** get_fragment_shader_source() {
|
||||
static const GLchar *fragment_shader_source[] = {
|
||||
"precision mediump float;"
|
||||
"uniform vec4 fragment_color = vec4(1, 1, 1, 1);"
|
||||
""
|
||||
"void main() { gl_FragColor = fragment_color; }"
|
||||
};
|
||||
|
||||
return fragment_shader_source;
|
||||
}
|
||||
|
||||
ColoredMaterial() {
|
||||
color = glm::vec4(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
GLint projection_matrix_location;
|
||||
GLint model_view_matrix_location;
|
||||
|
||||
GLint tri_color_uniform_location;
|
||||
glm::vec4 color;
|
||||
};
|
||||
|
||||
#endif
|
20
core/renderer/opengl/game_application.h
Normal file
20
core/renderer/opengl/game_application.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef GAME_APPLICATION_H
|
||||
#define GAME_APPLICATION_H
|
||||
|
||||
#include "application.h"
|
||||
|
||||
#include "game_scene.h"
|
||||
|
||||
class GameApplication : public Application {
|
||||
public:
|
||||
GameApplication() : Application() {
|
||||
scene = new GameScene();
|
||||
}
|
||||
|
||||
~GameApplication() {
|
||||
delete scene;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
165
core/renderer/opengl/game_scene.cpp
Normal file
165
core/renderer/opengl/game_scene.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include "game_scene.h"
|
||||
|
||||
#include "application.h"
|
||||
|
||||
void GameScene::event(const SDL_Event &ev) {
|
||||
switch (ev.type) {
|
||||
case SDL_WINDOWEVENT: {
|
||||
switch (ev.window.event) {
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED: {
|
||||
int width = ev.window.data1;
|
||||
int height = ev.window.data2;
|
||||
|
||||
float ar = static_cast<float>(width) / static_cast<float>(height);
|
||||
|
||||
camera->width = camera->height * ar;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SDL_KEYDOWN: {
|
||||
|
||||
if (ev.key.keysym.scancode == SDL_SCANCODE_A) {
|
||||
left = true;
|
||||
} else if (ev.key.keysym.scancode == SDL_SCANCODE_W) {
|
||||
up = true;
|
||||
} else if (ev.key.keysym.scancode == SDL_SCANCODE_S) {
|
||||
down = true;
|
||||
} else if (ev.key.keysym.scancode == SDL_SCANCODE_D) {
|
||||
right = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP: {
|
||||
|
||||
if (ev.key.keysym.scancode == SDL_SCANCODE_A) {
|
||||
left = false;
|
||||
} else if (ev.key.keysym.scancode == SDL_SCANCODE_W) {
|
||||
up = false;
|
||||
} else if (ev.key.keysym.scancode == SDL_SCANCODE_S) {
|
||||
down = false;
|
||||
} else if (ev.key.keysym.scancode == SDL_SCANCODE_D) {
|
||||
right = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameScene::update(float delta) {
|
||||
if (up) {
|
||||
sprite->position.y += delta * 3.0;
|
||||
}
|
||||
|
||||
if (down) {
|
||||
sprite->position.y -= delta * 3.0;
|
||||
}
|
||||
|
||||
if (left) {
|
||||
sprite->position.x -= delta * 3.0;
|
||||
}
|
||||
|
||||
if (right) {
|
||||
sprite->position.x += delta * 3.0;
|
||||
}
|
||||
|
||||
if (sprite->position.x < 1.5) {
|
||||
sprite->position.x = 1.5;
|
||||
}
|
||||
|
||||
if (sprite->position.x > 14.5) {
|
||||
sprite->position.x = 14.5;
|
||||
}
|
||||
|
||||
if (sprite->position.y < 1.5) {
|
||||
sprite->position.y = 1.5;
|
||||
}
|
||||
|
||||
if (sprite->position.y > 14.5) {
|
||||
sprite->position.y = 14.5;
|
||||
}
|
||||
}
|
||||
|
||||
void GameScene::render() {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
camera->bind();
|
||||
|
||||
tile_map->render();
|
||||
|
||||
sprite->render();
|
||||
}
|
||||
|
||||
GameScene::GameScene() {
|
||||
left = false;
|
||||
right = false;
|
||||
up = false;
|
||||
down = false;
|
||||
|
||||
camera = new OrthographicCamera();
|
||||
camera->width = 16;
|
||||
camera->height = 16;
|
||||
camera->position.x = 8;
|
||||
camera->position.y = 8;
|
||||
//camera->position.z = -2;
|
||||
|
||||
int w;
|
||||
int h;
|
||||
SDL_GetWindowSize(Application::get_singleton()->window, &w, &h);
|
||||
|
||||
float ar = static_cast<float>(w) / static_cast<float>(h);
|
||||
camera->width = camera->height * ar;
|
||||
|
||||
texture = new Texture();
|
||||
texture->load_image("download.bmp");
|
||||
//ha a textúrának van alpha csatornája:
|
||||
//texture->load_image("download.bmp", GL_RGBA, GL_RGBA);
|
||||
|
||||
material = new TextureMaterial();
|
||||
material->texture = texture;
|
||||
|
||||
sprite = new Sprite();
|
||||
sprite->mesh_instance->material = material;
|
||||
sprite->position.x = 8;
|
||||
sprite->position.y = 8;
|
||||
sprite->region_x = 7.0 * (1.0 / 16.0);
|
||||
sprite->region_y = 7.0 * (1.0 / 16.0);
|
||||
sprite->region_width = 1.0 / 16.0;
|
||||
sprite->region_height = 1.0 / 16.0;
|
||||
sprite->update_mesh();
|
||||
|
||||
tile_map = new TileMap();
|
||||
tile_map->material = material;
|
||||
tile_map->atlas_size_x = 16;
|
||||
tile_map->atlas_size_y = 16;
|
||||
|
||||
tile_map->allocate_data();
|
||||
|
||||
for (int x = 0; x < tile_map->size_x; ++x) {
|
||||
for (int y = 0; y < tile_map->size_y; ++y) {
|
||||
if (x == 0 || y == 0 || x == tile_map->size_x - 1 || y == tile_map->size_y - 1) {
|
||||
tile_map->set_data(x, y, 2);
|
||||
} else {
|
||||
tile_map->set_data(x, y, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tile_map->build_mesh();
|
||||
}
|
||||
|
||||
GameScene::~GameScene() {
|
||||
delete camera;
|
||||
delete texture;
|
||||
delete material;
|
||||
delete tile_map;
|
||||
delete sprite;
|
||||
}
|
34
core/renderer/opengl/game_scene.h
Normal file
34
core/renderer/opengl/game_scene.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef GAME_SCENE_H
|
||||
#define GAME_SCENE_H
|
||||
|
||||
#include "scene.h"
|
||||
|
||||
#include "camera.h"
|
||||
#include "mesh_instance.h"
|
||||
#include "texture.h"
|
||||
#include "texture_material.h"
|
||||
#include "tile_map.h"
|
||||
#include "sprite.h"
|
||||
|
||||
class GameScene : public Scene {
|
||||
public:
|
||||
virtual void event(const SDL_Event &ev);
|
||||
virtual void update(float delta);
|
||||
virtual void render();
|
||||
|
||||
GameScene();
|
||||
~GameScene();
|
||||
|
||||
bool left;
|
||||
bool right;
|
||||
bool up;
|
||||
bool down;
|
||||
|
||||
Camera *camera;
|
||||
Texture *texture;
|
||||
TextureMaterial *material;
|
||||
TileMap *tile_map;
|
||||
Sprite *sprite;
|
||||
};
|
||||
|
||||
#endif
|
31
core/renderer/opengl/main.cpp
Normal file
31
core/renderer/opengl/main.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include "application.h"
|
||||
|
||||
#include "game_application.h"
|
||||
#define APPLICATION_CLASS GameApplication
|
||||
|
||||
Application *application = nullptr;
|
||||
|
||||
void handle_frame() {
|
||||
application->main_loop();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
application = new APPLICATION_CLASS();
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(handle_frame, 0, 1);
|
||||
#else
|
||||
|
||||
while (application->running) {
|
||||
application->main_loop();
|
||||
}
|
||||
#endif
|
||||
|
||||
delete application;
|
||||
|
||||
return 0;
|
||||
}
|
1218
core/renderer/opengl/main_orig.cpp
Normal file
1218
core/renderer/opengl/main_orig.cpp
Normal file
File diff suppressed because it is too large
Load Diff
422
core/renderer/opengl/main_orig_2.cpp
Normal file
422
core/renderer/opengl/main_orig_2.cpp
Normal file
@ -0,0 +1,422 @@
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#define SDL_MAIN_HANDLED
|
||||
|
||||
#include "sdl.inc.h"
|
||||
|
||||
#include "opengl.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_GLContext context;
|
||||
|
||||
bool running = true;
|
||||
|
||||
#include "colored_material.h"
|
||||
#include "color_material.h"
|
||||
#include "texture_material.h"
|
||||
#include "mesh.h"
|
||||
#include "mesh_instance.h"
|
||||
#include "mesh_utils.h"
|
||||
#include "texture.h"
|
||||
#include "camera.h"
|
||||
|
||||
ColoredMaterial *colored_material = nullptr;
|
||||
ColorMaterial *color_material = nullptr;
|
||||
TextureMaterial *texture_material = nullptr;
|
||||
Texture *texture = nullptr;
|
||||
Mesh *mesh = nullptr;
|
||||
MeshInstance *mi = nullptr;
|
||||
MeshInstance *mic = nullptr;
|
||||
Camera *camera = nullptr;
|
||||
|
||||
void first_2d_triangle() {
|
||||
if (!colored_material) {
|
||||
colored_material = new ColoredMaterial();
|
||||
colored_material->color.r = 0;
|
||||
}
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
colored_material->bind();
|
||||
|
||||
//immediate mode
|
||||
/*
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex2f(0.0, 0.5);
|
||||
glVertex2f(0.5, -0.5);
|
||||
glVertex2f(-0.5, -0.5);
|
||||
glEnd();*/
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
float color_count = 0;
|
||||
void first_2d_triangle_uniforms() {
|
||||
if (!colored_material) {
|
||||
colored_material = new ColoredMaterial();
|
||||
colored_material->color.r = 0;
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
/*
|
||||
//2d
|
||||
mesh = new Mesh(2);
|
||||
|
||||
mesh->add_vertex2(-0.5, 0.5);
|
||||
mesh->add_vertex2(0.5, -0.5);
|
||||
mesh->add_vertex2(-0.5, -0.5);
|
||||
mesh->add_vertex2(0.5, 0.5);
|
||||
|
||||
mesh->add_triangle(0, 1, 2);
|
||||
mesh->add_triangle(0, 1, 3);
|
||||
|
||||
*/
|
||||
|
||||
//3d
|
||||
mesh = new Mesh();
|
||||
|
||||
mesh->add_vertex3(-0.5, 0.5, 0);
|
||||
mesh->add_vertex3(0.5, -0.5, 0);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0);
|
||||
mesh->add_vertex3(0.5, 0.5, 0);
|
||||
|
||||
mesh->add_triangle(0, 1, 2);
|
||||
mesh->add_triangle(0, 1, 3);
|
||||
|
||||
mesh->upload();
|
||||
}
|
||||
|
||||
color_count += 0.01;
|
||||
|
||||
if (color_count > 1)
|
||||
color_count = 0;
|
||||
|
||||
colored_material->color.r = color_count;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
colored_material->bind();
|
||||
|
||||
mesh->render();
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
void first_2d_triangle_uniforms_mi() {
|
||||
if (!colored_material) {
|
||||
colored_material = new ColoredMaterial();
|
||||
colored_material->color.r = 0;
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
mesh = new Mesh();
|
||||
|
||||
mesh->add_vertex3(-0.5, 0.5, 0);
|
||||
mesh->add_vertex3(0.5, -0.5, 0);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0);
|
||||
mesh->add_vertex3(0.5, 0.5, 0);
|
||||
|
||||
mesh->add_triangle(0, 1, 2);
|
||||
mesh->add_triangle(0, 1, 3);
|
||||
|
||||
mesh->upload();
|
||||
|
||||
mi = new MeshInstance();
|
||||
|
||||
mi->material = colored_material;
|
||||
mi->mesh = mesh;
|
||||
}
|
||||
|
||||
color_count += 0.01;
|
||||
|
||||
if (color_count > 1)
|
||||
color_count = 0;
|
||||
|
||||
mi->position.x = color_count;
|
||||
mi->rotation.z = color_count * 100;
|
||||
mi->scale.x = color_count;
|
||||
|
||||
colored_material->color.r = color_count;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
mi->render();
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
void first_2d_triangle_uniforms_mi_children() {
|
||||
if (!colored_material) {
|
||||
colored_material = new ColoredMaterial();
|
||||
colored_material->color.r = 0;
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
mesh = new Mesh();
|
||||
|
||||
mesh->add_vertex3(-0.5, 0.5, 0);
|
||||
mesh->add_vertex3(0.5, -0.5, 0);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0);
|
||||
mesh->add_vertex3(0.5, 0.5, 0);
|
||||
|
||||
mesh->add_triangle(0, 1, 2);
|
||||
mesh->add_triangle(0, 1, 3);
|
||||
|
||||
mesh->upload();
|
||||
|
||||
mi = new MeshInstance();
|
||||
|
||||
mi->material = colored_material;
|
||||
mi->mesh = mesh;
|
||||
|
||||
mic = new MeshInstance();
|
||||
|
||||
mic->material = colored_material;
|
||||
mic->mesh = mesh;
|
||||
mic->scale = glm::vec3(0.8, 0.8, 0.8);
|
||||
//mic->position.x = 0.5;
|
||||
|
||||
mi->children.push_back(mic);
|
||||
}
|
||||
|
||||
color_count += 0.01;
|
||||
|
||||
if (color_count > 1)
|
||||
color_count = 0;
|
||||
|
||||
//mi->position.x = color_count;
|
||||
//mi->rotation.z = color_count * 100;
|
||||
//mi->scale.x = color_count;
|
||||
|
||||
mi->position.x = color_count;
|
||||
mic->position.x = sin(color_count);
|
||||
mic->position.y = cos(color_count);
|
||||
|
||||
colored_material->color.r = color_count;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
mi->render();
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
void cone_perspective() {
|
||||
if (!camera) {
|
||||
camera = new PerspectiveCamera();
|
||||
camera->position.z = -2;
|
||||
}
|
||||
|
||||
if (!color_material) {
|
||||
color_material = new ColorMaterial();
|
||||
// color_material->color.r = 0;
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
mesh = new Mesh();
|
||||
|
||||
MeshUtils::create_cone(mesh);
|
||||
|
||||
mesh->upload();
|
||||
|
||||
mi = new MeshInstance();
|
||||
|
||||
mi->material = color_material;
|
||||
mi->mesh = mesh;
|
||||
}
|
||||
|
||||
color_count += 0.01;
|
||||
|
||||
if (color_count > 3)
|
||||
color_count = 0;
|
||||
|
||||
// mi->position.x = color_count;
|
||||
//mi->rotation.x = 210;
|
||||
mi->rotation.y = color_count;
|
||||
// mi->scale.x = color_count;
|
||||
|
||||
// color_material->color.r = color_count;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
camera->bind();
|
||||
|
||||
mi->render();
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
void first_2d_triangle_uvs() {
|
||||
if (!camera) {
|
||||
camera = new PerspectiveCamera();
|
||||
camera->position.z = -2;
|
||||
}
|
||||
|
||||
if (!texture) {
|
||||
texture = new Texture();
|
||||
texture->load_image("download.bmp");
|
||||
}
|
||||
|
||||
if (!texture_material) {
|
||||
texture_material = new TextureMaterial();
|
||||
texture_material->texture = texture;
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
mesh = new Mesh();
|
||||
|
||||
mesh->add_uv(0, 0);
|
||||
mesh->add_vertex3(-0.5, 0.5, 0);
|
||||
mesh->add_uv(1, 1);
|
||||
mesh->add_vertex3(0.5, -0.5, 0);
|
||||
mesh->add_uv(0, 1);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0);
|
||||
mesh->add_uv(1, 0);
|
||||
mesh->add_vertex3(0.5, 0.5, 0);
|
||||
|
||||
mesh->add_triangle(0, 1, 2);
|
||||
mesh->add_triangle(0, 1, 3);
|
||||
|
||||
mesh->upload();
|
||||
|
||||
mi = new MeshInstance();
|
||||
|
||||
mi->material = texture_material;
|
||||
mi->mesh = mesh;
|
||||
}
|
||||
|
||||
color_count += 0.01;
|
||||
|
||||
if (color_count > 1)
|
||||
color_count = 0;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
camera->position.x = color_count;
|
||||
|
||||
camera->bind();
|
||||
|
||||
mi->render();
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
int current_demo = 5;
|
||||
|
||||
//gameloop
|
||||
void handle_frame() {
|
||||
//handle input
|
||||
SDL_Event current_evevnt;
|
||||
|
||||
while(SDL_PollEvent(¤t_evevnt)) {
|
||||
if (current_evevnt.type == SDL_QUIT) {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
//update world
|
||||
//most ez nem kell
|
||||
|
||||
//render
|
||||
switch (current_demo) {
|
||||
case 0:
|
||||
first_2d_triangle();
|
||||
break;
|
||||
case 1:
|
||||
first_2d_triangle_uniforms();
|
||||
break;
|
||||
case 2:
|
||||
first_2d_triangle_uniforms_mi();
|
||||
break;
|
||||
case 3:
|
||||
first_2d_triangle_uniforms_mi_children();
|
||||
break;
|
||||
case 4:
|
||||
cone_perspective();
|
||||
break;
|
||||
case 5:
|
||||
first_2d_triangle_uvs();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
SDL_SetMainReady();
|
||||
int error = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
|
||||
if (error) {
|
||||
SDL_Log("SDL_Init: %s", SDL_GetError());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if _WIN64
|
||||
//Use OpenGl 2.1
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
#else
|
||||
//Use OpenGl ES 2.0
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow("SDL + OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
|
||||
|
||||
if (!window) {
|
||||
SDL_Log("SDL_CreateWindow: %s", SDL_GetError());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
context = SDL_GL_CreateContext(window);
|
||||
|
||||
#ifdef _WIN64
|
||||
gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress);
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(handle_frame, 0, 1);
|
||||
#else
|
||||
|
||||
while (running) {
|
||||
handle_frame();
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%s\n", glGetString(GL_VERSION));
|
||||
|
||||
//if (vbo_init) {
|
||||
// glDeleteBuffers(1, &triange_VBO);
|
||||
// }
|
||||
|
||||
if (colored_material) {
|
||||
delete colored_material;
|
||||
}
|
||||
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
window = nullptr;
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
62
core/renderer/opengl/material.cpp
Normal file
62
core/renderer/opengl/material.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "material.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
Material* Material::current_material = nullptr;
|
||||
|
||||
void Material::bind() {
|
||||
//csak a main thread fogja meghívni!
|
||||
|
||||
if (!shader) {
|
||||
shader = ShaderCache::get_singleton()->get_shader(get_material_id());
|
||||
|
||||
if (!shader) {
|
||||
shader = new Shader();
|
||||
|
||||
shader->set_vertex_shader_source(get_vertex_shader_source());
|
||||
shader->set_fragment_shader_source(get_fragment_shader_source());
|
||||
shader->compile();
|
||||
|
||||
ShaderCache::get_singleton()->add_shader(get_material_id(), shader);
|
||||
}
|
||||
|
||||
setup_uniforms();
|
||||
}
|
||||
|
||||
if (current_material && current_material != this) {
|
||||
current_material->unbind();
|
||||
|
||||
setup_state();
|
||||
}
|
||||
|
||||
current_material = this;
|
||||
|
||||
shader->bind();
|
||||
|
||||
bind_uniforms();
|
||||
}
|
||||
|
||||
void Material::unbind() {
|
||||
}
|
||||
void Material::bind_uniforms() {
|
||||
}
|
||||
void Material::setup_uniforms() {
|
||||
}
|
||||
void Material::setup_state() {
|
||||
}
|
||||
|
||||
GLint Material::get_uniform(const char *name) {
|
||||
GLint uniform = glGetUniformLocation(shader->program, name);
|
||||
|
||||
if (uniform == -1) {
|
||||
printf("%s is not a valid glsl program variable!\n", name);
|
||||
}
|
||||
|
||||
return uniform;
|
||||
}
|
||||
|
||||
Material::Material() {
|
||||
shader = nullptr;
|
||||
}
|
||||
Material::~Material() {
|
||||
}
|
30
core/renderer/opengl/material.h
Normal file
30
core/renderer/opengl/material.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef MATERIAL_H
|
||||
#define MATERIAL_H
|
||||
|
||||
#include "opengl.h"
|
||||
#include "shader.h"
|
||||
|
||||
class Material {
|
||||
public:
|
||||
void bind();
|
||||
|
||||
virtual void unbind();
|
||||
virtual int get_material_id() = 0;
|
||||
virtual void bind_uniforms();
|
||||
virtual void setup_uniforms();
|
||||
virtual void setup_state();
|
||||
virtual const GLchar** get_vertex_shader_source() = 0;
|
||||
virtual const GLchar** get_fragment_shader_source() = 0;
|
||||
|
||||
GLint get_uniform(const char* name);
|
||||
|
||||
Material();
|
||||
virtual ~Material();
|
||||
|
||||
protected:
|
||||
static Material* current_material;
|
||||
|
||||
Shader* shader;
|
||||
};
|
||||
|
||||
#endif
|
179
core/renderer/opengl/mesh.cpp
Normal file
179
core/renderer/opengl/mesh.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#include "mesh.h"
|
||||
|
||||
#include "shader.h"
|
||||
|
||||
void Mesh::add_vertex2(GLfloat x, GLfloat y) {
|
||||
vertices.push_back(x);
|
||||
vertices.push_back(y);
|
||||
}
|
||||
void Mesh::add_vertex3(GLfloat x, GLfloat y, GLfloat z) {
|
||||
vertices.push_back(x);
|
||||
vertices.push_back(y);
|
||||
vertices.push_back(z);
|
||||
}
|
||||
|
||||
void Mesh::add_normal(GLfloat x, GLfloat y, GLfloat z) {
|
||||
normals.push_back(x);
|
||||
normals.push_back(y);
|
||||
normals.push_back(z);
|
||||
}
|
||||
void Mesh::add_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
colors.push_back(r);
|
||||
colors.push_back(g);
|
||||
colors.push_back(b);
|
||||
colors.push_back(a);
|
||||
}
|
||||
|
||||
void Mesh::add_uv(GLfloat u, GLfloat v) {
|
||||
uvs.push_back(u);
|
||||
uvs.push_back(v);
|
||||
}
|
||||
void Mesh::add_index(GLuint index) {
|
||||
indices.push_back(index);
|
||||
}
|
||||
void Mesh::add_triangle(GLuint i1, GLuint i2, GLuint i3) {
|
||||
indices.push_back(i1);
|
||||
indices.push_back(i2);
|
||||
indices.push_back(i3);
|
||||
}
|
||||
|
||||
void Mesh::clear() {
|
||||
vertices.clear();
|
||||
normals.clear();
|
||||
colors.clear();
|
||||
uvs.clear();
|
||||
indices.clear();
|
||||
}
|
||||
|
||||
void Mesh::upload() {
|
||||
if (vertices.size() == 0)
|
||||
return;
|
||||
|
||||
if (!VBO) {
|
||||
glGenBuffers(1, &VBO);
|
||||
}
|
||||
|
||||
vertices_vbo_size = sizeof(GLfloat) * vertices.size();
|
||||
normals_vbo_size = sizeof(GLfloat) * normals.size();
|
||||
colors_vbo_size = sizeof(GLfloat) * colors.size();
|
||||
uvs_vbo_size = sizeof(GLfloat) * uvs.size();
|
||||
indices_vbo_size = sizeof(GLfloat) * indices.size();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size + colors_vbo_size + uvs_vbo_size, 0, GL_STATIC_DRAW);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_vbo_size, &vertices[0]);
|
||||
|
||||
if (normals_vbo_size > 0) {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size, normals_vbo_size, &normals[0]);
|
||||
}
|
||||
|
||||
if (colors_vbo_size > 0) {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size, colors_vbo_size, &colors[0]);
|
||||
}
|
||||
|
||||
if (uvs_vbo_size > 0) {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size + colors_vbo_size, uvs_vbo_size, &uvs[0]);
|
||||
}
|
||||
|
||||
if (indices_vbo_size > 0) {
|
||||
if (!IBO) {
|
||||
glGenBuffers(1, &IBO);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_vbo_size, &indices[0], GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
void Mesh::destroy() {
|
||||
if (VBO) {
|
||||
glDeleteBuffers(1, &VBO);
|
||||
}
|
||||
|
||||
if (IBO) {
|
||||
glDeleteBuffers(1, &IBO);
|
||||
}
|
||||
}
|
||||
void Mesh::render() {
|
||||
if (vertices.size() == 0 || !VBO)
|
||||
return;
|
||||
|
||||
if (!Shader::current_shader)
|
||||
return;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glVertexAttribPointer(Shader::ATTRIBUTE_POSITION, vertex_dimensions, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glEnableVertexAttribArray(Shader::ATTRIBUTE_POSITION);
|
||||
|
||||
if (normals_vbo_size > 0) {
|
||||
glVertexAttribPointer(Shader::ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, (void *)(vertices_vbo_size));
|
||||
glEnableVertexAttribArray(Shader::ATTRIBUTE_NORMAL);
|
||||
}
|
||||
|
||||
if (colors_vbo_size > 0) {
|
||||
glVertexAttribPointer(Shader::ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_FALSE, 0, (void *)(vertices_vbo_size + normals_vbo_size));
|
||||
glEnableVertexAttribArray(Shader::ATTRIBUTE_COLOR);
|
||||
}
|
||||
|
||||
if (uvs_vbo_size > 0) {
|
||||
glVertexAttribPointer(Shader::ATTRIBUTE_UV, 2, GL_FLOAT, GL_FALSE, 0, (void *)(vertices_vbo_size + normals_vbo_size + colors_vbo_size));
|
||||
glEnableVertexAttribArray(Shader::ATTRIBUTE_UV);
|
||||
}
|
||||
|
||||
if (indices_vbo_size > 0) {
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (GLvoid*)0);
|
||||
} else {
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(Shader::ATTRIBUTE_POSITION);
|
||||
|
||||
if (normals_vbo_size > 0) {
|
||||
glDisableVertexAttribArray(Shader::ATTRIBUTE_NORMAL);
|
||||
}
|
||||
|
||||
if (colors_vbo_size > 0) {
|
||||
glDisableVertexAttribArray(Shader::ATTRIBUTE_COLOR);
|
||||
}
|
||||
|
||||
if (uvs_vbo_size > 0) {
|
||||
glDisableVertexAttribArray(Shader::ATTRIBUTE_UV);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
Mesh::Mesh() {
|
||||
VBO = 0;
|
||||
IBO = 0;
|
||||
|
||||
vertex_dimensions = 3;
|
||||
|
||||
vertices_vbo_size = 0;
|
||||
normals_vbo_size = 0;
|
||||
colors_vbo_size = 0;
|
||||
uvs_vbo_size = 0;
|
||||
indices_vbo_size = 0;
|
||||
}
|
||||
Mesh::Mesh(int vert_dim) {
|
||||
VBO = 0;
|
||||
IBO = 0;
|
||||
|
||||
vertex_dimensions = vert_dim;
|
||||
|
||||
vertices_vbo_size = 0;
|
||||
normals_vbo_size = 0;
|
||||
colors_vbo_size = 0;
|
||||
uvs_vbo_size = 0;
|
||||
indices_vbo_size = 0;
|
||||
}
|
||||
Mesh::~Mesh() {
|
||||
destroy();
|
||||
clear();
|
||||
}
|
50
core/renderer/opengl/mesh.h
Normal file
50
core/renderer/opengl/mesh.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef MESH_H
|
||||
#define MESH_H
|
||||
|
||||
#include <vector>
|
||||
#include "opengl.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
void add_vertex2(GLfloat x, GLfloat y);
|
||||
void add_vertex3(GLfloat x, GLfloat y, GLfloat z);
|
||||
|
||||
void add_normal(GLfloat x, GLfloat y, GLfloat z);
|
||||
void add_color(GLfloat r = 1, GLfloat g = 1, GLfloat b = 1, GLfloat a = 1);
|
||||
|
||||
void add_uv(GLfloat u, GLfloat v);
|
||||
void add_index(GLuint index);
|
||||
void add_triangle(GLuint i1, GLuint i2, GLuint i3);
|
||||
|
||||
void clear();
|
||||
|
||||
void upload();
|
||||
void destroy();
|
||||
void render();
|
||||
|
||||
Mesh();
|
||||
Mesh(int vert_dim);
|
||||
virtual ~Mesh();
|
||||
|
||||
GLuint VBO;
|
||||
GLuint IBO;
|
||||
|
||||
int vertex_dimensions;
|
||||
|
||||
vector<GLfloat> vertices;
|
||||
vector<GLfloat> normals;
|
||||
vector<GLfloat> colors;
|
||||
vector<GLfloat> uvs;
|
||||
vector<GLuint> indices;
|
||||
|
||||
protected:
|
||||
size_t vertices_vbo_size;
|
||||
size_t normals_vbo_size;
|
||||
size_t colors_vbo_size;
|
||||
size_t uvs_vbo_size;
|
||||
size_t indices_vbo_size;
|
||||
};
|
||||
|
||||
#endif
|
61
core/renderer/opengl/mesh_instance.cpp
Normal file
61
core/renderer/opengl/mesh_instance.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "mesh_instance.h"
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "./glm/vec3.hpp"
|
||||
#include "./glm/matrix.hpp"
|
||||
#include "./glm/gtc/matrix_transform.hpp"
|
||||
|
||||
void MeshInstance::render() {
|
||||
if (!mesh)
|
||||
return;
|
||||
|
||||
//glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
//glPushMatrix();
|
||||
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
//glRotatef(rotation.x, 1, 0, 0);
|
||||
//glRotatef(rotation.y, 0, 1, 0);
|
||||
//glRotatef(rotation.z, 0, 0, 1);
|
||||
//glScalef(scale.x, scale.y, scale.z);
|
||||
|
||||
glm::mat4 mat_oring = Camera::current_camera->model_view_matrix;
|
||||
|
||||
Camera::current_camera->model_view_matrix = glm::translate(Camera::current_camera->model_view_matrix, position);
|
||||
|
||||
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation.x, glm::vec3(1, 0, 0));
|
||||
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation.y, glm::vec3(0, 1, 0));
|
||||
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation.z, glm::vec3(0, 0, 1));
|
||||
|
||||
Camera::current_camera->model_view_matrix = glm::scale(Camera::current_camera->model_view_matrix, scale);
|
||||
|
||||
if (material)
|
||||
material->bind();
|
||||
|
||||
mesh->render();
|
||||
|
||||
for (uint32_t i = 0; i < children.size(); ++i) {
|
||||
MeshInstance *c = children[i];
|
||||
|
||||
if (c)
|
||||
c->render();
|
||||
}
|
||||
|
||||
//glPopMatrix();
|
||||
|
||||
Camera::current_camera->model_view_matrix = mat_oring;
|
||||
}
|
||||
|
||||
MeshInstance::MeshInstance() {
|
||||
material = nullptr;
|
||||
mesh = nullptr;
|
||||
|
||||
position = glm::vec3(0, 0, 0);
|
||||
rotation = glm::vec3(0, 0, 0);
|
||||
scale = glm::vec3(1, 1, 1);
|
||||
}
|
||||
|
||||
MeshInstance::~MeshInstance() {
|
||||
children.clear();
|
||||
}
|
28
core/renderer/opengl/mesh_instance.h
Normal file
28
core/renderer/opengl/mesh_instance.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef MESH_INSTANCE_H
|
||||
#define MESH_INSTANCE_H
|
||||
|
||||
#include <vector>
|
||||
#include "opengl.h"
|
||||
#include "material.h"
|
||||
#include "mesh.h"
|
||||
|
||||
#include "./glm/vec3.hpp"
|
||||
|
||||
class MeshInstance {
|
||||
public:
|
||||
void render();
|
||||
|
||||
MeshInstance();
|
||||
virtual ~MeshInstance();
|
||||
|
||||
Material *material;
|
||||
Mesh *mesh;
|
||||
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
|
||||
std::vector<MeshInstance *> children;
|
||||
};
|
||||
|
||||
#endif
|
73
core/renderer/opengl/mesh_utils.cpp
Normal file
73
core/renderer/opengl/mesh_utils.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "mesh_utils.h"
|
||||
|
||||
void MeshUtils::create_cone(Mesh *mesh) {
|
||||
if (!mesh)
|
||||
return;
|
||||
|
||||
uint32_t vc = mesh->vertices.size();
|
||||
|
||||
//eleje
|
||||
mesh->add_color(1, 0, 0);
|
||||
mesh->add_vertex3(0, 0.5, 0);
|
||||
|
||||
mesh->add_color(1,0,0);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0.5);
|
||||
|
||||
mesh->add_color(1, 0, 0);
|
||||
mesh->add_vertex3(0.5, -0.5, 0.5);
|
||||
|
||||
mesh->add_triangle(0 + vc, 1 + vc, 2 + vc);
|
||||
|
||||
//bal
|
||||
mesh->add_color(0, 1, 0);
|
||||
mesh->add_vertex3(0, 0.5, 0);
|
||||
|
||||
mesh->add_color(0, 1, 0);
|
||||
mesh->add_vertex3(-0.5, -0.5, -0.5);
|
||||
|
||||
mesh->add_color(0, 1, 0);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0.5);
|
||||
|
||||
mesh->add_triangle(3 + vc, 4 + vc, 5 + vc);
|
||||
|
||||
//jobb
|
||||
mesh->add_color(0, 0, 1);
|
||||
mesh->add_vertex3(0, 0.5, 0);
|
||||
|
||||
mesh->add_color(0, 0, 1);
|
||||
mesh->add_vertex3(0.5, -0.5, 0.5);
|
||||
|
||||
mesh->add_color(0, 0, 1);
|
||||
mesh->add_vertex3(0.5, -0.5, -0.5);
|
||||
|
||||
mesh->add_triangle(6 + vc, 7 + vc, 8 + vc);
|
||||
|
||||
//hátulja
|
||||
mesh->add_color(1, 1, 0);
|
||||
mesh->add_vertex3(0, 0.5, 0);
|
||||
|
||||
mesh->add_color(1, 1, 0);
|
||||
mesh->add_vertex3(0.5, -0.5, -0.5);
|
||||
|
||||
mesh->add_color(1, 1, 0);
|
||||
mesh->add_vertex3(-0.5, -0.5, -0.5);
|
||||
|
||||
mesh->add_triangle(9 + vc, 10 + vc, 11 + vc);
|
||||
|
||||
//alja
|
||||
|
||||
mesh->add_color(1, 0, 1);
|
||||
mesh->add_vertex3(-0.5, -0.5, -0.5);
|
||||
|
||||
mesh->add_color(1, 0, 1);
|
||||
mesh->add_vertex3(0.5, -0.5, 0.5);
|
||||
|
||||
mesh->add_color(1, 0, 1);
|
||||
mesh->add_vertex3(-0.5, -0.5, 0.5);
|
||||
|
||||
mesh->add_color(1, 0, 1);
|
||||
mesh->add_vertex3(0.5, -0.5, -0.5);
|
||||
|
||||
mesh->add_triangle(12 + vc, 13 + vc, 14 + vc);
|
||||
mesh->add_triangle(13 + vc, 12 + vc, 15 + vc);
|
||||
}
|
11
core/renderer/opengl/mesh_utils.h
Normal file
11
core/renderer/opengl/mesh_utils.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef MESH_UTILS_H
|
||||
#define MESH_UTILS_H
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
class MeshUtils {
|
||||
public:
|
||||
static void create_cone(Mesh *mesh);
|
||||
};
|
||||
|
||||
#endif
|
10
core/renderer/opengl/object_2d.cpp
Normal file
10
core/renderer/opengl/object_2d.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "object_2d.h"
|
||||
|
||||
Object2D::Object2D() {
|
||||
position = glm::vec2(0, 0);
|
||||
rotation = 0;
|
||||
scale = glm::vec2(1, 1);
|
||||
}
|
||||
|
||||
Object2D::~Object2D() {
|
||||
}
|
17
core/renderer/opengl/object_2d.h
Normal file
17
core/renderer/opengl/object_2d.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef OBJECT_2D_H
|
||||
#define OBJECT_2D_H
|
||||
|
||||
#include "./glm/vec2.hpp"
|
||||
|
||||
class Object2D {
|
||||
public:
|
||||
|
||||
Object2D();
|
||||
virtual ~Object2D();
|
||||
|
||||
glm::vec2 position;
|
||||
float rotation;
|
||||
glm::vec2 scale;
|
||||
};
|
||||
|
||||
#endif
|
19
core/renderer/opengl/opengl.h
Normal file
19
core/renderer/opengl/opengl.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef OPENGL_H
|
||||
#define OPENGL_H
|
||||
|
||||
#if __unix__ && !__ANDROID__
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#if __ANDROID__
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GLES2/gl2.h>
|
||||
#endif
|
||||
|
||||
#if _WIN64
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
9
core/renderer/opengl/scene.cpp
Normal file
9
core/renderer/opengl/scene.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "scene.h"
|
||||
|
||||
Scene::Scene() {
|
||||
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
|
||||
}
|
16
core/renderer/opengl/scene.h
Normal file
16
core/renderer/opengl/scene.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
|
||||
#include "sdl.inc.h"
|
||||
|
||||
class Scene {
|
||||
public:
|
||||
virtual void event(const SDL_Event &ev) = 0;
|
||||
virtual void update(float delta) = 0;
|
||||
virtual void render() = 0;
|
||||
|
||||
Scene();
|
||||
virtual ~Scene();
|
||||
};
|
||||
|
||||
#endif
|
9
core/renderer/opengl/sdl.inc.h
Normal file
9
core/renderer/opengl/sdl.inc.h
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
#if __ANDROID__
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#define SDL_MAIN_HANDLED
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
|
||||
|
153
core/renderer/opengl/shader.cpp
Normal file
153
core/renderer/opengl/shader.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include "shader.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
Shader *Shader::current_shader = nullptr;
|
||||
|
||||
bool Shader::bind() {
|
||||
if (current_shader != this) {
|
||||
glUseProgram(program);
|
||||
|
||||
current_shader = this;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void Shader::unbind() {
|
||||
if (current_shader == this) {
|
||||
glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::compile() {
|
||||
program = glCreateProgram();
|
||||
|
||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
const GLchar **vertex_shader_source = get_vertex_shader_source();
|
||||
|
||||
glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
|
||||
glCompileShader(vertex_shader);
|
||||
|
||||
GLint shader_compiled = GL_FALSE;
|
||||
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_compiled);
|
||||
if (shader_compiled != GL_TRUE) {
|
||||
print_shader_errors(vertex_shader, "compiling Vertex Shader");
|
||||
return;
|
||||
}
|
||||
|
||||
glAttachShader(program, vertex_shader);
|
||||
|
||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
const GLchar **fragment_shader_source = get_fragment_shader_source();
|
||||
|
||||
glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
GLint fragment_shader_compiled = GL_FALSE;
|
||||
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &fragment_shader_compiled);
|
||||
if (fragment_shader_compiled != GL_TRUE) {
|
||||
print_shader_errors(fragment_shader, "compiling Fragment Shader");
|
||||
return;
|
||||
}
|
||||
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
glBindAttribLocation(program, ATTRIBUTE_POSITION, "a_position");
|
||||
glBindAttribLocation(program, ATTRIBUTE_NORMAL, "a_normal");
|
||||
glBindAttribLocation(program, ATTRIBUTE_COLOR, "a_color");
|
||||
glBindAttribLocation(program, ATTRIBUTE_UV, "a_uv");
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint program_success = GL_TRUE;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &program_success);
|
||||
if (program_success != GL_TRUE) {
|
||||
print_program_errors(program);
|
||||
return;
|
||||
}
|
||||
}
|
||||
void Shader::destroy() {
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
|
||||
const GLchar **Shader::get_vertex_shader_source() {
|
||||
return vertex_shader_source;
|
||||
}
|
||||
void Shader::set_vertex_shader_source(const GLchar **source) {
|
||||
vertex_shader_source = source;
|
||||
}
|
||||
|
||||
const GLchar **Shader::get_fragment_shader_source() {
|
||||
return fragment_shader_source;
|
||||
}
|
||||
void Shader::set_fragment_shader_source(const GLchar **source) {
|
||||
fragment_shader_source = source;
|
||||
}
|
||||
|
||||
void Shader::print_shader_errors(const GLuint p_program, const char *name) {
|
||||
int max_length = 5000;
|
||||
std::vector<GLchar> error_log(max_length);
|
||||
glGetShaderInfoLog(p_program, max_length, &max_length, &error_log[0]);
|
||||
|
||||
printf("Error %s!\n", name);
|
||||
printf("%s\n", &error_log[0]);
|
||||
}
|
||||
|
||||
void Shader::print_program_errors(const GLuint p_program) {
|
||||
if (glIsProgram(p_program)) {
|
||||
int info_length = 0;
|
||||
int max_length = 5000;
|
||||
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_length);
|
||||
|
||||
char *info_log = new char[max_length];
|
||||
|
||||
glGetProgramInfoLog(p_program, max_length, &info_length, info_log);
|
||||
|
||||
if (info_length > 0) {
|
||||
printf("%s\n", info_log);
|
||||
}
|
||||
|
||||
delete[] info_log;
|
||||
} else {
|
||||
printf("print_program_errors: Not a program!");
|
||||
}
|
||||
}
|
||||
|
||||
Shader::Shader() {
|
||||
}
|
||||
Shader::~Shader() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
//Meyers singleton
|
||||
//Thread safe
|
||||
ShaderCache *ShaderCache::get_singleton() {
|
||||
static ShaderCache instance;
|
||||
|
||||
return &instance;
|
||||
}
|
||||
|
||||
Shader *ShaderCache::get_shader(const int id) {
|
||||
return shaders[id];
|
||||
}
|
||||
void ShaderCache::add_shader(const int id, Shader *shader) {
|
||||
shaders[id] = shader;
|
||||
}
|
||||
|
||||
ShaderCache::ShaderCache() {
|
||||
}
|
||||
ShaderCache::~ShaderCache() {
|
||||
for (const std::pair<int, Shader*>& n : shaders) {
|
||||
delete n.second;
|
||||
}
|
||||
|
||||
shaders.clear();
|
||||
}
|
58
core/renderer/opengl/shader.h
Normal file
58
core/renderer/opengl/shader.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include "opengl.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
enum VertexAttributes {
|
||||
ATTRIBUTE_POSITION = 0,
|
||||
ATTRIBUTE_NORMAL,
|
||||
ATTRIBUTE_COLOR,
|
||||
ATTRIBUTE_UV,
|
||||
};
|
||||
|
||||
bool bind();
|
||||
void unbind();
|
||||
|
||||
void compile();
|
||||
void destroy();
|
||||
|
||||
const GLchar** get_vertex_shader_source();
|
||||
void set_vertex_shader_source(const GLchar** source);
|
||||
|
||||
const GLchar** get_fragment_shader_source();
|
||||
void set_fragment_shader_source(const GLchar** source);
|
||||
|
||||
void print_shader_errors(const GLuint p_program, const char* name);
|
||||
void print_program_errors(const GLuint p_program);
|
||||
|
||||
Shader();
|
||||
~Shader();
|
||||
|
||||
GLuint vertex_shader = 0;
|
||||
GLuint fragment_shader = 0;
|
||||
GLuint program = 0;
|
||||
|
||||
static Shader* current_shader;
|
||||
protected:
|
||||
const GLchar **vertex_shader_source;
|
||||
const GLchar **fragment_shader_source;
|
||||
};
|
||||
|
||||
class ShaderCache {
|
||||
public:
|
||||
static ShaderCache *get_singleton();
|
||||
|
||||
Shader *get_shader(const int id);
|
||||
void add_shader(const int id, Shader * shader);
|
||||
|
||||
ShaderCache(); //lehetene nem publikus
|
||||
~ShaderCache();
|
||||
|
||||
protected:
|
||||
std::unordered_map<int, Shader*> shaders;
|
||||
};
|
||||
|
||||
#endif
|
59
core/renderer/opengl/sprite.cpp
Normal file
59
core/renderer/opengl/sprite.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "sprite.h"
|
||||
|
||||
void Sprite::render() {
|
||||
mesh_instance->position.x = position.x;
|
||||
mesh_instance->position.y = position.y;
|
||||
|
||||
mesh_instance->rotation.z = rotation;
|
||||
|
||||
mesh_instance->scale.x = scale.x;
|
||||
mesh_instance->scale.y = scale.y;
|
||||
|
||||
mesh_instance->render();
|
||||
}
|
||||
|
||||
void Sprite::update_mesh() {
|
||||
Mesh *mesh = mesh_instance->mesh;
|
||||
|
||||
mesh->clear();
|
||||
|
||||
float w2 = width / 2.0;
|
||||
float h2 = height / 2.0;
|
||||
|
||||
mesh->add_uv(region_x, region_y);
|
||||
mesh->add_vertex2(-w2, h2);
|
||||
|
||||
mesh->add_uv(region_x + region_width, region_y + region_height);
|
||||
mesh->add_vertex2(w2, -h2);
|
||||
|
||||
mesh->add_uv(region_x, region_y + region_height);
|
||||
mesh->add_vertex2(-w2, -h2);
|
||||
|
||||
mesh->add_uv(region_x + region_width, region_y);
|
||||
mesh->add_vertex2(w2, h2);
|
||||
|
||||
mesh->add_triangle(1, 0, 2);
|
||||
mesh->add_triangle(0, 1, 3);
|
||||
|
||||
mesh->upload();
|
||||
}
|
||||
|
||||
Sprite::Sprite() : Object2D() {
|
||||
mesh_instance = new MeshInstance();
|
||||
mesh_instance->mesh = new Mesh(2);
|
||||
|
||||
width = 1;
|
||||
height = 1;
|
||||
|
||||
region_x = 0;
|
||||
region_y = 0;
|
||||
region_width = 1;
|
||||
region_height = 1;
|
||||
}
|
||||
|
||||
Sprite::~Sprite() {
|
||||
delete mesh_instance->mesh;
|
||||
delete mesh_instance;
|
||||
}
|
||||
|
||||
|
27
core/renderer/opengl/sprite.h
Normal file
27
core/renderer/opengl/sprite.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef SPRITE_H
|
||||
#define SPRITE_H
|
||||
|
||||
#include "object_2d.h"
|
||||
|
||||
#include "mesh_instance.h"
|
||||
|
||||
class Sprite : public Object2D {
|
||||
public:
|
||||
void render();
|
||||
void update_mesh();
|
||||
|
||||
Sprite();
|
||||
~Sprite();
|
||||
|
||||
MeshInstance *mesh_instance;
|
||||
float width;
|
||||
float height;
|
||||
|
||||
float region_x;
|
||||
float region_y;
|
||||
float region_width;
|
||||
float region_height;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
44
core/renderer/opengl/texture.cpp
Normal file
44
core/renderer/opengl/texture.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "texture.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void Texture::load_image(const char* file_name, const int format, const int internal_components) {
|
||||
if (image) {
|
||||
SDL_FreeSurface(image);
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
|
||||
image = SDL_LoadBMP(file_name);
|
||||
if (!image) {
|
||||
printf("Couldn't load %s.\n", file_name);
|
||||
} else {
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_components, image->w, image->h, 0, format, GL_UNSIGNED_BYTE, image->pixels);
|
||||
|
||||
apply_filer();
|
||||
}
|
||||
}
|
||||
void Texture::apply_filer() {
|
||||
GLint param = GL_NEAREST;
|
||||
|
||||
if (filter == TEXTURE_FILTER_LINEAR)
|
||||
param = GL_LINEAR;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, param);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, param);
|
||||
}
|
||||
|
||||
Texture::Texture() {
|
||||
filter = TEXTURE_FILTER_NEAREST;
|
||||
texture = 0;
|
||||
image = nullptr;
|
||||
}
|
||||
Texture::~Texture() {
|
||||
if (image) {
|
||||
SDL_FreeSurface(image);
|
||||
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
}
|
25
core/renderer/opengl/texture.h
Normal file
25
core/renderer/opengl/texture.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
#include "opengl.h"
|
||||
#include "sdl.inc.h"
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
enum TextureFilter {
|
||||
TEXTURE_FILTER_NEAREST = 0,
|
||||
TEXTURE_FILTER_LINEAR,
|
||||
};
|
||||
|
||||
void load_image(const char* file_name, const int format = GL_RGB, const int internal_components = GL_RGB);
|
||||
void apply_filer();
|
||||
|
||||
TextureFilter filter;
|
||||
GLuint texture;
|
||||
SDL_Surface *image;
|
||||
|
||||
Texture();
|
||||
virtual ~Texture();
|
||||
};
|
||||
|
||||
#endif
|
87
core/renderer/opengl/texture_material.h
Normal file
87
core/renderer/opengl/texture_material.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef TEXTURE_MATERIAL_H
|
||||
#define TEXTURE_MATERIAL_H
|
||||
|
||||
#include "material.h"
|
||||
#include "glm/vec4.hpp"
|
||||
#include "texture.h"
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "./glm/gtc/type_ptr.hpp"
|
||||
|
||||
class TextureMaterial : public Material {
|
||||
|
||||
public:
|
||||
int get_material_id() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
void bind_uniforms() {
|
||||
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
|
||||
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
|
||||
|
||||
if (texture) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->texture);
|
||||
glUniform1i(texture_location, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uniforms() {
|
||||
projection_matrix_location = get_uniform("u_proj_matrix");
|
||||
model_view_matrix_location = get_uniform("u_model_view_matrix");
|
||||
texture_location = get_uniform("u_texture");
|
||||
}
|
||||
|
||||
void unbind() {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void setup_state() {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
const GLchar** get_vertex_shader_source() {
|
||||
static const GLchar *vertex_shader_source[] = {
|
||||
"uniform mat4 u_proj_matrix;\n"
|
||||
"uniform mat4 u_model_view_matrix;\n"
|
||||
"\n"
|
||||
"attribute vec4 a_position;\n"
|
||||
"attribute vec2 a_uv;\n"
|
||||
"\n"
|
||||
"varying vec2 v_uv;\n"
|
||||
"\n"
|
||||
"void main() { \n"
|
||||
" v_uv = a_uv;\n"
|
||||
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position; \n"
|
||||
"}"
|
||||
};
|
||||
|
||||
return vertex_shader_source;
|
||||
}
|
||||
|
||||
const GLchar** get_fragment_shader_source() {
|
||||
static const GLchar *fragment_shader_source[] = {
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D u_texture;\n"
|
||||
"varying vec2 v_uv;\n"
|
||||
"\n"
|
||||
"void main() { gl_FragColor = texture2D(u_texture, v_uv); }\n"
|
||||
};
|
||||
|
||||
return fragment_shader_source;
|
||||
}
|
||||
|
||||
TextureMaterial() {
|
||||
texture = nullptr;
|
||||
}
|
||||
|
||||
GLint projection_matrix_location;
|
||||
GLint model_view_matrix_location;
|
||||
|
||||
GLint texture_location;
|
||||
|
||||
Texture *texture;
|
||||
};
|
||||
|
||||
#endif
|
138
core/renderer/opengl/tile_map.cpp
Normal file
138
core/renderer/opengl/tile_map.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
#include "tile_map.h"
|
||||
|
||||
#include "./glm/gtc/matrix_transform.hpp"
|
||||
#include "./glm/matrix.hpp"
|
||||
#include "./glm/vec3.hpp"
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
void TileMap::build_mesh() {
|
||||
if (!mesh) {
|
||||
mesh = new Mesh(2);
|
||||
} else {
|
||||
mesh->clear();
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
//mesh->upload();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float asx = 1.0 / atlas_size_x;
|
||||
float asy = 1.0 / atlas_size_y;
|
||||
|
||||
for (int x = 0; x < size_x; ++x) {
|
||||
int x_offset = x * size_x;
|
||||
|
||||
for (int y = 0; y < size_y; ++y) {
|
||||
uint8_t d = data[x_offset + y];
|
||||
|
||||
if (d == 0)
|
||||
continue;
|
||||
|
||||
float px;
|
||||
float py;
|
||||
|
||||
switch (d) {
|
||||
case 1:
|
||||
px = 1;
|
||||
py = 0;
|
||||
break;
|
||||
case 2:
|
||||
px = 0;
|
||||
py = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
px /= atlas_size_x;
|
||||
py /= atlas_size_y;
|
||||
|
||||
add_rect(x, y, px, py, asx, asy);
|
||||
}
|
||||
}
|
||||
|
||||
mesh->upload();
|
||||
}
|
||||
|
||||
void TileMap::allocate_data() {
|
||||
if (size_x <= 0 || size_y <= 0)
|
||||
return;
|
||||
|
||||
if (data) {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
int size = size_x * size_y;
|
||||
|
||||
data = new uint8_t[size];
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
data[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TileMap::add_rect(const int x, const int y, const float uv_x, const float uv_y, const float uv_size_x, const float uv_size_y) {
|
||||
int vc = static_cast<int>(mesh->vertices.size() / mesh->vertex_dimensions);
|
||||
|
||||
mesh->add_uv(uv_x, uv_y);
|
||||
mesh->add_vertex2(x, y + 1);
|
||||
|
||||
mesh->add_uv(uv_x + uv_size_x, uv_y + uv_size_y);
|
||||
mesh->add_vertex2(x + 1, y);
|
||||
|
||||
mesh->add_uv(uv_x, uv_y + uv_size_y);
|
||||
mesh->add_vertex2(x, y);
|
||||
|
||||
mesh->add_uv(uv_x + uv_size_x, uv_y);
|
||||
mesh->add_vertex2(x + 1, y + 1);
|
||||
|
||||
mesh->add_triangle(vc + 1, vc + 0, vc + 2);
|
||||
mesh->add_triangle(vc + 0, vc + 1, vc + 3);
|
||||
}
|
||||
|
||||
uint8_t TileMap::get_data(const int x, const int y) const {
|
||||
//3d-ben: data[(x * size_x * size_x) + (y * size_y) + size_z] etc
|
||||
|
||||
return data[x * size_x + y];
|
||||
}
|
||||
|
||||
void TileMap::set_data(const int x, const int y, const uint8_t value) {
|
||||
data[x * size_x + y] = value;
|
||||
}
|
||||
|
||||
void TileMap::render() {
|
||||
if (!mesh)
|
||||
return;
|
||||
|
||||
glm::mat4 mat_orig = Camera::current_camera->model_view_matrix;
|
||||
|
||||
Camera::current_camera->model_view_matrix = glm::translate(Camera::current_camera->model_view_matrix, glm::vec3(position.x, position.y, 0));
|
||||
|
||||
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation, glm::vec3(0, 0, 1));
|
||||
|
||||
Camera::current_camera->model_view_matrix = glm::scale(Camera::current_camera->model_view_matrix, glm::vec3(scale.x, scale.y, 0));
|
||||
|
||||
if (material)
|
||||
material->bind();
|
||||
|
||||
mesh->render();
|
||||
|
||||
Camera::current_camera->model_view_matrix = mat_orig;
|
||||
}
|
||||
|
||||
TileMap::TileMap() : Object2D() {
|
||||
data = nullptr;
|
||||
size_x = 16;
|
||||
size_y = 16;
|
||||
|
||||
atlas_size_x = 1;
|
||||
atlas_size_y = 1;
|
||||
|
||||
mesh = nullptr;
|
||||
material = nullptr;
|
||||
}
|
||||
TileMap::~TileMap() {
|
||||
if (data)
|
||||
delete[] data;
|
||||
}
|
36
core/renderer/opengl/tile_map.h
Normal file
36
core/renderer/opengl/tile_map.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef TILE_MAP_H
|
||||
#define TILE_MAP_H
|
||||
|
||||
#include "object_2d.h"
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
#include "material.h"
|
||||
|
||||
class TileMap : public Object2D {
|
||||
public:
|
||||
|
||||
void build_mesh();
|
||||
void allocate_data();
|
||||
void add_rect(const int x, const int y, const float uv_x, const float uv_y, const float uv_size_x, const float uv_size_y);
|
||||
|
||||
uint8_t get_data(const int x, const int y) const;
|
||||
void set_data(const int x, const int y, const uint8_t value);
|
||||
|
||||
void render();
|
||||
|
||||
TileMap();
|
||||
~TileMap();
|
||||
|
||||
uint8_t *data;
|
||||
int size_x;
|
||||
int size_y;
|
||||
|
||||
int atlas_size_x;
|
||||
int atlas_size_y;
|
||||
|
||||
Mesh *mesh;
|
||||
Material *material;
|
||||
};
|
||||
|
||||
#endif
|
94
core/renderer/opengl/transparent_texture_material.h
Normal file
94
core/renderer/opengl/transparent_texture_material.h
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef TRANSPARENT_TEXTURE_MATERIAL_H
|
||||
#define TRANSPARENT_TEXTURE_MATERIAL_H
|
||||
|
||||
#include "material.h"
|
||||
#include "glm/vec4.hpp"
|
||||
#include "texture.h"
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
#include "./glm/gtc/type_ptr.hpp"
|
||||
|
||||
class TransparentTextureMaterial : public Material {
|
||||
|
||||
public:
|
||||
int get_material_id() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
void bind_uniforms() {
|
||||
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
|
||||
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
|
||||
|
||||
if (texture) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->texture);
|
||||
glUniform1i(texture_location, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_uniforms() {
|
||||
projection_matrix_location = get_uniform("u_proj_matrix");
|
||||
model_view_matrix_location = get_uniform("u_model_view_matrix");
|
||||
texture_location = get_uniform("u_texture");
|
||||
}
|
||||
|
||||
void unbind() {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void setup_state() {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
const GLchar** get_vertex_shader_source() {
|
||||
static const GLchar *vertex_shader_source[] = {
|
||||
"uniform mat4 u_proj_matrix;\n"
|
||||
"uniform mat4 u_model_view_matrix;\n"
|
||||
"\n"
|
||||
"attribute vec4 a_position;\n"
|
||||
"attribute vec2 a_uv;\n"
|
||||
"\n"
|
||||
"varying vec2 v_uv;\n"
|
||||
"\n"
|
||||
"void main() { \n"
|
||||
" v_uv = a_uv;\n"
|
||||
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position; \n"
|
||||
"}"
|
||||
};
|
||||
|
||||
return vertex_shader_source;
|
||||
}
|
||||
|
||||
const GLchar** get_fragment_shader_source() {
|
||||
static const GLchar *fragment_shader_source[] = {
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D u_texture;\n"
|
||||
"varying vec2 v_uv;\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" vec4 col = texture2D(u_texture, v_uv);\n"
|
||||
"\n"
|
||||
" if (col.a < 0.1)\n"
|
||||
" discard;\n"
|
||||
"\n"
|
||||
" gl_FragColor = col;\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
return fragment_shader_source;
|
||||
}
|
||||
|
||||
TransparentTextureMaterial() {
|
||||
texture = nullptr;
|
||||
}
|
||||
|
||||
GLint projection_matrix_location;
|
||||
GLint model_view_matrix_location;
|
||||
|
||||
GLint texture_location;
|
||||
|
||||
Texture *texture;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user