diff --git a/compile_linux.sh b/compile_linux.sh index bc0ff8c..d63d335 100755 --- a/compile_linux.sh +++ b/compile_linux.sh @@ -49,6 +49,8 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/mate ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/mesh.cpp -o sfw/application/mesh.o ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/camera.cpp -o sfw/application/camera.o ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/mesh_instance.cpp -o sfw/application/mesh_instance.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/camera_2d.cpp -o sfw/application/camera_2d.o +ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/mesh_instance_2d.cpp -o sfw/application/mesh_instance_2d.o ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/object_2d.cpp -o sfw/application/object_2d.o ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/sprite.cpp -o sfw/application/sprite.o ccache g++ -Wall -D_REENTRANT -g -Isfw -Isfw/application -c sfw/application/tile_map.cpp -o sfw/application/tile_map.o @@ -68,6 +70,7 @@ ccache g++ -Wall -lm -ldl -lpthread -lX11 -D_REENTRANT -g sfw/aabb.o sfw/basis. sfw/application/shader.o sfw/application/material.o sfw/application/mesh.o \ sfw/application/camera.o sfw/application/mesh_instance.o sfw/application/object_2d.o \ sfw/application/sprite.o sfw/application/tile_map.o sfw/application/texture.o \ + sfw/application/camera_2d.o sfw/application/mesh_instance_2d.o \ sfw/application/mesh_utils.o \ game_scene.o main.o \ -o game diff --git a/game_scene.cpp b/game_scene.cpp index b9b291c..791d40e 100644 --- a/game_scene.cpp +++ b/game_scene.cpp @@ -116,7 +116,8 @@ void GameScene::render() { rotmi += 0.01; mi->render(); - //sprite->render(); + camera_2d->bind(); + sprite->render(); } GameScene::GameScene() { @@ -134,23 +135,24 @@ GameScene::GameScene() { //float ar = static_cast(w) / static_cast(h); //camera->width = camera->height * ar; - //texture = new Texture(); - //texture->load_image("icon.png"); + texture = new Texture(); + texture->load_image("icon.png"); //ha a textúrának van alpha csatornája: //texture->load_image("download.bmp", GL_RGBA, GL_RGBA); - //material = new TextureMaterial(); - //material->texture = texture; + material = new TextureMaterial2D(); + material->texture = texture; - //sprite = new Sprite(); - //sprite->mesh_instance->material = material; - //sprite->position.x = 0; - //sprite->position.y = 0; + sprite = new Sprite(); + sprite->mesh_instance->material = material; + sprite->width = 500; + sprite->height = 500; + sprite->transform.set_origin(Vector2(250, 250)); //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(); + sprite->update_mesh(); /* tile_map = new TileMap(); tile_map->material = material; @@ -179,7 +181,10 @@ GameScene::GameScene() { //camera->position.y = 0; //camera->position.z = -2; camera->camera_transform.origin.z -= 2; - camera->screen_aspect_ratio = 1980.0 / 1080.0; + camera->screen_aspect_ratio = 1920.0 / 1080.0; + + camera_2d = memnew(Camera2D); + camera_2d->size = Vector2(1920, 1080); mesh = memnew(Mesh()); //cmaterial = memnew(ColoredMaterial()); diff --git a/game_scene.h b/game_scene.h index f6994fa..3170e0d 100644 --- a/game_scene.h +++ b/game_scene.h @@ -5,20 +5,23 @@ /* -#include "mesh_instance.h" -#include "sprite.h" + + #include "texture.h" #include "texture_material.h" #include "tile_map.h" */ +#include "mesh_instance.h" #include "camera.h" +#include "camera_2d.h" #include "color_material.h" #include "colored_material.h" #include "mesh.h" #include "sprite.h" #include "texture.h" #include "texture_material.h" +#include "texture_material_2d.h" class GameScene : public Scene { public: @@ -35,12 +38,12 @@ public: bool down; */ - /* Texture *texture; - TextureMaterial *material; + TextureMaterial2D *material; + + Camera2D *camera_2d; //TileMap *tile_map; Sprite *sprite; - */ Camera *camera; Mesh *mesh; diff --git a/sfw/application/camera_2d.cpp b/sfw/application/camera_2d.cpp new file mode 100644 index 0000000..2de2f7d --- /dev/null +++ b/sfw/application/camera_2d.cpp @@ -0,0 +1,26 @@ +#include "camera_2d.h" + +#include "math_funcs.h" + +void Camera2D::bind() { + make_current(); + + Transform canvas_transform; + 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(); +} + +void Camera2D::make_current() { + current_camera = this; +} + +Camera2D::Camera2D() { +} +Camera2D::~Camera2D() { +} + +Camera2D *Camera2D::current_camera = NULL; diff --git a/sfw/application/camera_2d.h b/sfw/application/camera_2d.h new file mode 100644 index 0000000..d65f64f --- /dev/null +++ b/sfw/application/camera_2d.h @@ -0,0 +1,31 @@ +#ifndef CAMERA_2D_H +#define CAMERA_2D_H + +#include "3rd_glad.h" + +#include "transform.h" +#include "transform_2d.h" +#include "vector2.h" + +class Camera2D { +public: + virtual void bind(); + + void make_current(); + + Camera2D(); + virtual ~Camera2D(); + + Vector2 size; + + //RenderTexture target ? + //bool auto_set_size? + //func auto_set_size()? + + static Camera2D *current_camera; + + Transform2D model_view_matrix; + Transform projection_matrix; +}; + +#endif // CAMERA_H diff --git a/sfw/application/mesh_instance_2d.cpp b/sfw/application/mesh_instance_2d.cpp new file mode 100644 index 0000000..b64d406 --- /dev/null +++ b/sfw/application/mesh_instance_2d.cpp @@ -0,0 +1,37 @@ +#include "mesh_instance_2d.h" + +#include "camera_2d.h" + +void MeshInstance2D::render() { + if (!mesh) { + return; + } + + Transform2D mat_orig = Camera2D::current_camera->model_view_matrix; + + Camera2D::current_camera->model_view_matrix *= transform; + + if (material) { + material->bind(); + } + + mesh->render(); + + for (uint32_t i = 0; i < children.size(); ++i) { + MeshInstance2D * c = children[i]; + + if (c) { + c->render(); + } + } + + Camera2D::current_camera->model_view_matrix = mat_orig; +} + +MeshInstance2D::MeshInstance2D() { + material = NULL; + mesh = NULL; +} +MeshInstance2D::~MeshInstance2D() { + children.clear(); +} diff --git a/sfw/application/mesh_instance_2d.h b/sfw/application/mesh_instance_2d.h new file mode 100644 index 0000000..d73259b --- /dev/null +++ b/sfw/application/mesh_instance_2d.h @@ -0,0 +1,26 @@ +#ifndef MESH_INSTACE_2D_H +#define MESH_INSTACE_2D_H + +#include + +#include "material.h" +#include "mesh.h" + +#include "transform.h" + +class MeshInstance2D { +public: + void render(); + + MeshInstance2D(); + ~MeshInstance2D(); + + Material *material; + Mesh *mesh; + + Transform2D transform; + + std::vector children; +}; + +#endif // MESH_INSTACE_H diff --git a/sfw/application/sprite.cpp b/sfw/application/sprite.cpp index e9641ff..d41e7e2 100644 --- a/sfw/application/sprite.cpp +++ b/sfw/application/sprite.cpp @@ -1,63 +1,77 @@ #include "sprite.h" void Sprite::render() { - /* - mesh_instance->position.x = position.x; - mesh_instance->position.y = position.y; + /* + mesh_instance->position.x = position.x; + mesh_instance->position.y = position.y; - mesh_instance->rotation.z = rotation; + mesh_instance->rotation.z = rotation; - mesh_instance->scale.x = scale.x; - mesh_instance->scale.y = scale.y; - */ + mesh_instance->scale.x = scale.x; + mesh_instance->scale.y = scale.y; + */ - mesh_instance->render(); + mesh_instance->transform = transform; + mesh_instance->render(); } void Sprite::update_mesh() { - Mesh *mesh = mesh_instance->mesh; + Mesh *mesh = mesh_instance->mesh; - mesh->clear(); + mesh->clear(); - float w2 = width / 2.0; - float h2 = height / 2.0; + 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_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_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_y + region_height); + mesh->add_vertex2(-w2, -h2); - mesh->add_uv(region_x + region_width, region_y); - 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->add_uv(region_x, region_y); + mesh->add_vertex2(-w2, -h2); - mesh->upload(); + 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); +Sprite::Sprite() : + Object2D() { + mesh_instance = new MeshInstance2D(); + mesh_instance->mesh = new Mesh(2); - width = 1; - height = 1; + width = 1; + height = 1; - region_x = 0; - region_y = 0; - region_width = 1; - region_height = 1; + region_x = 0; + region_y = 0; + region_width = 1; + region_height = 1; } Sprite::~Sprite() { - delete mesh_instance->mesh; - delete mesh_instance; + delete mesh_instance->mesh; + delete mesh_instance; } - - - - diff --git a/sfw/application/sprite.h b/sfw/application/sprite.h index f6f6c68..41c27b5 100644 --- a/sfw/application/sprite.h +++ b/sfw/application/sprite.h @@ -3,7 +3,8 @@ #include "object_2d.h" -#include "mesh_instance.h" +#include "transform_2d.h" +#include "mesh_instance_2d.h" class Sprite : public Object2D { public: @@ -13,7 +14,9 @@ public: Sprite(); ~Sprite(); - MeshInstance *mesh_instance; + Transform2D transform; + + MeshInstance2D *mesh_instance; float width; float height; diff --git a/sfw/application/texture_material_2d.h b/sfw/application/texture_material_2d.h new file mode 100644 index 0000000..0bd2a9e --- /dev/null +++ b/sfw/application/texture_material_2d.h @@ -0,0 +1,99 @@ +#ifndef TEXTURE_MATERIAL_2D_H +#define TEXTURE_MATERIAL_2D_H + +#include "material.h" +#include "texture.h" + +#include "camera_2d.h" + +class TextureMaterial2D : public Material { +public: + int get_material_id() { + return 10; + } + + 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); + + 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" + "\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; + } + + TextureMaterial2D() : + Material() { + projection_matrix_location = 0; + model_view_matrix_location = 0; + + texture_location = 0; + texture = NULL; + } + + GLint projection_matrix_location; + GLint model_view_matrix_location; + + GLint texture_location; + + Texture *texture; +}; + +#endif // COLORED_MATERIAL_H