Added a central RenderState. Reworked Cameras to use it. This means that Camera classes are no longer needed in render_core.

This commit is contained in:
Relintai 2023-12-31 20:38:51 +01:00
parent cb6408a2d4
commit e0bde10e93
16 changed files with 320 additions and 197 deletions

View File

@ -61,6 +61,7 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh.cpp -o sfw/render
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh_utils.cpp -o sfw/render_core/mesh_utils.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/texture.cpp -o sfw/render_core/texture.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/image.cpp -o sfw/render_core/image.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/render_state.cpp -o sfw/render_core/render_state.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_objects/camera_3d.cpp -o sfw/render_objects/camera_3d.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_objects/object_3d.cpp -o sfw/render_objects/object_3d.o
@ -88,7 +89,7 @@ ccache g++ -Wall -lm -ldl -lpthread -lX11 -D_REENTRANT -g sfw/core/aabb.o sfw/c
sfw/object/variant.o sfw/object/variant_op.o sfw/object/psignal.o \
sfw/object/array.o sfw/object/dictionary.o sfw/object/ref_ptr.o \
sfw/object/resource.o \
sfw/render_core/image.o \
sfw/render_core/image.o sfw/render_core/render_state.o \
sfw/render_core/application.o sfw/render_core/scene.o sfw/render_core/window.o \
sfw/render_core/shader.o sfw/render_core/material.o sfw/render_core/mesh.o \
sfw/render_core/mesh_utils.o sfw/render_core/texture.o \

View File

@ -100,7 +100,9 @@ void GameScene::render() {
glClear(GL_COLOR_BUFFER_BIT);
static float rot = 0;
camera->camera_transform.basis = Basis(Vector3(0, 1, 0), rot);
Transform t = camera->get_camera_transform();
t.basis = Basis(Vector3(0, 1, 0), rot);
camera->set_camera_transform(t);
rot += 0.01;
Ref<Image> d = texture->get_data();
@ -185,12 +187,15 @@ GameScene::GameScene() {
tile_map->transform.set_origin(Vector2(500, 500));
camera = new PerspectiveCamera();
Transform t = camera->get_camera_transform();
//camera->width = 2;
//camera->height = 2;
//camera->position.x = 0;
//camera->position.y = 0;
//camera->position.z = -2;
camera->camera_transform.origin.z -= 2;
t.origin.z -= 2;
camera->set_camera_transform(t);
camera->screen_aspect_ratio = 1920.0 / 1080.0;
camera_2d = memnew(Camera2D);

View File

@ -3,7 +3,7 @@
#include "render_core/material.h"
#include "render_objects/camera_3d.h"
#include "render_core/render_state.h"
class ColorMaterial : public Material {
public:
@ -12,14 +12,14 @@ public:
}
void bind_uniforms() {
set_uniform(projection_matrix_location, Camera3D::current_camera->projection_matrix);
set_uniform(camera_matrix_location, Camera3D::current_camera->camera_transform);
set_uniform(model_view_matrix_location, Camera3D::current_camera->model_view_matrix);
set_uniform(projection_matrix_location, RenderState::projection_matrix_3d);
set_uniform(camera_matrix_location, RenderState::camera_transform_3d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_3d);
}
void setup_uniforms() {
projection_matrix_location = get_uniform("u_proj_matrix");
camera_matrix_location = get_uniform("u_camera_matrix");
camera_matrix_location = get_uniform("u_camera_matrix");
model_view_matrix_location = get_uniform("u_model_view_matrix");
}

View File

@ -5,68 +5,66 @@
#include "core/color.h"
#include "render_objects/camera_3d.h"
#include "render_core/render_state.h"
class ColoredMaterial : public Material {
public:
int get_material_id() {
return 1;
}
int get_material_id() {
return 1;
}
void bind_uniforms() {
//glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera3D::current_camera->projection_matrix));
//glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera3D::current_camera->model_view_matrix));
void bind_uniforms() {
set_uniform(projection_matrix_location, RenderState::projection_matrix_3d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_3d);
glUniform4f(tri_color_uniform_location, color.r, color.g, color.b, color.a);
}
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");
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");
}
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"
"\n"
"void main() {\n"
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
"}"
};
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"
"\n"
"void main() {\n"
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
"}"
};
return vertex_shader_source;
}
return vertex_shader_source;
}
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform vec4 fragment_color;\n"
"\n"
"void main() {\n"
" gl_FragColor = fragment_color;\n"
"}"
};
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform vec4 fragment_color;\n"
"\n"
"void main() {\n"
" gl_FragColor = fragment_color;\n"
"}"
};
return fragment_shader_source;
}
return fragment_shader_source;
}
ColoredMaterial() :
Material() {
}
ColoredMaterial() : Material() {
}
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint tri_color_uniform_location;
Color color;
GLint tri_color_uniform_location;
Color color;
};
#endif // COLORED_MATERIAL_H

View File

@ -0,0 +1,8 @@
#include "render_core/render_state.h"
Transform RenderState::camera_transform_3d;
Transform RenderState::model_view_matrix_3d;
Projection RenderState::projection_matrix_3d;
Transform2D RenderState::model_view_matrix_2d;
Transform RenderState::projection_matrix_2d;

View File

@ -0,0 +1,23 @@
#ifndef RENDER_STATE_H
#define RENDER_STATE_H
#include "core/projection.h"
#include "core/transform.h"
#include "core/vector3.h"
#include "core/transform_2d.h"
#include "core/vector2.h"
class RenderState {
public:
static Transform camera_transform_3d;
static Transform model_view_matrix_3d;
static Projection projection_matrix_3d;
static Transform2D model_view_matrix_2d;
static Transform projection_matrix_2d;
//TODO should probably add the current shader here, and active material etc.
};
#endif // RENDER_STATE_H

View File

@ -4,7 +4,7 @@
#include "render_core/material.h"
#include "render_core/texture.h"
#include "render_objects/camera_3d.h"
#include "render_core/render_state.h"
class TextureMaterial : public Material {
public:
@ -13,9 +13,9 @@ public:
}
void bind_uniforms() {
set_uniform(projection_matrix_location, Camera3D::current_camera->projection_matrix);
set_uniform(camera_matrix_location, Camera3D::current_camera->camera_transform);
set_uniform(model_view_matrix_location, Camera3D::current_camera->model_view_matrix);
set_uniform(projection_matrix_location, RenderState::projection_matrix_3d);
set_uniform(camera_matrix_location, RenderState::camera_transform_3d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_3d);
if (texture) {
glActiveTexture(GL_TEXTURE0);

View File

@ -4,7 +4,7 @@
#include "render_core/material.h"
#include "render_core/texture.h"
#include "render_objects/camera_2d.h"
#include "render_core/render_state.h"
class TextureMaterial2D : public Material {
public:
@ -13,8 +13,8 @@ public:
}
void bind_uniforms() {
set_uniform(projection_matrix_location, Camera2D::current_camera->projection_matrix);
set_uniform(model_view_matrix_location, Camera2D::current_camera->model_view_matrix);
set_uniform(projection_matrix_location, RenderState::projection_matrix_2d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_2d);
if (texture) {
glActiveTexture(GL_TEXTURE0);

View File

@ -4,97 +4,93 @@
#include "render_core/material.h"
#include "render_core/texture.h"
#include "./libs/glm/vec4.hpp"
#include "./libs/glm/gtc/type_ptr.hpp"
#include "render_objects/camera_3d.h"
#include "render_core/render_state.h"
class TransparentTextureMaterial : public Material {
public:
int get_material_id() {
return 4;
}
int get_material_id() {
return 4;
}
void bind_uniforms() {
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera3D::current_camera->projection_matrix));
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera3D::current_camera->model_view_matrix));
void bind_uniforms() {
set_uniform(projection_matrix_location, RenderState::projection_matrix_3d);
set_uniform(model_view_matrix_location, RenderState::model_view_matrix_3d);
if (texture) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->get_gl_texture());
glUniform1i(texture_location, 0);
}
}
if (texture) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->get_gl_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");
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");
}
texture_location = get_uniform("u_texture");
}
void unbind() {
glDisable(GL_TEXTURE_2D);
}
void unbind() {
glDisable(GL_TEXTURE_2D);
}
void setup_state() {
glEnable(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"
"}"
};
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;
}
return vertex_shader_source;
}
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform sampler2D u_texture;\n"
"\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"
"\n"
" gl_FragColor = col;\n"
"}"
};
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform sampler2D u_texture;\n"
"\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"
"\n"
" gl_FragColor = col;\n"
"}"
};
return fragment_shader_source;
}
return fragment_shader_source;
}
TransparentTextureMaterial() : Material() {
texture_location = 0;
texture = NULL;
}
TransparentTextureMaterial() :
Material() {
texture_location = 0;
texture = NULL;
}
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint texture_location;
GLint texture_location;
Texture *texture;
Texture *texture;
};
#endif // COLORED_MATERIAL_H

View File

@ -2,6 +2,30 @@
#include "core/math_funcs.h"
#include "render_core/render_state.h"
Transform2D Camera2D::get_model_view_matrix() {
return _model_view_matrix;
}
void Camera2D::set_model_view_matrix(const Transform2D &p_value) {
_model_view_matrix = p_value;
if (current_camera == this) {
RenderState::model_view_matrix_2d = _model_view_matrix;
}
}
Transform Camera2D::get_projection_matrix() {
return _projection_matrix;
}
void Camera2D::set_projection_matrix(const Transform &p_value) {
_projection_matrix = p_value;
if (current_camera == this) {
RenderState::projection_matrix_2d = _projection_matrix;
}
}
void Camera2D::bind() {
make_current();
@ -9,9 +33,12 @@ void Camera2D::bind() {
canvas_transform.translate_local(-(size.width / 2.0f), -(size.height / 2.0f), 0.0f);
//canvas_transform.scale(Vector3(2.0f / size.width, 2.0f / size.height, 1.0f));
canvas_transform.scale(Vector3(2.0f / size.width, -2.0f / size.height, 1.0f));
projection_matrix = canvas_transform;
model_view_matrix = Transform2D();
_projection_matrix = canvas_transform;
_model_view_matrix = Transform2D();
RenderState::model_view_matrix_2d = _model_view_matrix;
RenderState::projection_matrix_2d = _projection_matrix;
}
void Camera2D::make_current() {

View File

@ -11,6 +11,12 @@
class Camera2D : Object2D {
public:
Transform2D get_model_view_matrix();
void set_model_view_matrix(const Transform2D &p_value);
Transform get_projection_matrix();
void set_projection_matrix(const Transform &p_value);
virtual void bind();
void make_current();
@ -29,8 +35,9 @@ public:
static Camera2D *current_camera;
Transform2D model_view_matrix;
Transform projection_matrix;
protected:
Transform2D _model_view_matrix;
Transform _projection_matrix;
};
#endif // CAMERA_H

View File

@ -2,10 +2,49 @@
#include "core/math_funcs.h"
#include "render_core/render_state.h"
Transform Camera3D::get_camera_transform() {
return _camera_transform;
}
void Camera3D::set_camera_transform(const Transform &p_value) {
_camera_transform = p_value;
if (current_camera == this) {
RenderState::camera_transform_3d = _camera_transform;
}
}
Transform Camera3D::get_model_view_matrix() {
return _model_view_matrix;
}
void Camera3D::set_model_view_matrix(const Transform &p_value) {
_model_view_matrix = p_value;
if (current_camera == this) {
RenderState::model_view_matrix_3d = _model_view_matrix;
}
}
Projection Camera3D::get_projection_matrix() {
return _projection_matrix;
}
void Camera3D::set_projection_matrix(const Projection &p_value) {
_projection_matrix = p_value;
if (current_camera == this) {
RenderState::projection_matrix_3d = _projection_matrix;
}
}
void Camera3D::bind() {
make_current();
model_view_matrix = Transform();
_model_view_matrix = Transform();
RenderState::camera_transform_3d = _camera_transform;
RenderState::model_view_matrix_3d = _model_view_matrix;
RenderState::projection_matrix_3d = _projection_matrix;
}
void Camera3D::make_current() {
@ -27,13 +66,14 @@ Camera3D::~Camera3D() {
Camera3D *Camera3D::current_camera = NULL;
void OrthographicCamera::bind() {
Camera3D::bind();
projection_matrix.set_orthogonal(
_projection_matrix.set_orthogonal(
size,
screen_aspect_ratio,
znear,
zfar,
vaspect);
Camera3D::bind();
}
OrthographicCamera::OrthographicCamera() :
@ -43,14 +83,14 @@ OrthographicCamera::~OrthographicCamera() {
}
void PerspectiveCamera::bind() {
Camera3D::bind();
projection_matrix.set_perspective(
_projection_matrix.set_perspective(
fov,
screen_aspect_ratio,
znear,
zfar,
vaspect);
Camera3D::bind();
}
PerspectiveCamera::PerspectiveCamera() :
@ -62,6 +102,14 @@ PerspectiveCamera::~PerspectiveCamera() {
}
void FrustumCamera::bind() {
_projection_matrix.set_frustum(
size,
screen_aspect_ratio,
offset,
znear,
zfar,
vaspect);
Camera3D::bind();
}
@ -69,7 +117,7 @@ FrustumCamera::FrustumCamera() :
Camera3D() {
offset = 0;
projection_matrix.set_frustum(
_projection_matrix.set_frustum(
size,
screen_aspect_ratio,
offset,

View File

@ -9,6 +9,15 @@
class Camera3D {
public:
Transform get_camera_transform();
void set_camera_transform(const Transform &p_value);
Transform get_model_view_matrix();
void set_model_view_matrix(const Transform &p_value);
Projection get_projection_matrix();
void set_projection_matrix(const Projection &p_value);
virtual void bind();
void make_current();
@ -17,16 +26,17 @@ public:
virtual ~Camera3D();
float size;
float screen_aspect_ratio; //p_viewport_size.width / (float)p_viewport_size.height,
float screen_aspect_ratio; //p_viewport_size.width / (float)p_viewport_size.height,
float znear;
float zfar;
bool vaspect;
bool vaspect;
static Camera3D *current_camera;
Transform camera_transform;
Transform model_view_matrix;
Projection projection_matrix;
protected:
Transform _camera_transform;
Transform _model_view_matrix;
Projection _projection_matrix;
};
class OrthographicCamera : public Camera3D {
@ -50,12 +60,11 @@ public:
class FrustumCamera : public Camera3D {
public:
float offset;
void bind();
FrustumCamera();
~FrustumCamera();
};
#endif // CAMERA_H

View File

@ -3,35 +3,35 @@
#include "render_objects/camera_2d.h"
void MeshInstance2D::render() {
if (!mesh) {
return;
}
if (!mesh) {
return;
}
Transform2D mat_orig = Camera2D::current_camera->model_view_matrix;
Transform2D mat_orig = Camera2D::current_camera->get_model_view_matrix();
Camera2D::current_camera->model_view_matrix *= transform;
Camera2D::current_camera->set_model_view_matrix(mat_orig * transform);
if (material) {
material->bind();
}
if (material) {
material->bind();
}
mesh->render();
mesh->render();
for (int i = 0; i < children.size(); ++i) {
MeshInstance2D * c = children[i];
for (int i = 0; i < children.size(); ++i) {
MeshInstance2D *c = children[i];
if (c) {
c->render();
}
}
if (c) {
c->render();
}
}
Camera2D::current_camera->model_view_matrix = mat_orig;
Camera2D::current_camera->set_model_view_matrix(mat_orig);
}
MeshInstance2D::MeshInstance2D() {
material = NULL;
mesh = NULL;
material = NULL;
mesh = NULL;
}
MeshInstance2D::~MeshInstance2D() {
children.clear();
children.clear();
}

View File

@ -3,35 +3,35 @@
#include "render_objects/camera_3d.h"
void MeshInstance3D::render() {
if (!mesh) {
return;
}
if (!mesh) {
return;
}
Transform mat_orig = Camera3D::current_camera->model_view_matrix;
Transform mat_orig = Camera3D::current_camera->get_model_view_matrix();
Camera3D::current_camera->model_view_matrix *= transform;
Camera3D::current_camera->set_model_view_matrix(mat_orig * transform);
if (material) {
material->bind();
}
if (material) {
material->bind();
}
mesh->render();
mesh->render();
for (int i = 0; i < children.size(); ++i) {
MeshInstance3D * c = children[i];
for (int i = 0; i < children.size(); ++i) {
MeshInstance3D *c = children[i];
if (c) {
c->render();
}
}
if (c) {
c->render();
}
}
Camera3D::current_camera->model_view_matrix = mat_orig;
Camera3D::current_camera->set_model_view_matrix(mat_orig);
}
MeshInstance3D::MeshInstance3D() {
material = NULL;
mesh = NULL;
material = NULL;
mesh = NULL;
}
MeshInstance3D::~MeshInstance3D() {
children.clear();
children.clear();
}

View File

@ -98,12 +98,13 @@ void TileMap::set_data(const int x, const int y, const uint8_t value) {
}
void TileMap::render() {
if (!mesh)
if (!mesh) {
return;
}
Transform2D mat_orig = Camera2D::current_camera->model_view_matrix;
Transform2D mat_orig = Camera2D::current_camera->get_model_view_matrix();
Camera2D::current_camera->model_view_matrix *= transform;
Camera2D::current_camera->set_model_view_matrix(mat_orig * transform);
if (material) {
material->bind();
@ -111,7 +112,7 @@ void TileMap::render() {
mesh->render();
Camera2D::current_camera->model_view_matrix = mat_orig;
Camera2D::current_camera->set_model_view_matrix(mat_orig);
}
TileMap::TileMap() :