mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-02 13:47:56 +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