mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-06-19 03:06:37 +02:00
initial import, >900commits predate this
This commit is contained in:
203
framework/opengl_renderer/CMakeLists.txt
Normal file
203
framework/opengl_renderer/CMakeLists.txt
Normal file
@ -0,0 +1,203 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(opengl_renderer CXX)
|
||||
|
||||
add_library(opengl_renderer_s
|
||||
src/mm/opengl/render_task.hpp
|
||||
|
||||
src/mm/services/opengl_renderer.hpp
|
||||
src/mm/services/opengl_renderer.cpp
|
||||
|
||||
src/mm/opengl/camera_3d.hpp
|
||||
src/mm/opengl/camera_3d.cpp
|
||||
)
|
||||
|
||||
target_include_directories(opengl_renderer_s PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
add_definitions(-DGLM_ENABLE_EXPERIMENTAL)
|
||||
target_link_libraries(opengl_renderer_s
|
||||
engine
|
||||
logger
|
||||
|
||||
opengl_primitives
|
||||
sdl_service
|
||||
)
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
set_target_properties(opengl_renderer_s PROPERTIES COMPILE_FLAGS "-s USE_SDL=2")
|
||||
set_target_properties(opengl_renderer_s PROPERTIES LINK_FLAGS "-s USE_SDL=2")
|
||||
endif()
|
||||
|
||||
############# imgui render task ###########
|
||||
|
||||
add_library(imgui_render_task
|
||||
src/mm/opengl/render_tasks/imgui.hpp
|
||||
src/mm/opengl/render_tasks/imgui.cpp
|
||||
)
|
||||
|
||||
target_include_directories(imgui_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
#add_definitions(-DGLM_ENABLE_EXPERIMENTAL)
|
||||
target_link_libraries(imgui_render_task
|
||||
opengl_renderer_s
|
||||
|
||||
imgui
|
||||
icon_font_cpp_headers
|
||||
)
|
||||
|
||||
############# simple rect render task ###########
|
||||
|
||||
add_library(simple_rect_render_task
|
||||
src/mm/opengl/render_tasks/simple_rect.hpp
|
||||
src/mm/opengl/render_tasks/simple_rect.cpp
|
||||
)
|
||||
|
||||
target_include_directories(simple_rect_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(simple_rect_render_task
|
||||
opengl_renderer_s
|
||||
common_components
|
||||
engine
|
||||
)
|
||||
|
||||
############# simple sprite render task ###########
|
||||
|
||||
add_library(simple_sprite_render_task
|
||||
src/mm/opengl/render_tasks/simple_sprite.hpp
|
||||
src/mm/opengl/render_tasks/simple_sprite.cpp
|
||||
)
|
||||
|
||||
target_include_directories(simple_sprite_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(simple_sprite_render_task
|
||||
opengl_renderer_s
|
||||
common_components
|
||||
engine
|
||||
)
|
||||
|
||||
############# simple spritesheet render task ###########
|
||||
|
||||
add_library(simple_spritesheet_render_task
|
||||
src/mm/opengl/render_tasks/simple_spritesheet.hpp
|
||||
src/mm/opengl/render_tasks/spritesheet_renderable.hpp
|
||||
|
||||
src/mm/opengl/render_tasks/simple_spritesheet.cpp
|
||||
)
|
||||
|
||||
target_include_directories(simple_spritesheet_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(simple_spritesheet_render_task
|
||||
opengl_renderer_s
|
||||
common_components
|
||||
engine
|
||||
)
|
||||
|
||||
############# batched spritesheet render task ###########
|
||||
|
||||
add_library(batched_spritesheet_render_task
|
||||
src/mm/opengl/render_tasks/batched_spritesheet.hpp
|
||||
src/mm/opengl/render_tasks/spritesheet_renderable.hpp # dup?
|
||||
|
||||
src/mm/opengl/render_tasks/batched_spritesheet.cpp
|
||||
)
|
||||
|
||||
target_include_directories(batched_spritesheet_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(batched_spritesheet_render_task
|
||||
opengl_renderer_s
|
||||
common_components
|
||||
engine
|
||||
)
|
||||
|
||||
############# clear render task ###########
|
||||
|
||||
add_library(clear_render_task
|
||||
src/mm/opengl/render_tasks/clear.hpp
|
||||
src/mm/opengl/render_tasks/clear.cpp
|
||||
)
|
||||
|
||||
target_include_directories(clear_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(clear_render_task
|
||||
opengl_renderer_s
|
||||
engine
|
||||
)
|
||||
|
||||
############# blit fb render task ###########
|
||||
|
||||
add_library(blit_fb_render_task
|
||||
src/mm/opengl/render_tasks/blit_fb.hpp
|
||||
src/mm/opengl/render_tasks/blit_fb.cpp
|
||||
)
|
||||
|
||||
target_include_directories(blit_fb_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(blit_fb_render_task
|
||||
opengl_renderer_s
|
||||
engine
|
||||
)
|
||||
|
||||
############# copy to fb render task ###########
|
||||
|
||||
add_library(copy_to_fb_render_task
|
||||
src/mm/opengl/render_tasks/copy_to_fb.hpp
|
||||
src/mm/opengl/render_tasks/copy_to_fb.cpp
|
||||
)
|
||||
|
||||
target_include_directories(copy_to_fb_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(copy_to_fb_render_task
|
||||
opengl_renderer_s
|
||||
engine
|
||||
)
|
||||
|
||||
############# blur render task ###########
|
||||
|
||||
add_library(blur_render_task
|
||||
src/mm/opengl/render_tasks/blur.hpp
|
||||
src/mm/opengl/render_tasks/blur.cpp
|
||||
)
|
||||
|
||||
target_include_directories(blur_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(blur_render_task
|
||||
opengl_renderer_s
|
||||
engine
|
||||
)
|
||||
|
||||
############# tilemap renderer ###########
|
||||
|
||||
add_library(tilemap_render_task
|
||||
src/mm/opengl/render_tasks/tilemap.hpp
|
||||
src/mm/opengl/render_tasks/tilemap_renderable.hpp
|
||||
|
||||
src/mm/opengl/render_tasks/tilemap.cpp
|
||||
)
|
||||
|
||||
target_include_directories(tilemap_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(tilemap_render_task
|
||||
opengl_renderer_s
|
||||
engine
|
||||
common_components
|
||||
)
|
||||
|
||||
############# fast sky render task ###########
|
||||
|
||||
add_library(fast_sky_render_task
|
||||
src/mm/opengl/render_tasks/fast_sky_render_task.hpp
|
||||
src/mm/opengl/render_tasks/fast_sky_render_task.cpp
|
||||
)
|
||||
|
||||
target_include_directories(fast_sky_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(fast_sky_render_task
|
||||
opengl_renderer_s
|
||||
engine
|
||||
)
|
||||
|
||||
########################
|
||||
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
182
framework/opengl_renderer/src/mm/opengl/camera_3d.cpp
Normal file
182
framework/opengl_renderer/src/mm/opengl/camera_3d.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
#include "./camera_3d.hpp"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
Camera3D::Camera3D(void) {
|
||||
updateView();
|
||||
}
|
||||
|
||||
void Camera3D::setOrthographic(void) {
|
||||
ortho = true;
|
||||
_projection = glm::ortho(
|
||||
-horizontalViewPortSize / 2,
|
||||
horizontalViewPortSize / 2,
|
||||
-horizontalViewPortSize / (screenRatio * 2),
|
||||
horizontalViewPortSize / (screenRatio * 2),
|
||||
nearPlane,
|
||||
farPlane
|
||||
);
|
||||
}
|
||||
|
||||
void Camera3D::setPerspective(void) {
|
||||
ortho = false;
|
||||
_projection = glm::perspective(fov, screenRatio, nearPlane, farPlane);
|
||||
}
|
||||
|
||||
void Camera3D::updateView(void) {
|
||||
roll = glm::mod(roll, 2*glm::pi<float>());
|
||||
|
||||
if (ortho) {
|
||||
_view = glm::mat4(1);
|
||||
|
||||
_view = glm::rotate(_view, roll, glm::vec3{0.f, 0.f, 1.f});
|
||||
|
||||
auto tmp_trans = glm::mat4(1);
|
||||
tmp_trans[3] = glm::vec4(-translation.x, -translation.y, 0.f, 1.f);
|
||||
_view = _view * tmp_trans;
|
||||
//_view[3] = glm::vec4(-translation.x, -translation.y, 0.f, 1.f);
|
||||
////_view[3] = glm::vec4(-translation.x, -translation.y, 1.0f, 1.f);
|
||||
//_view = glm::translate(_view, glm::vec3{-translation.x, -translation.y, -1.f});
|
||||
|
||||
//_view = glm::inverse(_view);
|
||||
|
||||
_view[2][2] = -1.f;
|
||||
|
||||
// TODO: please fix me
|
||||
} else {
|
||||
pitch = glm::clamp(pitch, -(glm::pi<float>()/2 - 0.00001f), glm::pi<float>()/2 - 0.00001f);
|
||||
yaw = glm::mod(yaw, 2*glm::pi<float>());
|
||||
|
||||
glm::vec3 front {0,0,0};
|
||||
{ // TODO: optimize
|
||||
// if y up/down
|
||||
front.x += up.y * glm::cos(pitch) * glm::cos(-yaw); // TODO: y is yaw inverted??
|
||||
front.y += up.y * glm::sin(pitch);
|
||||
front.z += up.y * glm::cos(pitch) * glm::sin(-yaw);
|
||||
|
||||
// if z up/down
|
||||
front.x += up.z * glm::cos(pitch) * glm::cos(yaw);
|
||||
front.y += up.z * glm::cos(pitch) * glm::sin(yaw);
|
||||
front.z += up.z * glm::sin(pitch);
|
||||
}
|
||||
|
||||
front = glm::normalize(front);
|
||||
|
||||
_view = glm::lookAt(translation, translation + front, up);
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 Camera3D::getViewProjection() const {
|
||||
return _projection * _view;
|
||||
}
|
||||
|
||||
glm::mat4 Camera3D::getView() const {
|
||||
return _view;
|
||||
}
|
||||
|
||||
glm::mat4 Camera3D::getProjection() const {
|
||||
return _projection;
|
||||
}
|
||||
|
||||
std::array<glm::vec4, 6> Camera3D::getFrustumPlanes(void) const {
|
||||
std::array<glm::vec4, 6> planes;
|
||||
|
||||
glm::mat4 wvp = getViewProjection();
|
||||
|
||||
// see:
|
||||
// https://stackoverflow.com/questions/11770262/glm-calculating-the-frustum-from-the-projection-matrix
|
||||
// http://web.archive.org/web/20120531231005/http://crazyjoke.free.fr/doc/3D/plane%20extraction.pdf
|
||||
|
||||
#ifdef LEFT_HANDED
|
||||
// left handed
|
||||
{
|
||||
// Left clipping plane
|
||||
planes[0].x = wvp[0][3] + wvp[0][0];
|
||||
planes[0].y = wvp[1][3] + wvp[1][0];
|
||||
planes[0].z = wvp[2][3] + wvp[2][0];
|
||||
planes[0].w = wvp[3][3] + wvp[3][0];
|
||||
|
||||
// Right clipping plane
|
||||
planes[1].x = wvp[0][3] - wvp[0][0];
|
||||
planes[1].y = wvp[1][3] - wvp[1][0];
|
||||
planes[1].z = wvp[2][3] - wvp[2][0];
|
||||
planes[1].w = wvp[3][3] - wvp[3][0];
|
||||
|
||||
// Top clipping
|
||||
planes[2].x = wvp[0][3] - wvp[0][1];
|
||||
planes[2].y = wvp[1][3] - wvp[1][1];
|
||||
planes[2].z = wvp[2][3] - wvp[2][1];
|
||||
planes[2].w = wvp[3][3] - wvp[3][1];
|
||||
|
||||
// Bottom clipping plane
|
||||
planes[3].x = wvp[0][3] + wvp[0][1];
|
||||
planes[3].y = wvp[1][3] + wvp[1][1];
|
||||
planes[3].z = wvp[2][3] + wvp[2][1];
|
||||
planes[3].w = wvp[3][3] + wvp[3][1];
|
||||
|
||||
// Near clipping plane
|
||||
planes[4].x = wvp[0][2];
|
||||
planes[4].y = wvp[1][2];
|
||||
planes[4].z = wvp[2][2];
|
||||
planes[4].w = wvp[3][2];
|
||||
|
||||
// Far clipping
|
||||
planes[5].x = wvp[0][3] - wvp[0][2];
|
||||
planes[5].y = wvp[1][3] - wvp[1][2];
|
||||
planes[5].z = wvp[2][3] - wvp[2][2];
|
||||
planes[5].w = wvp[3][3] - wvp[3][2];
|
||||
}
|
||||
#else
|
||||
// right handed
|
||||
{
|
||||
// Left clipping plane
|
||||
planes[0].x = wvp[0][3] + wvp[0][0];
|
||||
planes[0].y = wvp[1][3] + wvp[1][0];
|
||||
planes[0].z = wvp[2][3] + wvp[2][0];
|
||||
planes[0].w = wvp[3][3] + wvp[3][0];
|
||||
|
||||
// Right clipping plane
|
||||
planes[1].x = wvp[0][3] - wvp[0][0];
|
||||
planes[1].y = wvp[1][3] - wvp[1][0];
|
||||
planes[1].z = wvp[2][3] - wvp[2][0];
|
||||
planes[1].w = wvp[3][3] - wvp[3][0];
|
||||
|
||||
// Top clipping plane
|
||||
planes[2].x = wvp[0][3] - wvp[0][1];
|
||||
planes[2].y = wvp[1][3] - wvp[1][1];
|
||||
planes[2].z = wvp[2][3] - wvp[2][1];
|
||||
planes[2].w = wvp[3][3] - wvp[3][1];
|
||||
|
||||
// Bottom clipping plane
|
||||
planes[3].x = wvp[0][3] + wvp[0][1];
|
||||
planes[3].y = wvp[1][3] + wvp[1][1];
|
||||
planes[3].z = wvp[2][3] + wvp[2][1];
|
||||
planes[3].w = wvp[3][3] + wvp[3][1];
|
||||
|
||||
// Near clipping plane
|
||||
planes[4].x = wvp[0][3] + wvp[0][2];
|
||||
planes[4].y = wvp[1][3] + wvp[1][2];
|
||||
planes[4].z = wvp[2][3] + wvp[2][2];
|
||||
planes[4].w = wvp[3][3] + wvp[3][2];
|
||||
|
||||
// Far clipping plane
|
||||
planes[5].x = wvp[0][3] - wvp[0][2];
|
||||
planes[5].y = wvp[1][3] - wvp[1][2];
|
||||
planes[5].z = wvp[2][3] - wvp[2][2];
|
||||
planes[5].w = wvp[3][3] - wvp[3][2];
|
||||
}
|
||||
#endif
|
||||
|
||||
// normalize
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
planes[i] = glm::normalize(planes[i]);
|
||||
//planes[i] /= glm::length(glm::vec3(planes[i]));
|
||||
}
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
} // MM::Rendering
|
||||
|
54
framework/opengl_renderer/src/mm/opengl/camera_3d.hpp
Normal file
54
framework/opengl_renderer/src/mm/opengl/camera_3d.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
class Camera3D {
|
||||
private:
|
||||
glm::mat4 _view{1}, _projection{1};
|
||||
|
||||
public:
|
||||
glm::vec3 translation {0.f, 0.f, 0.f};
|
||||
float screenRatio {16.f / 9.f};
|
||||
float nearPlane {0.1f};
|
||||
float farPlane {1000.f};
|
||||
|
||||
// for orth and pers
|
||||
float roll {0.f}; // in rad
|
||||
|
||||
bool ortho {true};
|
||||
|
||||
// for orthogonal
|
||||
float horizontalViewPortSize {100.f}; // 100 meters
|
||||
|
||||
// for perspective (right handed, z up)
|
||||
float fov {glm::half_pi<float>()}; // in rad
|
||||
float yaw {0.f}; // in rad
|
||||
float pitch {0.f}; // in rad
|
||||
glm::vec3 up {0.f, 0.f, 1.f}; // normalize!
|
||||
|
||||
public:
|
||||
Camera3D(void);
|
||||
|
||||
// call this if ortho and horizontalViewPortSize or screenRatio changes
|
||||
void setOrthographic(void);
|
||||
|
||||
// call this if not ortho and fov or screenRation changes
|
||||
void setPerspective(void);
|
||||
|
||||
// call this after changing translation
|
||||
void updateView(void);
|
||||
|
||||
glm::mat4 getViewProjection(void) const;
|
||||
glm::mat4 getView(void) const;
|
||||
glm::mat4 getProjection(void) const;
|
||||
|
||||
// call updateView beforehand, does not cache
|
||||
std::array<glm::vec4, 6> getFrustumPlanes(void) const;
|
||||
};
|
||||
} // MM::OpenGL
|
||||
|
32
framework/opengl_renderer/src/mm/opengl/render_task.hpp
Normal file
32
framework/opengl_renderer/src/mm/opengl/render_task.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
// fwd
|
||||
namespace MM {
|
||||
class Engine;
|
||||
namespace Services {
|
||||
class OpenGLRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#define GLSL_VERSION_STRING "#version 300 es\n"
|
||||
#else
|
||||
#define GLSL_VERSION_STRING "#version 330 core\n"
|
||||
#endif
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
class RenderTask {
|
||||
public:
|
||||
virtual ~RenderTask(void) = default;
|
||||
|
||||
virtual void render(Services::OpenGLRenderer& rs, Engine& engine) = 0;
|
||||
|
||||
// a place to reload/compile shaders etc.
|
||||
//virtual void reload(void) {} // TODO: remove
|
||||
//virtual std::vector<const char*> getShaderPaths(void) {return {};} // TODO: remove
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,244 @@
|
||||
#include "./batched_spritesheet.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include "./spritesheet_renderable.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#define TracyGpuZone(...)
|
||||
#endif
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
BatchedSpriteSheet::BatchedSpriteSheet(Engine& engine) {
|
||||
default_cam.setOrthographic();
|
||||
default_cam.updateView();
|
||||
|
||||
float vertices[] = {
|
||||
-0.5f, 0.5f,
|
||||
-0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, 0.5f,
|
||||
-0.5f, 0.5f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
gl_inst_buffer = std::make_unique<MM::OpenGL::InstanceBuffer<gl_instance_data>>();
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
}
|
||||
|
||||
BatchedSpriteSheet::~BatchedSpriteSheet(void) {
|
||||
}
|
||||
|
||||
void BatchedSpriteSheet::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::BatchedSpriteSheet::render");
|
||||
|
||||
auto* scene_ss = engine.tryService<MM::Services::SceneServiceInterface>();
|
||||
// no scene
|
||||
if (scene_ss == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& scene = scene_ss->getScene();
|
||||
|
||||
struct sp_data {
|
||||
SpriteSheet sp;
|
||||
struct instance_data {
|
||||
MM::Components::Transform2D* trans = nullptr;
|
||||
glm::vec4* color = nullptr;
|
||||
uint32_t tile_index = 0;
|
||||
};
|
||||
std::vector<instance_data> instances;
|
||||
};
|
||||
// HACK: assume same sp for same texture
|
||||
std::unordered_map<MM::OpenGL::Texture::handle, sp_data> batch_map;
|
||||
|
||||
auto view = scene.view<Components::Transform2D, SpriteSheetRenderable>();
|
||||
|
||||
view.each([&](auto e, Components::Transform2D& t, SpriteSheetRenderable& spr) {
|
||||
// if off screen, early out
|
||||
if (false) { // TODO:
|
||||
return;
|
||||
}
|
||||
|
||||
assert(spr.sp.tex); // debug
|
||||
|
||||
// first insert
|
||||
if (!batch_map.count(spr.sp.tex)) {
|
||||
auto& sp_ent = batch_map[spr.sp.tex];
|
||||
sp_ent.sp = spr.sp;
|
||||
}
|
||||
|
||||
auto* tmp_col_ptr = &default_color;
|
||||
if (scene.has<Components::Color>(e)) {
|
||||
tmp_col_ptr = &scene.get<Components::Color>(e).color;
|
||||
}
|
||||
|
||||
auto& tmp_new_ent = batch_map[spr.sp.tex].instances.emplace_back();
|
||||
tmp_new_ent.trans = &t;
|
||||
tmp_new_ent.tile_index = spr.tile_index;
|
||||
tmp_new_ent.color = tmp_col_ptr;
|
||||
});
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
auto* cam = scene.try_ctx<Camera3D>();
|
||||
if (!cam) {
|
||||
cam = &default_cam;
|
||||
}
|
||||
|
||||
auto vp = cam->getViewProjection();
|
||||
_shader->setUniformMat4f("_VP", vp);
|
||||
|
||||
for (auto& sp_ent : batch_map) {
|
||||
TracyGpuZone("MM::OpenGL::RenderTasks::BatchedSpriteSheet::render::sprite_entry");
|
||||
sp_ent.second.sp.tex->bind(0);
|
||||
|
||||
_shader->setUniform2ui("_tileCount", sp_ent.second.sp.tile_count.x, sp_ent.second.sp.tile_count.y);
|
||||
|
||||
auto* inst_memory = gl_inst_buffer->map(sp_ent.second.instances.size(), GL_DYNAMIC_DRAW);
|
||||
for (auto& inst : sp_ent.second.instances) {
|
||||
inst_memory->pos_trans = inst.trans->getTransform4(inst.trans->position.y/10.f + 500.f);
|
||||
inst_memory->color = *inst.color;
|
||||
inst_memory->tile_index = inst.tile_index;
|
||||
|
||||
inst_memory++;
|
||||
}
|
||||
gl_inst_buffer->unmap();
|
||||
|
||||
static_assert(std::is_standard_layout<gl_instance_data>::value); // check if offsetof() is usable
|
||||
|
||||
// mat4, oof
|
||||
// attptr 1-4
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
glVertexAttribPointer(
|
||||
1 + i,
|
||||
4,
|
||||
GL_FLOAT, GL_FALSE,
|
||||
sizeof(gl_instance_data),
|
||||
(void*) (offsetof(gl_instance_data, pos_trans) + sizeof(glm::mat4::row_type) * i)
|
||||
);
|
||||
glVertexAttribDivisor(1 + i, 1);
|
||||
glEnableVertexAttribArray(1 + i);
|
||||
}
|
||||
|
||||
|
||||
glVertexAttribIPointer(5, 1, GL_UNSIGNED_INT, sizeof(gl_instance_data), (void*) offsetof(gl_instance_data, tile_index));
|
||||
glVertexAttribDivisor(5, 1);
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(gl_instance_data), (void*) offsetof(gl_instance_data, color));
|
||||
glVertexAttribDivisor(6, 1);
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, sp_ent.second.instances.size());
|
||||
}
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void BatchedSpriteSheet::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform mat4 _VP;
|
||||
uniform uvec2 _tileCount;
|
||||
|
||||
layout(location = 0) in vec2 _vertexPosition;
|
||||
layout(location = 1) in mat4 _pos_trans;
|
||||
layout(location = 5) in uint _atlasIndex;
|
||||
layout(location = 6) in vec4 _color;
|
||||
|
||||
out vec2 _tex_pos;
|
||||
out vec4 _tex_color;
|
||||
|
||||
void main() {
|
||||
// fwd
|
||||
_tex_color = _color;
|
||||
|
||||
// position
|
||||
gl_Position = _VP * _pos_trans * vec4(_vertexPosition, 0, 1);
|
||||
|
||||
|
||||
// uv
|
||||
uint row = _atlasIndex / _tileCount.x;
|
||||
uint column = _atlasIndex % _tileCount.x;
|
||||
|
||||
_tex_pos.x = (float(column) + 0.5 + _vertexPosition.x) / float(_tileCount.x);
|
||||
_tex_pos.y = 1.0 - (float(row) + 0.5 - _vertexPosition.y) / float(_tileCount.y);
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D _tex0;
|
||||
|
||||
in vec2 _tex_pos;
|
||||
in vec4 _tex_color;
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
vec4 tmp_col = texture(_tex0, _tex_pos) * _tex_color;
|
||||
|
||||
if (tmp_col.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_out_color = tmp_col;
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
|
||||
//#include <glm/fwd.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <mm/opengl/instance_buffer.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class BatchedSpriteSheet : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
struct gl_instance_data {
|
||||
glm::mat4 pos_trans;
|
||||
glm::vec4 color;
|
||||
uint32_t tile_index;
|
||||
};
|
||||
std::unique_ptr<MM::OpenGL::InstanceBuffer<gl_instance_data>> gl_inst_buffer;
|
||||
|
||||
|
||||
public:
|
||||
glm::vec4 default_color {1.f, 1.f, 1.f, 1.f};
|
||||
|
||||
OpenGL::Camera3D default_cam;
|
||||
|
||||
BatchedSpriteSheet(Engine& engine);
|
||||
~BatchedSpriteSheet(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/batched_spritesheet_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/batched_spritesheet_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,40 @@
|
||||
#include "./blit_fb.hpp"
|
||||
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
BlitFB::BlitFB(Engine& engine) {
|
||||
// assuming fbo textures are the size of the window buffer
|
||||
auto [x, y] = engine.getService<MM::Services::SDLService>().getWindowSize();
|
||||
|
||||
srcX1 = x;
|
||||
srcY1 = y;
|
||||
|
||||
dstX1 = x;
|
||||
dstY1 = y;
|
||||
}
|
||||
|
||||
BlitFB::~BlitFB(void) {
|
||||
}
|
||||
|
||||
void BlitFB::render(Services::OpenGLRenderer& rs, Engine&) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::BlitFB::render");
|
||||
|
||||
rs.targets[read_fbo]->bind(FrameBufferObject::R);
|
||||
rs.targets[write_fbo]->bind(FrameBufferObject::W);
|
||||
|
||||
glBlitFramebuffer(
|
||||
srcX0, srcY0,
|
||||
srcX1, srcY1,
|
||||
dstX0, dstY0,
|
||||
dstX1, dstY1,
|
||||
mask,
|
||||
filter
|
||||
);
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class BlitFB : public RenderTask {
|
||||
public:
|
||||
BlitFB(Engine& engine);
|
||||
~BlitFB(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
std::string read_fbo = "game_view";
|
||||
std::string write_fbo = "display";
|
||||
|
||||
// blit params
|
||||
GLint srcX0 = 0;
|
||||
GLint srcY0 = 0;
|
||||
GLint srcX1 = 0; // u will want to set this
|
||||
GLint srcY1 = 0; // u will want to set this
|
||||
|
||||
GLint dstX0 = 0;
|
||||
GLint dstY0 = 0;
|
||||
GLint dstX1 = 0; // u will want to set this
|
||||
GLint dstY1 = 0; // u will want to set this
|
||||
|
||||
GLbitfield mask = GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
|
||||
GLenum filter = GL_NEAREST;
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
135
framework/opengl_renderer/src/mm/opengl/render_tasks/blur.cpp
Normal file
135
framework/opengl_renderer/src/mm/opengl/render_tasks/blur.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
#include "./blur.hpp"
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/opengl/texture.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
Blur::Blur(Engine& engine) {
|
||||
float vertices[] = {
|
||||
-1.f, 1.f,
|
||||
-1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, 1.f,
|
||||
-1.f, 1.f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
}
|
||||
|
||||
Blur::~Blur(void) {
|
||||
}
|
||||
|
||||
void Blur::render(Services::OpenGLRenderer& rs, Engine&) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::Blur::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
rs.targets[src_fbo]->bind(FrameBufferObject::W);
|
||||
{
|
||||
_shader->setUniform1i("horizontal", 1);
|
||||
rs.targets[src_fbo]->_texAttachments.front()->bind(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
{
|
||||
_shader->setUniform1i("horizontal", 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
|
||||
rs.targets[src_fbo]->clear(0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
void Blur::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec2 _vertexPosition;
|
||||
out vec2 _tex;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(_vertexPosition, 0, 1);
|
||||
_tex = vec2(_vertexPosition.x * 0.5 + 0.5, _vertexPosition.y * 0.5 + 0.5);
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex0;
|
||||
|
||||
in vec2 _tex;
|
||||
|
||||
uniform bool horizontal;
|
||||
|
||||
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
vec2 tex_offset = vec2(1.0) / vec2(textureSize(tex0, 0)); // gets size of single texel
|
||||
vec3 result = texture(tex0, _tex).rgb * weight[0]; // current fragment's contribution
|
||||
|
||||
if (horizontal) {
|
||||
for (int i = 1; i < 5; i++) {
|
||||
result += texture(tex0, _tex + vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
|
||||
result += texture(tex0, _tex - vec2(tex_offset.x * float(i), 0.0)).rgb * weight[i];
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < 5; i++) {
|
||||
result += texture(tex0, _tex + vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
|
||||
result += texture(tex0, _tex - vec2(0.0, tex_offset.y * float(i))).rgb * weight[i];
|
||||
}
|
||||
}
|
||||
|
||||
_out_color = vec4(result, 1.0);
|
||||
|
||||
//float brightness = dot(gl_FragColor.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
//if (brightness > 1.0)
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class Blur : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
public:
|
||||
Blur(Engine& engine);
|
||||
~Blur(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/blur_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/blur_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "blur_out";
|
||||
std::string src_fbo = "blur_in";
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,19 @@
|
||||
#include "./clear.hpp"
|
||||
|
||||
//#include <tracy/Tracy.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
Clear::Clear(Engine&) {
|
||||
}
|
||||
|
||||
Clear::~Clear(void) {
|
||||
}
|
||||
|
||||
void Clear::render(Services::OpenGLRenderer& rs, Engine&) {
|
||||
//ZoneScopedN("MM::OpenGL::RenderTasks::Clear::render");
|
||||
rs.targets[target_fbo]->clear(r,g,b,a,mask);
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class Clear : public RenderTask {
|
||||
public:
|
||||
Clear(Engine& engine);
|
||||
~Clear(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
std::string target_fbo = "display";
|
||||
|
||||
float r = 0.f;
|
||||
float g = 0.f;
|
||||
float b = 0.f;
|
||||
float a = 1.f;
|
||||
|
||||
GLbitfield mask = GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,110 @@
|
||||
#include "./copy_to_fb.hpp"
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/opengl/texture.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
CopyToFB::CopyToFB(Engine& engine) {
|
||||
float vertices[] = {
|
||||
-1.f, 1.f,
|
||||
-1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, 1.f,
|
||||
-1.f, 1.f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
}
|
||||
|
||||
CopyToFB::~CopyToFB(void) {
|
||||
}
|
||||
|
||||
void CopyToFB::render(Services::OpenGLRenderer& rs, Engine&) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::CopyToFB::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
auto& rm = MM::ResourceManager<MM::OpenGL::Texture>::ref();
|
||||
|
||||
auto tex = rm.get(entt::hashed_string::value(src_tex.c_str()));
|
||||
tex->bind(0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void CopyToFB::reloadShaders(MM::Engine& engine) {
|
||||
auto tmp_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
if (tmp_shader) {
|
||||
_shader = tmp_shader;
|
||||
}
|
||||
}
|
||||
|
||||
void CopyToFB::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec2 _vertexPosition;
|
||||
out vec2 _tex;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(_vertexPosition, 0, 1);
|
||||
_tex = vec2(_vertexPosition.x * 0.5 + 0.5, _vertexPosition.y * 0.5 + 0.5);
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D tex0;
|
||||
|
||||
in vec2 _tex;
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
_out_color = texture(tex0, _tex);
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class CopyToFB : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
public:
|
||||
CopyToFB(Engine& engine);
|
||||
~CopyToFB(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/copy_to_fb_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/copy_to_fb_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
std::string src_tex = "game_view";
|
||||
|
||||
void reloadShaders(Engine& engine);
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,231 @@
|
||||
#include "./fast_sky_render_task.hpp"
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#define TracyGpuZone(...)
|
||||
#endif
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
FastSky::FastSky(MM::Engine& engine) {
|
||||
setupShaderFiles();
|
||||
_shader = MM::OpenGL::Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
|
||||
float vertices[] = {
|
||||
-1.f, 1.f,
|
||||
-1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, 1.f,
|
||||
-1.f, 1.f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<MM::OpenGL::Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<MM::OpenGL::VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
}
|
||||
|
||||
FastSky::~FastSky(void) {
|
||||
}
|
||||
|
||||
void FastSky::render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::FastSky::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(MM::OpenGL::FrameBufferObject::W);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
//glDepthFunc(GL_LESS);
|
||||
glDisable(GL_BLEND); // i hate my life
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
{
|
||||
auto& cam = scene.ctx<MM::OpenGL::Camera3D>();
|
||||
MM::OpenGL::Camera3D tmp_cam = cam;
|
||||
// create cam with y up, bc shader says so
|
||||
tmp_cam.up = {0, 1, 0};
|
||||
tmp_cam.updateView();
|
||||
|
||||
_shader->setUniformMat4f("V", tmp_cam.getView());
|
||||
_shader->setUniformMat4f("P", cam.getProjection());
|
||||
}
|
||||
|
||||
{
|
||||
auto* ctx_ptr = scene.try_ctx<FastSkyContext>();
|
||||
if (!ctx_ptr) {
|
||||
ctx_ptr = &_default_context;
|
||||
}
|
||||
|
||||
_shader->setUniform1f("time", ctx_ptr->time);
|
||||
|
||||
_shader->setUniform1f("cirrus", ctx_ptr->cirrus);
|
||||
_shader->setUniform1f("cumulus", ctx_ptr->cumulus);
|
||||
|
||||
_shader->setUniform3f("fsun", ctx_ptr->fsun);
|
||||
}
|
||||
|
||||
//glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void FastSky::reloadShaders(MM::Engine& engine) {
|
||||
auto tmp_shader = MM::OpenGL::Shader::createF(engine, vertexPath, fragmentPath);
|
||||
if (tmp_shader) {
|
||||
_shader = tmp_shader;
|
||||
}
|
||||
}
|
||||
|
||||
// the shaders are based on https://github.com/shff/opengl_sky/
|
||||
// with the following LICENSE:
|
||||
|
||||
// MIT License
|
||||
|
||||
//Copyright (c) 2019 Silvio Henrique Ferreira
|
||||
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
|
||||
//The above copyright notice and this permission notice shall be included in all
|
||||
//copies or substantial portions of the Software.
|
||||
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//SOFTWARE.
|
||||
|
||||
void FastSky::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec2 vertex_pos;
|
||||
|
||||
out vec3 pos;
|
||||
|
||||
uniform mat4 P;
|
||||
uniform mat4 V;
|
||||
|
||||
void main() {
|
||||
vec4 tmp_pos = vec4(vertex_pos, 1.0, 1.0);
|
||||
gl_Position = tmp_pos;
|
||||
|
||||
pos = transpose(mat3(V)) * (inverse(P) * tmp_pos).xyz;
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec3 pos;
|
||||
uniform vec3 fsun;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform float time;
|
||||
uniform float cirrus;
|
||||
uniform float cumulus;
|
||||
|
||||
const float Br = 0.0025;
|
||||
const float Bm = 0.0003;
|
||||
const float g = 0.9800;
|
||||
const vec3 nitrogen = vec3(0.650, 0.570, 0.475);
|
||||
const vec3 Kr = Br / pow(nitrogen, vec3(4.0));
|
||||
const vec3 Km = Bm / pow(nitrogen, vec3(0.84));
|
||||
|
||||
float hash(float n) {
|
||||
return fract(sin(n) * 43758.5453123);
|
||||
}
|
||||
|
||||
float noise(vec3 x) {
|
||||
vec3 f = fract(x);
|
||||
float n = dot(floor(x), vec3(1.0, 157.0, 113.0));
|
||||
return mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
|
||||
mix(hash(n + 157.0), hash(n + 158.0), f.x), f.y),
|
||||
mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
|
||||
mix(hash(n + 270.0), hash(n + 271.0), f.x), f.y), f.z);
|
||||
}
|
||||
|
||||
const mat3 m = mat3(0.0, 1.60, 1.20, -1.6, 0.72, -0.96, -1.2, -0.96, 1.28);
|
||||
|
||||
float fbm(vec3 p) {
|
||||
float f = 0.0;
|
||||
f += noise(p) / 2.0; p = m * p * 1.1;
|
||||
f += noise(p) / 4.0; p = m * p * 1.2;
|
||||
f += noise(p) / 6.0; p = m * p * 1.3;
|
||||
f += noise(p) / 12.0; p = m * p * 1.4;
|
||||
f += noise(p) / 24.0;
|
||||
return f;
|
||||
}
|
||||
|
||||
void main() {
|
||||
if (pos.y < 0.0) {
|
||||
discard;
|
||||
//return;
|
||||
}
|
||||
|
||||
// Atmosphere Scattering
|
||||
float mu = dot(normalize(pos), normalize(fsun));
|
||||
vec3 extinction = mix(exp(-exp(-((pos.y + fsun.y * 4.0) * (exp(-pos.y * 16.0) + 0.1) / 80.0) / Br) * (exp(-pos.y * 16.0) + 0.1) * Kr / Br) * exp(-pos.y * exp(-pos.y * 8.0 ) * 4.0) * exp(-pos.y * 2.0) * 4.0, vec3(1.0 - exp(fsun.y)) * 0.2, -fsun.y * 0.2 + 0.5);
|
||||
color.rgb = 3.0 / (8.0 * 3.14) * (1.0 + mu * mu) * (Kr + Km * (1.0 - g * g) / (2.0 + g * g) / pow(1.0 + g * g - 2.0 * g * mu, 1.5)) / (Br + Bm) * extinction;
|
||||
|
||||
// Cirrus Clouds
|
||||
float density = smoothstep(1.0 - cirrus, 1.0, fbm(pos.xyz / pos.y * 2.0 + time * 0.05)) * 0.3;
|
||||
color.rgb = mix(color.rgb, extinction * 4.0, density * max(pos.y, 0.0));
|
||||
|
||||
// Cumulus Clouds
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float density = smoothstep(1.0 - cumulus, 1.0, fbm((0.7 + float(i) * 0.01) * pos.xyz / pos.y + time * 0.3));
|
||||
color.rgb = mix(color.rgb, extinction * density * 5.0, min(density, 1.0) * max(pos.y, 0.0));
|
||||
}
|
||||
|
||||
// Dithering Noise
|
||||
color.rgb += noise(pos * 1000.0) * 0.01; // needed?
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
|
||||
namespace RenderTasks {
|
||||
|
||||
struct FastSkyContext {
|
||||
float time = 0.f;
|
||||
|
||||
float cirrus = 0.4f;
|
||||
float cumulus = 0.8f;
|
||||
|
||||
glm::vec3 fsun {0,0,1};
|
||||
};
|
||||
|
||||
class FastSky : public MM::OpenGL::RenderTask {
|
||||
private:
|
||||
std::shared_ptr<MM::OpenGL::Shader> _shader;
|
||||
std::unique_ptr<MM::OpenGL::Buffer> _vertexBuffer;
|
||||
std::unique_ptr<MM::OpenGL::VertexArrayObject> _vao;
|
||||
|
||||
FastSkyContext _default_context;
|
||||
|
||||
public:
|
||||
FastSky(MM::Engine& engine);
|
||||
~FastSky(void);
|
||||
|
||||
void render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/fast_sky_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/fast_sky_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
|
||||
void reloadShaders(MM::Engine& engine);
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // RenderTasks
|
||||
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,38 @@
|
||||
#include <mm/opengl/render_tasks/imgui.hpp> // bc imgui.hpp is overused
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#define TracyGpuZone(...)
|
||||
#endif
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
ImGuiRT::ImGuiRT(Engine&) {
|
||||
assert(ImGui::GetCurrentContext());
|
||||
}
|
||||
|
||||
ImGuiRT::~ImGuiRT(void) {
|
||||
}
|
||||
|
||||
void ImGuiRT::render(Services::OpenGLRenderer& rs, Engine&) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::ImGuiRT::render");
|
||||
TracyGpuZone("MM::OpenGL::RenderTasks::ImGuiRT::render");
|
||||
|
||||
rs.targets["display"]->bind(FrameBufferObject::W);
|
||||
|
||||
// render
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
// RT to avoid name collisons
|
||||
class ImGuiRT : public RenderTask {
|
||||
public:
|
||||
ImGuiRT(Engine& engine);
|
||||
~ImGuiRT(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,134 @@
|
||||
#include "./simple_rect.hpp"
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_SRR(x) LOG("SimpleRectRenderTask", x)
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
SimpleRect::SimpleRect(Engine& engine) {
|
||||
default_cam.setOrthographic();
|
||||
default_cam.updateView();
|
||||
|
||||
float vertices[] = {
|
||||
-0.5f, 0.5f,
|
||||
-0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, 0.5f,
|
||||
-0.5f, 0.5f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
}
|
||||
|
||||
SimpleRect::~SimpleRect(void) {
|
||||
}
|
||||
|
||||
void SimpleRect::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::SimpleRect::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
//_shader->setUniform4f("_color", default_color);
|
||||
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
Camera3D* cam = scene.try_ctx<Camera3D>();
|
||||
if (!cam) {
|
||||
cam = &default_cam;
|
||||
}
|
||||
|
||||
auto vp = cam->getViewProjection();
|
||||
|
||||
auto view = scene.view<MM::Components::Transform2D>();
|
||||
|
||||
for (auto& e : view) {
|
||||
auto& t = view.get(e);
|
||||
|
||||
_shader->setUniformMat4f("_WVP", vp * t.getTransform4(t.position.y/10.f + 500.f));
|
||||
|
||||
if (scene.has<Components::Color>(e)) {
|
||||
_shader->setUniform4f("_color", scene.get<Components::Color>(e).color);
|
||||
} else {
|
||||
_shader->setUniform4f("_color", default_color);
|
||||
}
|
||||
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void SimpleRect::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec2 _vertexPosition;
|
||||
uniform mat4 _WVP;
|
||||
|
||||
void main() {
|
||||
gl_Position = _WVP * vec4(_vertexPosition, 0, 1);
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec4 _color;
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
_out_color = _color;
|
||||
//gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
|
||||
//#include <glm/fwd.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class SimpleRect : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
public:
|
||||
glm::vec4 default_color {1,1,1,1};
|
||||
|
||||
Camera3D default_cam;
|
||||
|
||||
SimpleRect(Engine& engine);
|
||||
~SimpleRect(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/simple_rect_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/simple_rect_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,153 @@
|
||||
#include "./simple_sprite.hpp"
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/opengl/components/texture.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#define TracyGpuZone(...)
|
||||
#endif
|
||||
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
SimpleSprite::SimpleSprite(Engine& engine) {
|
||||
default_cam.setOrthographic();
|
||||
default_cam.updateView();
|
||||
|
||||
float vertices[] = {
|
||||
-0.5f, 0.5f,
|
||||
-0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, 0.5f,
|
||||
-0.5f, 0.5f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
}
|
||||
|
||||
SimpleSprite::~SimpleSprite(void) {
|
||||
}
|
||||
|
||||
void SimpleSprite::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::SimpleSprite::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
auto* cam = scene.try_ctx<Camera3D>();
|
||||
if (!cam) {
|
||||
cam = &default_cam;
|
||||
}
|
||||
|
||||
auto vp = cam->getViewProjection();
|
||||
|
||||
auto view = scene.view<Components::Transform2D, Components::OpenGL::Texture>();
|
||||
|
||||
view.each([&](auto e, Components::Transform2D& t, Components::OpenGL::Texture& tex) {
|
||||
assert(tex.tex); // debug
|
||||
|
||||
tex.tex->bind(0);
|
||||
|
||||
_shader->setUniformMat4f("_WVP", vp * t.getTransform4(t.position.y/10.f + 500.f));
|
||||
|
||||
if (scene.has<Components::Color>(e)) {
|
||||
_shader->setUniform4f("_color", scene.get<Components::Color>(e).color);
|
||||
} else {
|
||||
_shader->setUniform4f("_color", default_color);
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
});
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void SimpleSprite::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec2 _vertexPosition;
|
||||
uniform mat4 _WVP;
|
||||
|
||||
out vec2 _tex_pos;
|
||||
|
||||
void main() {
|
||||
gl_Position = _WVP * vec4(_vertexPosition, 0, 1);
|
||||
_tex_pos = vec2(_vertexPosition.x + 0.5, _vertexPosition.y + 0.5);
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec4 _color;
|
||||
uniform sampler2D _tex0;
|
||||
|
||||
in vec2 _tex_pos;
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
vec4 tmp_col = texture(_tex0, _tex_pos) * _color;
|
||||
|
||||
if (tmp_col.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
//gl_FragColor = tmp_col;
|
||||
_out_color = tmp_col;
|
||||
//gl_FragColor = texture(_tex0, _tex_pos) * _color;
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
|
||||
//#include <glm/fwd.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class SimpleSprite : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
public:
|
||||
glm::vec4 default_color {1,1,1,1};
|
||||
|
||||
Camera3D default_cam;
|
||||
|
||||
SimpleSprite(Engine& engine);
|
||||
~SimpleSprite(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/simple_sprite_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/simple_sprite_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,178 @@
|
||||
#include "./simple_spritesheet.hpp"
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
#include "./spritesheet_renderable.hpp"
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#define TracyGpuZone(...)
|
||||
#endif
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_SSSR(x) LOG("SimpleSpriteSheetRenderTask", x)
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
SimpleSpriteSheet::SimpleSpriteSheet(Engine& engine) {
|
||||
default_cam.setOrthographic();
|
||||
default_cam.updateView();
|
||||
|
||||
float vertices[] = {
|
||||
-0.5f, 0.5f,
|
||||
-0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, 0.5f,
|
||||
-0.5f, 0.5f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
if (!scene.try_ctx<Camera3D>()) {
|
||||
LOG_SSSR("warn: scene has no Camera!");
|
||||
}
|
||||
}
|
||||
|
||||
SimpleSpriteSheet::~SimpleSpriteSheet(void) {
|
||||
}
|
||||
|
||||
void SimpleSpriteSheet::render(Services::OpenGLRenderer& rs, Engine& engine) {
|
||||
ZoneScopedN("MM::OpenGL::RenderTasks::SimpleSpriteSheet::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(FrameBufferObject::W);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
auto* cam = scene.try_ctx<Camera3D>();
|
||||
if (!cam) {
|
||||
cam = &default_cam;
|
||||
}
|
||||
|
||||
auto vp = cam->getViewProjection();
|
||||
|
||||
auto view = scene.view<Components::Transform2D, SpriteSheetRenderable>();
|
||||
|
||||
view.each([&](auto e, Components::Transform2D& t, SpriteSheetRenderable& spr) {
|
||||
assert(spr.sp.tex); // debug
|
||||
|
||||
TracyGpuZone("MM::OpenGL::Renderers::SimpleSpriteSheetRenderer::render.each");
|
||||
|
||||
spr.sp.tex->bind(0);
|
||||
|
||||
_shader->setUniformMat4f("_WVP", vp * t.getTransform4(t.position.y/10.f + 500.f));
|
||||
_shader->setUniform2ui("_tileCount", spr.sp.tile_count.x, spr.sp.tile_count.y);
|
||||
_shader->setUniform1ui("_atlasIndex", spr.tile_index);
|
||||
|
||||
if (scene.has<Components::Color>(e)) {
|
||||
_shader->setUniform4f("_color", scene.get<Components::Color>(e).color);
|
||||
} else {
|
||||
_shader->setUniform4f("_color", default_color);
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
});
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void SimpleSpriteSheet::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
in vec2 _vertexPosition;
|
||||
|
||||
uniform mat4 _WVP;
|
||||
uniform uvec2 _tileCount;
|
||||
|
||||
uniform uint _atlasIndex;
|
||||
|
||||
out vec2 _tex_pos;
|
||||
|
||||
void main() {
|
||||
// position
|
||||
gl_Position = _WVP * vec4(_vertexPosition, 0, 1);
|
||||
|
||||
|
||||
// uv
|
||||
uint row = _atlasIndex / _tileCount.x;
|
||||
uint column = _atlasIndex % _tileCount.x;
|
||||
|
||||
_tex_pos.x = (float(column) + 0.5 + _vertexPosition.x) / float(_tileCount.x);
|
||||
_tex_pos.y = 1.0 - (float(row) + 0.5 - _vertexPosition.y) / float(_tileCount.y);
|
||||
|
||||
//_tex_pos = vec2(_vertexPosition.x + 0.5, _vertexPosition.y + 0.5);
|
||||
})")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec4 _color;
|
||||
uniform sampler2D _tex0;
|
||||
|
||||
in vec2 _tex_pos;
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
vec4 tmp_col = texture(_tex0, _tex_pos) * _color;
|
||||
|
||||
if (tmp_col.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
//gl_FragColor = tmp_col;
|
||||
_out_color = tmp_col;
|
||||
//gl_FragColor = texture(_tex0, _tex_pos) * _color;
|
||||
})")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "../render_task.hpp"
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
|
||||
//#include <glm/fwd.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class SimpleSpriteSheet : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
public:
|
||||
glm::vec4 default_color {1.f, 1.f, 1.f, 1.f};
|
||||
|
||||
Camera3D default_cam;
|
||||
|
||||
SimpleSpriteSheet(Engine& engine);
|
||||
~SimpleSpriteSheet(void);
|
||||
|
||||
void render(Services::OpenGLRenderer& rs, Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/simple_spritesheet_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/simple_spritesheet_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,12 @@
|
||||
#include <mm/opengl/spritesheet.hpp>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
struct SpriteSheetRenderable {
|
||||
SpriteSheet sp;
|
||||
|
||||
uint32_t tile_index = 0;
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
193
framework/opengl_renderer/src/mm/opengl/render_tasks/tilemap.cpp
Normal file
193
framework/opengl_renderer/src/mm/opengl/render_tasks/tilemap.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
#include <mm/opengl/render_tasks/tilemap.hpp>
|
||||
|
||||
#include <mm/opengl/shader.hpp>
|
||||
#include <mm/opengl/buffer.hpp>
|
||||
#include <mm/opengl/vertex_array_object.hpp>
|
||||
|
||||
#include <mm/fs_const_archiver.hpp>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/opengl/components/texture.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
|
||||
#include "./tilemap_renderable.hpp"
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#define TracyGpuZone(...)
|
||||
#endif
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_SSR(x) LOG("TilemapRenderTask", x)
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
Tilemap::Tilemap(MM::Engine& engine) {
|
||||
float vertices[] = {
|
||||
-0.5f, 0.5f,
|
||||
-0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, -0.5f,
|
||||
0.5f, 0.5f,
|
||||
-0.5f, 0.5f,
|
||||
};
|
||||
|
||||
_vertexBuffer = std::make_unique<MM::OpenGL::Buffer>(vertices, 2 * 6 * sizeof(float), GL_STATIC_DRAW);
|
||||
_vao = std::make_unique<MM::OpenGL::VertexArrayObject>();
|
||||
_vao->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
|
||||
|
||||
glEnableVertexAttribArray(1); // Tilemap::Tile::pos
|
||||
glEnableVertexAttribArray(2); // Tilemap::Tile::atlas_index
|
||||
//glEnableVertexAttribArray(3); // Tilemap::Tile::color
|
||||
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_vao->unbind();
|
||||
|
||||
setupShaderFiles();
|
||||
_shader = MM::OpenGL::Shader::createF(engine, vertexPath, fragmentPath);
|
||||
assert(_shader != nullptr);
|
||||
}
|
||||
|
||||
Tilemap::~Tilemap(void) {
|
||||
}
|
||||
|
||||
void Tilemap::render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) {
|
||||
ZoneScopedN("MM::OpenGL::Renderers::TilemapRenderer::render");
|
||||
|
||||
rs.targets[target_fbo]->bind(MM::OpenGL::FrameBufferObject::W);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
_shader->bind();
|
||||
_vertexBuffer->bind(GL_ARRAY_BUFFER);
|
||||
_vao->bind();
|
||||
|
||||
|
||||
auto& scene = engine.tryService<Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
MM::OpenGL::Camera3D& cam = scene.ctx<MM::OpenGL::Camera3D>();
|
||||
auto vp = cam.getViewProjection();
|
||||
|
||||
auto view = scene.view<MM::Components::Transform2D, OpenGL::TilemapRenderable>();
|
||||
view.each([&](auto, MM::Components::Transform2D& t, OpenGL::TilemapRenderable& tilemap) {
|
||||
_shader->setUniformMat4f("_WVP", vp * t.getTransform4(tilemap.z + 500.f));
|
||||
|
||||
// for each sprite layer
|
||||
for (auto& sp_layer : tilemap.sprite_layer) {
|
||||
assert(sp_layer.sprite_sheet.tex); // debug
|
||||
assert(sp_layer.map_buffer);
|
||||
assert(sp_layer.map_buffer->getSize());
|
||||
|
||||
sp_layer.sprite_sheet.tex->bind(0);
|
||||
|
||||
_shader->setUniform2ui("_tileCount", sp_layer.sprite_sheet.tile_count.x, sp_layer.sprite_sheet.tile_count.y);
|
||||
|
||||
// renderj
|
||||
{
|
||||
TracyGpuZone("MM::OpenGL::Renderers::TilemapRenderer::render.each_tilemap.each_sprite_layer");
|
||||
|
||||
sp_layer.map_buffer->bind();
|
||||
OpenGL::TilemapRenderable::Tile::setupGLBindings();
|
||||
|
||||
glVertexAttribDivisor(1, 1);
|
||||
glVertexAttribDivisor(2, 1);
|
||||
//glVertexAttribDivisor(3, 1);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, sp_layer.map_buffer->getSize());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_vao->unbind();
|
||||
_vertexBuffer->unbind(GL_ARRAY_BUFFER);
|
||||
_shader->unbind();
|
||||
}
|
||||
|
||||
void Tilemap::setupShaderFiles(void) {
|
||||
FS_CONST_MOUNT_FILE(vertexPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
|
||||
uniform mat4 _WVP;
|
||||
uniform uvec2 _tileCount;
|
||||
|
||||
layout(location = 0) in vec2 _vertexPosition;
|
||||
layout(location = 1) in vec2 _tPos;
|
||||
layout(location = 2) in uint _atlasIndex;
|
||||
//layout(location = 3) in vec3 _tColor;
|
||||
|
||||
//out vec4 _color;
|
||||
out vec2 _tex_pos;
|
||||
|
||||
void main() {
|
||||
//gl_Position = vec4(_WVP * vec3(_vertexPosition, 1), 1);
|
||||
//mat3 tmp = mat3(_WVP[0], _WVP[1], vec3(_WVP[2][0] * _tPos.x, _WVP[2][1] * _tPos.y, _WVP[2][2]));
|
||||
//gl_Position = vec4(tmp * vec3(_vertexPosition, 1), 1);
|
||||
|
||||
mat4 tmp = mat4(1.0);
|
||||
tmp[3] = vec4(_tPos.x, -_tPos.y, -_tPos.y / 10.f, 1);
|
||||
gl_Position = (_WVP * tmp) * vec4(_vertexPosition, 0, 1);
|
||||
|
||||
|
||||
//_color = vec4(_tColor, 1.0);
|
||||
|
||||
uint row = _atlasIndex / _tileCount.x;
|
||||
uint column = _atlasIndex % _tileCount.x;
|
||||
|
||||
//_tex_pos = vec2(_vertexPosition.x + 0.5, _vertexPosition.y + 0.5);
|
||||
//_tex_pos.x = _vertexPosition.x + 0.5;
|
||||
_tex_pos.x = (float(column) + 0.5 + _vertexPosition.x) / float(_tileCount.x);
|
||||
|
||||
_tex_pos.y = 1.0 - (float(row) + 0.5 - _vertexPosition.y) / float(_tileCount.y);
|
||||
//_tex_pos.y = _vertexPosition.y + 0.5;
|
||||
}
|
||||
)")
|
||||
|
||||
FS_CONST_MOUNT_FILE(fragmentPath,
|
||||
GLSL_VERSION_STRING
|
||||
R"(
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D _tex0;
|
||||
|
||||
//in vec4 _color;
|
||||
in vec2 _tex_pos;
|
||||
|
||||
out vec4 _out_color;
|
||||
|
||||
void main() {
|
||||
vec4 tmp_col = texture(_tex0, _tex_pos);
|
||||
|
||||
if (tmp_col.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
//gl_FragColor = tmp_col;
|
||||
_out_color = tmp_col;
|
||||
//gl_FragColor = texture(_tex0, _tex_pos);
|
||||
//gl_FragColor = texture(_tex0, _tex_pos) * _color;
|
||||
//gl_FragColor = vec4(_tex_pos.x, _tex_pos.y, 0, 1);
|
||||
}
|
||||
)")
|
||||
}
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/opengl/render_task.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
//#include <glm/fwd.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM::OpenGL {
|
||||
class Shader;
|
||||
class Buffer;
|
||||
class VertexArrayObject;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL::RenderTasks {
|
||||
|
||||
class Tilemap : public RenderTask {
|
||||
private:
|
||||
std::shared_ptr<Shader> _shader;
|
||||
std::unique_ptr<Buffer> _vertexBuffer;
|
||||
std::unique_ptr<VertexArrayObject> _vao;
|
||||
|
||||
public:
|
||||
Tilemap(MM::Engine& engine);
|
||||
~Tilemap(void);
|
||||
|
||||
void render(MM::Services::OpenGLRenderer& rs, MM::Engine& engine) override;
|
||||
|
||||
public:
|
||||
const char* vertexPath = "shader/tilemap_render_task/vert.glsl";
|
||||
const char* fragmentPath = "shader/tilemap_render_task/frag.glsl";
|
||||
|
||||
std::string target_fbo = "display";
|
||||
|
||||
private:
|
||||
void setupShaderFiles(void);
|
||||
};
|
||||
|
||||
} // MM::OpenGL::RenderTasks
|
||||
|
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/opengl/texture.hpp>
|
||||
|
||||
#include <mm/opengl/instance_buffer.hpp>
|
||||
|
||||
#include <mm/opengl/spritesheet.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
struct TilemapRenderable {
|
||||
struct Tile {
|
||||
float pos[2];
|
||||
uint32_t sprite_sheet_index;
|
||||
//float color[3] = {1.f, 1.f, 1.f};
|
||||
|
||||
static void setupGLBindings(void) {
|
||||
static_assert(std::is_standard_layout<Tile>::value); // check if offsetof() is usable
|
||||
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Tile), (void*) offsetof(Tile, pos));
|
||||
glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(Tile), (void*) offsetof(Tile, sprite_sheet_index));
|
||||
//glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Tile), (void*) offsetof(Tile, color));
|
||||
}
|
||||
} /*__attribute__((packed))*/;
|
||||
|
||||
struct SpriteLayer {
|
||||
MM::OpenGL::SpriteSheet sprite_sheet;
|
||||
|
||||
std::vector<Tile> map; // TODO: move this to tilemap
|
||||
std::shared_ptr<MM::OpenGL::InstanceBuffer<Tile>> map_buffer = std::make_shared<MM::OpenGL::InstanceBuffer<Tile>>();
|
||||
|
||||
void syncMapBuffer(void) {
|
||||
auto* arr = map_buffer->map(map.size(), GL_STATIC_DRAW);
|
||||
std::memcpy(arr, map.data(), map.size() * sizeof(Tile));
|
||||
|
||||
map_buffer->unmap();
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<SpriteLayer> sprite_layer;
|
||||
float z = 0.f;
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,18 @@
|
||||
unsigned char default_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, 0xf4, 0x00, 0x00, 0x00,
|
||||
0x78, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0x96, 0xb1, 0x11, 0x80,
|
||||
0x30, 0x0c, 0x03, 0x65, 0x46, 0x33, 0x25, 0x6b, 0xa4, 0x0d, 0xc3, 0x24,
|
||||
0x2d, 0x3b, 0x50, 0x51, 0xe2, 0xd5, 0xc2, 0x06, 0x72, 0x87, 0x1b, 0xb9,
|
||||
0xfd, 0x3b, 0xdf, 0x9f, 0x0a, 0xd9, 0x36, 0xd0, 0x16, 0xc8, 0x74, 0x1c,
|
||||
0x0c, 0x63, 0xf7, 0x49, 0x79, 0x44, 0x50, 0xbe, 0x51, 0xfa, 0xc3, 0x48,
|
||||
0x40, 0x02, 0x12, 0xb0, 0x85, 0x9b, 0xf6, 0xc0, 0xc4, 0x43, 0x17, 0x9c,
|
||||
0xb8, 0x28, 0x77, 0x77, 0xca, 0xcb, 0x13, 0x90, 0x80, 0x04, 0x24, 0x60,
|
||||
0xee, 0x4e, 0x7b, 0x20, 0xbb, 0xe7, 0x03, 0x8d, 0xf2, 0xec, 0x9f, 0x28,
|
||||
0x4f, 0x40, 0x02, 0x12, 0x90, 0x80, 0x01, 0xa0, 0x3d, 0x90, 0xdd, 0xf3,
|
||||
0x37, 0x3a, 0xe5, 0xd9, 0x3f, 0x51, 0x9e, 0x80, 0x04, 0x24, 0x20, 0x81,
|
||||
0x0f, 0x49, 0xf4, 0x16, 0xa3, 0xb7, 0xbf, 0xe8, 0xa6, 0x00, 0x00, 0x00,
|
||||
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
|
||||
};
|
||||
unsigned int default_png_len = 177;
|
1649
framework/opengl_renderer/src/mm/opengl/res/errig_texture.h
Normal file
1649
framework/opengl_renderer/src/mm/opengl/res/errig_texture.h
Normal file
File diff suppressed because it is too large
Load Diff
175
framework/opengl_renderer/src/mm/services/opengl_renderer.cpp
Normal file
175
framework/opengl_renderer/src/mm/services/opengl_renderer.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include "./opengl_renderer.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
|
||||
#include <mm/opengl/fbo_builder.hpp>
|
||||
#include <mm/opengl/frame_buffer_object.hpp>
|
||||
#include <mm/resource_manager.hpp>
|
||||
#include <mm/opengl/texture_loader.hpp>
|
||||
#include "../opengl/res/default_texture.h" // data
|
||||
#include "../opengl/res/errig_texture.h" // data
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
#ifndef MM_OPENGL_3_GLES
|
||||
#include <tracy/TracyOpenGL.hpp>
|
||||
#else
|
||||
#define TracyGpuContext
|
||||
#define TracyGpuCollect
|
||||
#endif
|
||||
|
||||
|
||||
//#define LOGRS_SDL(x) LOGRS(std::string(SDL_GetError()) + x)
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_CRIT(...) __LOG_CRIT( "OpenGLRenderer", __VA_ARGS__)
|
||||
#define LOG_ERROR(...) __LOG_ERROR("OpenGLRenderer", __VA_ARGS__)
|
||||
#define LOG_WARN(...) __LOG_WARN( "OpenGLRenderer", __VA_ARGS__)
|
||||
#define LOG_INFO(...) __LOG_INFO( "OpenGLRenderer", __VA_ARGS__)
|
||||
#define LOG_DEBUG(...) __LOG_DEBUG("OpenGLRenderer", __VA_ARGS__)
|
||||
#define LOG_TRACE(...) __LOG_TRACE("OpenGLRenderer", __VA_ARGS__)
|
||||
|
||||
|
||||
namespace MM::Services {
|
||||
|
||||
OpenGLRenderer::OpenGLRenderer(void) {
|
||||
MM::Logger::initSectionLogger("OpenGL");
|
||||
MM::Logger::initSectionLogger("OpenGLRenderer");
|
||||
}
|
||||
|
||||
OpenGLRenderer::~OpenGLRenderer(void) {
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::enable(Engine& engine) {
|
||||
if (!engine.tryService<SDLService>()) {
|
||||
LOG_ERROR("OpenGLRenderer requires SDLService");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& sdl_s = engine.getService<SDLService>();
|
||||
|
||||
if (!sdl_s.win) {
|
||||
if (!sdl_s.createGLWindow("MushMachine (OpenGLRenderer)", 800, 600)) {
|
||||
LOG_ERROR("couldn't create window with gl context");
|
||||
return false;
|
||||
}
|
||||
} else if (!sdl_s.gl_context) {
|
||||
if (!sdl_s.createGLContext()) {
|
||||
LOG_ERROR("couldn't create gl context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// "creating" display fbo
|
||||
{
|
||||
targets["display"].reset(new OpenGL::FrameBufferObject);
|
||||
targets["display"]->_fboID = 0;
|
||||
targets["display"]->_resize = false; // its done for us
|
||||
}
|
||||
|
||||
_render_handle = engine.addUpdate([this](Engine& e){ this->render(e); });
|
||||
if (_render_handle.expired()) {
|
||||
LOG_ERROR("couldn't add update function!");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
auto tmp_lock = _render_handle.lock();
|
||||
tmp_lock->priority = -10;
|
||||
tmp_lock->name = "render";
|
||||
}
|
||||
|
||||
_sdl_event_handle = sdl_s.addEventHandler([this, &engine](const SDL_Event& e) -> bool {
|
||||
if (e.type == SDL_WINDOWEVENT) {
|
||||
if (e.window.event == SDL_WINDOWEVENT_RESIZED || e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
auto& sdl_s = engine.getService<MM::Services::SDLService>();
|
||||
auto new_window_size = sdl_s.getWindowSize();
|
||||
glViewport(0, 0, new_window_size.first, new_window_size.second);
|
||||
|
||||
// TODO: recreate fbos, dirvers seem to have problems otherwise
|
||||
//std::vector<std::pair<std::string,std::shared_ptr<MM::OpenGL::FrameBufferObject>>> new_fbos;
|
||||
|
||||
for (auto& map_entry : targets) {
|
||||
if (map_entry.second->_resize) {
|
||||
auto& fbo = map_entry.second;
|
||||
float new_width = fbo->_resize_factor_width * new_window_size.first;
|
||||
float new_height = fbo->_resize_factor_height * new_window_size.second;
|
||||
|
||||
for (auto& tex : fbo->_texAttachments) {
|
||||
if (tex->height == new_height && tex->width == new_width) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tex->resize(static_cast<int32_t>(new_width), static_cast<int32_t>(new_height));
|
||||
}
|
||||
|
||||
//auto new_fbo = std::make_shared<MM::OpenGL::FrameBufferObject>();
|
||||
//auto new_fbo = OpenGL::FBOBuilder::start().
|
||||
//new_fbos.emplace_back(map_entry.first, new_fbo);
|
||||
}
|
||||
}
|
||||
|
||||
//if (!new_fbos.empty()) {
|
||||
//}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!_sdl_event_handle) {
|
||||
LOG_ERROR("couldn't add sdl event function!");
|
||||
return false;
|
||||
}
|
||||
|
||||
{ // default texures
|
||||
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
|
||||
if (!rm_t.contains("default"_hs)) {
|
||||
if (!rm_t.load<MM::OpenGL::TextureLoaderConstBuffer>("default", default_png, default_png_len)) {
|
||||
LOG_WARN("couldn't load 'default' texture!");
|
||||
}
|
||||
}
|
||||
if (!rm_t.contains("errig"_hs)) {
|
||||
if (!rm_t.load<MM::OpenGL::TextureLoaderConstBuffer>("errig", errig_jpg, errig_jpg_len)) {
|
||||
LOG_WARN("couldn't load 'errig' texture!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::disable(Engine& engine) {
|
||||
if (!_render_handle.expired()) {
|
||||
engine.removeUpdate(_render_handle);
|
||||
_render_handle.reset();
|
||||
}
|
||||
|
||||
// TODO: do we need this??
|
||||
targets.clear();
|
||||
render_tasks.clear();
|
||||
|
||||
// TODO: reallly?
|
||||
MM::ResourceManager<MM::OpenGL::Texture>::ref().clear();
|
||||
}
|
||||
|
||||
void OpenGLRenderer::render(Engine& engine) {
|
||||
ZoneScopedN("MM::Services::OpenGLRenderer::render");
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
//targets["display"]->bind(FrameBufferObject::RW);
|
||||
//glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
//glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
targets["display"]->clear(0.1f, 0.1f, 0.1f, 1.0f, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
for (auto& r : render_tasks) {
|
||||
r->render(*this, engine);
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(engine.getService<SDLService>().win);
|
||||
TracyGpuCollect;
|
||||
}
|
||||
|
||||
} // namespace MM::Services
|
||||
|
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
|
||||
#include <mm/opengl/frame_buffer_object.hpp>
|
||||
#include <mm/opengl/render_task.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MM::Services {
|
||||
|
||||
class OpenGLRenderer : public Service {
|
||||
public:
|
||||
OpenGLRenderer(void);
|
||||
~OpenGLRenderer(void);
|
||||
|
||||
public:
|
||||
std::vector<std::unique_ptr<OpenGL::RenderTask>> render_tasks;
|
||||
std::unordered_map<std::string, std::shared_ptr<MM::OpenGL::FrameBufferObject>> targets;
|
||||
|
||||
// add rendertask helper
|
||||
// TODO: forward args
|
||||
template<typename RT_T>
|
||||
RT_T& addRenderTask(::MM::Engine& engine) {
|
||||
return *(RT_T*)render_tasks.emplace_back(std::make_unique<RT_T>(engine)).get();
|
||||
}
|
||||
|
||||
private:
|
||||
Engine::FunctionDataHandle _render_handle;
|
||||
SDLService::EventHandlerHandle _sdl_event_handle = nullptr;
|
||||
|
||||
public:
|
||||
bool enable(Engine& engine) override;
|
||||
void disable(Engine& engine) override;
|
||||
|
||||
const char* name(void) override { return "OpenGLRendererService"; }
|
||||
|
||||
private:
|
||||
void render(Engine& engine);
|
||||
};
|
||||
|
||||
} // namespace MM::Services
|
||||
|
154
framework/opengl_renderer/test/CMakeLists.txt
Normal file
154
framework/opengl_renderer/test/CMakeLists.txt
Normal file
@ -0,0 +1,154 @@
|
||||
add_executable(opengl_renderer_s_test ./opengl_renderer_s_test.cpp)
|
||||
|
||||
target_include_directories(opengl_renderer_s_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(opengl_renderer_s_test
|
||||
opengl_renderer_s
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME opengl_renderer_s_test COMMAND opengl_renderer_s_test)
|
||||
|
||||
#################
|
||||
|
||||
add_executable(imgui_render_task_test imgui_render_task_test.cpp)
|
||||
|
||||
target_include_directories(imgui_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(imgui_render_task_test
|
||||
opengl_renderer_s
|
||||
imgui_service
|
||||
imgui_render_task
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME imgui_render_task_test COMMAND imgui_render_task_test)
|
||||
|
||||
################# simple rect render task
|
||||
|
||||
add_executable(simple_rect_render_task_test simple_rect_render_task_test.cpp)
|
||||
|
||||
target_include_directories(simple_rect_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(simple_rect_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
simple_rect_render_task
|
||||
|
||||
simple_velocity_system
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME simple_rect_render_task_test COMMAND simple_rect_render_task_test)
|
||||
|
||||
################# simple sprite render task
|
||||
|
||||
add_executable(simple_sprite_render_task_test simple_sprite_render_task_test.cpp)
|
||||
|
||||
target_include_directories(simple_sprite_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(simple_sprite_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
simple_sprite_render_task
|
||||
|
||||
simple_velocity_system
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME simple_sprite_render_task_test COMMAND simple_sprite_render_task_test)
|
||||
|
||||
################# simple spritesheet render task
|
||||
|
||||
add_executable(simple_spritesheet_render_task_test simple_spritesheet_render_task_test.cpp)
|
||||
|
||||
target_include_directories(simple_spritesheet_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(simple_spritesheet_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
simple_spritesheet_render_task
|
||||
|
||||
#simple_velocity_system
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME simple_spritesheet_render_task_test COMMAND simple_spritesheet_render_task_test)
|
||||
|
||||
################# batched spritesheet render task
|
||||
|
||||
add_executable(batched_spritesheet_render_task_test batched_spritesheet_render_task_test.cpp)
|
||||
|
||||
target_include_directories(batched_spritesheet_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(batched_spritesheet_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
batched_spritesheet_render_task
|
||||
|
||||
#simple_velocity_system
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME batched_spritesheet_render_task_test COMMAND batched_spritesheet_render_task_test)
|
||||
|
||||
#################
|
||||
|
||||
add_executable(blur_render_task_test blur_render_task_test.cpp)
|
||||
|
||||
target_include_directories(blur_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(blur_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
simple_rect_render_task
|
||||
blur_render_task
|
||||
imgui_service
|
||||
imgui_render_task
|
||||
|
||||
simple_velocity_system
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME blur_render_task_test COMMAND blur_render_task_test)
|
||||
|
||||
################# tilemap render task
|
||||
|
||||
add_executable(tilemap_render_task_test tilemap_render_task_test.cpp)
|
||||
|
||||
target_include_directories(tilemap_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(tilemap_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
imgui_service
|
||||
tilemap_render_task
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME tilemap_render_task_test COMMAND tilemap_render_task_test)
|
||||
|
||||
################# fast sky render task
|
||||
|
||||
add_executable(fast_sky_render_task_test fast_sky_render_task_test.cpp)
|
||||
|
||||
target_include_directories(fast_sky_render_task_test PRIVATE ".")
|
||||
|
||||
target_link_libraries(fast_sky_render_task_test
|
||||
opengl_renderer_s
|
||||
simple_scene
|
||||
#imgui_service
|
||||
fast_sky_render_task
|
||||
fast_sky_sun_system
|
||||
|
||||
gtest_main
|
||||
)
|
||||
|
||||
add_test(NAME fast_sky_render_task_test COMMAND fast_sky_render_task_test)
|
||||
|
@ -0,0 +1,111 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/texture_loader.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/batched_spritesheet.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
#include <mm/opengl/render_tasks/spritesheet_renderable.hpp>
|
||||
|
||||
#include <physfs.h>
|
||||
#include "res/textures.zip.h"
|
||||
|
||||
const char* argv0;
|
||||
|
||||
TEST(batched_spritesheet_render_task, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("batched_spritesheet_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(argv0, "batched_spritesheet_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
ASSERT_TRUE(PHYSFS_mountMemory(textures_zip, textures_zip_len, NULL, "", NULL, 0));
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
auto& cam = scene.set<MM::OpenGL::Camera3D>();
|
||||
cam.horizontalViewPortSize = 5;
|
||||
cam.setOrthographic();
|
||||
cam.updateView();
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::BatchedSpriteSheet>(engine);
|
||||
|
||||
float accu = 0.f;
|
||||
MM::AddSystemToScene(scene, [&accu](auto& scene, float delta) {
|
||||
accu += delta;
|
||||
|
||||
if (accu >= 1.f/10) {
|
||||
accu -= 1.f/10;
|
||||
scene.template view<MM::OpenGL::SpriteSheetRenderable>()
|
||||
.each([](auto, auto& spr) {
|
||||
spr.tile_index = (spr.tile_index+spr.sp.tile_count.x) % (spr.sp.tile_count.x*spr.sp.tile_count.y);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
|
||||
ASSERT_TRUE(rm_t.load<MM::OpenGL::TextureLoaderFile>("anim_run", engine, "/textures/animation_running-1_ea_0.3.png"));
|
||||
ASSERT_TRUE(rm_t.load<MM::OpenGL::TextureLoaderFile>("anim_idle", engine, "/textures/animation_standing-1_ea_0.1.png"));
|
||||
|
||||
{
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = -1.f;
|
||||
t.scale.x = 1.5f;
|
||||
t.scale.y = 2.f;
|
||||
|
||||
auto& spr = scene.emplace<MM::OpenGL::SpriteSheetRenderable>(e);
|
||||
spr.sp.tex = rm_t.get("anim_run"_hs);
|
||||
spr.sp.tile_count.x = 8;
|
||||
spr.sp.tile_count.y = 8;
|
||||
spr.tile_index = 2;
|
||||
}
|
||||
|
||||
{
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = 1.f;
|
||||
t.scale.x = 1.5f;
|
||||
t.scale.y = 2.f;
|
||||
|
||||
auto& spr = scene.emplace<MM::OpenGL::SpriteSheetRenderable>(e);
|
||||
spr.sp.tex = rm_t.get("anim_idle"_hs);
|
||||
spr.sp.tile_count.x = 8;
|
||||
spr.sp.tile_count.y = 4;
|
||||
spr.tile_index = 0;
|
||||
}
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
argv0 = argv[0];
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
120
framework/opengl_renderer/test/blur_render_task_test.cpp
Normal file
120
framework/opengl_renderer/test/blur_render_task_test.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
#include <mm/services/imgui_s.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/simple_rect.hpp>
|
||||
#include <mm/opengl/render_tasks/blur.hpp>
|
||||
#include <mm/opengl/render_tasks/imgui.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include <mm/systems/simple_velocity_system2d.hpp>
|
||||
|
||||
#include <mm/opengl/fbo_builder.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <random>
|
||||
|
||||
const char* argv0;
|
||||
|
||||
TEST(blur_render_task, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("blur_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(argv0, "blur_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
engine.addService<MM::Services::ImGuiService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::ImGuiService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine).target_fbo = "game_view";
|
||||
|
||||
MM::OpenGL::RenderTasks::SimpleRect* bsrr_rend_ptr = &rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine);
|
||||
bsrr_rend_ptr->target_fbo = "blur_in";
|
||||
|
||||
MM::OpenGL::RenderTasks::Blur* blur_rend_ptr = &rs.addRenderTask<MM::OpenGL::RenderTasks::Blur>(engine);
|
||||
blur_rend_ptr->target_fbo = "display";
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::ImGuiRT>(engine);
|
||||
|
||||
|
||||
{
|
||||
auto [w, h] = sdl_ss.getWindowSize();
|
||||
|
||||
rs.targets["game_view"] = MM::OpenGL::FBOBuilder::start()
|
||||
.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
|
||||
.finish();
|
||||
rs.targets["blur_in"] = MM::OpenGL::FBOBuilder::start()
|
||||
.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
|
||||
.finish();
|
||||
rs.targets["blur_out"] = MM::OpenGL::FBOBuilder::start()
|
||||
.attachTexture(MM::OpenGL::Texture::createEmpty(GL_RGB, w, h, GL_RGB, GL_UNSIGNED_BYTE))
|
||||
.finish();
|
||||
}
|
||||
|
||||
|
||||
// setup v system
|
||||
MM::AddSystemToScene(scene, MM::Systems::SimpleVelocity);
|
||||
|
||||
std::mt19937 mt(42);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = i * 9.f - 40;
|
||||
t.scale = {5,5};
|
||||
|
||||
auto& v = scene.emplace<MM::Components::Velocity2D>(e);
|
||||
v.rotation = i * 0.3f;
|
||||
|
||||
if (mt() % 2) {
|
||||
auto& col = scene.emplace<MM::Components::Color>(e);
|
||||
auto rc = [&mt]() -> float {
|
||||
return (mt() % 1001) / 1000.f ;
|
||||
};
|
||||
col.color = {rc(),rc(),rc(),1};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
engine.addUpdate(
|
||||
[&](MM::Engine&) {
|
||||
ImGui::ColorEdit4("rect_col", &bsrr_rend_ptr->default_color[0]);
|
||||
}
|
||||
);
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
argv0 = argv[0];
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
59
framework/opengl_renderer/test/fast_sky_render_task_test.cpp
Normal file
59
framework/opengl_renderer/test/fast_sky_render_task_test.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "mm/opengl/camera_3d.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/fast_sky_render_task.hpp>
|
||||
#include <mm/systems/fast_sky_sun_system.hpp>
|
||||
|
||||
const char* argv0;
|
||||
|
||||
TEST(fast_sky_render_task, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("fast_sky_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(argv0, "fast_sky_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::FastSky>(engine);
|
||||
|
||||
MM::AddSystemToScene(scene, MM::Systems::FastSkySun);
|
||||
|
||||
auto& cam = scene.set<MM::OpenGL::Camera3D>();
|
||||
cam.setPerspective();
|
||||
cam.updateView();
|
||||
|
||||
scene.set<MM::OpenGL::RenderTasks::FastSkyContext>();
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
argv0 = argv[0];
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
46
framework/opengl_renderer/test/imgui_render_task_test.cpp
Normal file
46
framework/opengl_renderer/test/imgui_render_task_test.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
#include <mm/services/imgui_s.hpp>
|
||||
#include <mm/opengl/render_tasks/imgui.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
TEST(imgui_render_task, demowindow) {
|
||||
MM::Engine engine;
|
||||
|
||||
engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
// needs a open window (and opengl context) which the OpenGLRenderer creates in this case
|
||||
engine.addService<MM::Services::ImGuiService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::ImGuiService>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::ImGuiRT>(engine);
|
||||
|
||||
auto handle = engine.addUpdate([](MM::Engine&) {
|
||||
ImGui::ShowDemoWindow();
|
||||
}
|
||||
);
|
||||
|
||||
{
|
||||
auto tmp_lock = handle.lock();
|
||||
tmp_lock->priority = 0;
|
||||
tmp_lock->name = "imgui demo window";
|
||||
}
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
26
framework/opengl_renderer/test/opengl_renderer_s_test.cpp
Normal file
26
framework/opengl_renderer/test/opengl_renderer_s_test.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
TEST(opengl_renderer_s, basic) {
|
||||
MM::Engine engine;
|
||||
|
||||
engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
engine.update();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
//argv0 = argv[0];
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
framework/opengl_renderer/test/res/errig.jpg
Normal file
BIN
framework/opengl_renderer/test/res/errig.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
framework/opengl_renderer/test/res/test.png
Normal file
BIN
framework/opengl_renderer/test/res/test.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
framework/opengl_renderer/test/res/textures.zip
Normal file
BIN
framework/opengl_renderer/test/res/textures.zip
Normal file
Binary file not shown.
2627
framework/opengl_renderer/test/res/textures.zip.h
Normal file
2627
framework/opengl_renderer/test/res/textures.zip.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,83 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/simple_rect.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include <mm/systems/simple_velocity_system2d.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
const char* argv0;
|
||||
|
||||
TEST(simple_rect_render_task, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("simple_rect_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(argv0, "simple_rect_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleRect>(engine);
|
||||
|
||||
// setup v system
|
||||
MM::AddSystemToScene(scene, MM::Systems::SimpleVelocity);
|
||||
|
||||
std::mt19937 mt(42);
|
||||
|
||||
for (int y = 0; y < 10; y++) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = i * 9.f - 40;
|
||||
t.position.y = -y * 6.f + 25;
|
||||
t.scale = {5,5};
|
||||
|
||||
auto& v = scene.emplace<MM::Components::Velocity2D>(e);
|
||||
v.rotation = i * 0.3f;
|
||||
|
||||
if (mt() % 2) {
|
||||
auto& col = scene.emplace<MM::Components::Color>(e);
|
||||
auto rc = [&mt]() -> float {
|
||||
return (mt() % 1001) / 1000.f ;
|
||||
};
|
||||
col.color = {rc(),rc(),rc(),1};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
argv0 = argv[0];
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/simple_sprite.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/opengl/components/texture.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
|
||||
#include <mm/systems/simple_velocity_system2d.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
const char* argv0;
|
||||
|
||||
TEST(simple_sprite_render_task, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("simple_sprite_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(argv0, "simple_sprite_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleSprite>(engine);
|
||||
|
||||
// setup v system
|
||||
MM::AddSystemToScene(scene, MM::Systems::SimpleVelocity);
|
||||
|
||||
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
|
||||
|
||||
std::mt19937 mt(42);
|
||||
|
||||
for (int y = 0; y < 10; y++) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = i * 9.f - 40;
|
||||
t.position.y = -y * 6.f + 25;
|
||||
t.scale = {5,5};
|
||||
|
||||
auto& v = scene.emplace<MM::Components::Velocity2D>(e);
|
||||
v.rotation = i * 0.3f;
|
||||
|
||||
auto& tex = scene.emplace<MM::Components::OpenGL::Texture>(e);
|
||||
tex.tex = rm_t.get("errig"_hs);
|
||||
|
||||
if (mt() % 2) {
|
||||
auto& col = scene.emplace<MM::Components::Color>(e);
|
||||
auto rc = [&mt]() -> float {
|
||||
return (mt() % 1001) / 1000.f ;
|
||||
};
|
||||
col.color = {rc(),rc(),rc(),1};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
argv0 = argv[0];
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/texture_loader.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/simple_spritesheet.hpp>
|
||||
|
||||
#include <mm/components/transform2d.hpp>
|
||||
#include <mm/components/color.hpp>
|
||||
#include <mm/opengl/render_tasks/spritesheet_renderable.hpp>
|
||||
|
||||
#include <physfs.h>
|
||||
#include "res/textures.zip.h"
|
||||
|
||||
TEST(simple_spritesheet_render_task, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("simple_spritesheet_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(nullptr, "simple_spritesheet_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
ASSERT_TRUE(PHYSFS_mountMemory(textures_zip, textures_zip_len, NULL, "", NULL, 0));
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
auto& cam = scene.set<MM::OpenGL::Camera3D>();
|
||||
cam.horizontalViewPortSize = 5;
|
||||
cam.setOrthographic();
|
||||
cam.updateView();
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::SimpleSpriteSheet>(engine);
|
||||
|
||||
float accu = 0.f;
|
||||
MM::AddSystemToScene(scene, [&accu](auto& scene, float delta) {
|
||||
accu += delta;
|
||||
|
||||
if (accu >= 1.f/10) {
|
||||
accu -= 1.f/10;
|
||||
scene.template view<MM::OpenGL::SpriteSheetRenderable>()
|
||||
.each([](auto, auto& spr) {
|
||||
spr.tile_index = (spr.tile_index+spr.sp.tile_count.x) % (spr.sp.tile_count.x*spr.sp.tile_count.y);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
|
||||
ASSERT_TRUE(rm_t.load<MM::OpenGL::TextureLoaderFile>("anim_run", engine, "/textures/animation_running-1_ea_0.3.png"));
|
||||
ASSERT_TRUE(rm_t.load<MM::OpenGL::TextureLoaderFile>("anim_idle", engine, "/textures/animation_standing-1_ea_0.1.png"));
|
||||
|
||||
{
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = -1.f;
|
||||
t.scale.x = 1.5f;
|
||||
t.scale.y = 2.f;
|
||||
|
||||
auto& spr = scene.emplace<MM::OpenGL::SpriteSheetRenderable>(e);
|
||||
spr.sp.tex = rm_t.get("anim_run"_hs);
|
||||
spr.sp.tile_count.x = 8;
|
||||
spr.sp.tile_count.y = 8;
|
||||
spr.tile_index = 2;
|
||||
}
|
||||
|
||||
{
|
||||
auto e = scene.create();
|
||||
auto& t = scene.emplace<MM::Components::Transform2D>(e);
|
||||
t.position.x = 1.f;
|
||||
t.scale.x = 1.5f;
|
||||
t.scale.y = 2.f;
|
||||
|
||||
auto& spr = scene.emplace<MM::OpenGL::SpriteSheetRenderable>(e);
|
||||
spr.sp.tex = rm_t.get("anim_idle"_hs);
|
||||
spr.sp.tile_count.x = 8;
|
||||
spr.sp.tile_count.y = 4;
|
||||
spr.tile_index = 0;
|
||||
}
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
97
framework/opengl_renderer/test/tilemap_render_task_test.cpp
Normal file
97
framework/opengl_renderer/test/tilemap_render_task_test.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/services/sdl_service.hpp>
|
||||
#include <mm/services/simple_scene.hpp>
|
||||
#include <mm/services/opengl_renderer.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
#include <mm/opengl/camera_3d.hpp>
|
||||
#include <mm/opengl/render_tasks/tilemap.hpp>
|
||||
|
||||
#include <mm/opengl/render_tasks/tilemap_renderable.hpp>
|
||||
#include <mm/components/transform2d.hpp>
|
||||
|
||||
#include <mm/opengl/texture_loader.hpp>
|
||||
|
||||
TEST(tilemap_render_task_test, it) {
|
||||
MM::Engine engine;
|
||||
|
||||
auto& sdl_ss = engine.addService<MM::Services::SDLService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SDLService>());
|
||||
|
||||
sdl_ss.createGLWindow("tilemap_render_task_test", 1280, 720);
|
||||
|
||||
engine.addService<MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::SimpleSceneService>());
|
||||
|
||||
bool provide_ret = engine.provide<MM::Services::SceneServiceInterface, MM::Services::SimpleSceneService>();
|
||||
ASSERT_TRUE(provide_ret);
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
auto& cam = scene.set<MM::OpenGL::Camera3D>();
|
||||
cam.translation = {2.f, -2.f, 0.f};
|
||||
cam.horizontalViewPortSize = 20.f;
|
||||
cam.setOrthographic();
|
||||
cam.updateView();
|
||||
|
||||
engine.addService<MM::Services::FilesystemService>(nullptr, "tilemap_render_task_test");
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::FilesystemService>());
|
||||
|
||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||
|
||||
rs.addRenderTask<MM::OpenGL::RenderTasks::Tilemap>(engine);
|
||||
|
||||
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
|
||||
|
||||
{
|
||||
auto e = scene.create();
|
||||
scene.emplace<MM::Components::Transform2D>(e);
|
||||
|
||||
auto& tm = scene.emplace<MM::OpenGL::TilemapRenderable>(e);
|
||||
|
||||
auto& slayer = tm.sprite_layer.emplace_back();
|
||||
|
||||
// fill sprite sheet
|
||||
{
|
||||
slayer.sprite_sheet.tile_count.x = 1;
|
||||
slayer.sprite_sheet.tile_count.y = 1;
|
||||
//slayer.sprite_sheet.tex = rm_t.get("default"_hs);
|
||||
slayer.sprite_sheet.tex = rm_t.get("errig"_hs);
|
||||
}
|
||||
|
||||
// fill tiles
|
||||
{
|
||||
std::vector<uint32_t> temp_map {
|
||||
1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 1, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1,
|
||||
};
|
||||
|
||||
uint32_t width = 5;
|
||||
uint32_t height = 5;
|
||||
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
for (uint32_t x = 0; x < width; x++) {
|
||||
if (temp_map[y*width + x] != 0) {
|
||||
auto& tile = slayer.map.emplace_back();
|
||||
tile.pos[0] = x;
|
||||
tile.pos[1] = y;
|
||||
tile.sprite_sheet_index = temp_map[y*width + x] - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slayer.syncMapBuffer(); // send to opengl
|
||||
}
|
||||
}
|
||||
|
||||
engine.run();
|
||||
}
|
||||
|
Reference in New Issue
Block a user