This is a class project, but I extended it with more flexible command (shader playground , Blit , loading model via ffile explorer etc...)
- You can use it as a starter framework of your project.
- I will keep adding items till this semester end.
- Hieraarchy is a singleton class.
- Component added to Hieraarchy will call their
Do()
function in main logic each frame.
Hierarchy Hierarchy::sInstance;
- Any attachable element is a sub class of Component .
- Please ovride functions below.
virtual void Do(){};
virtual void DO_Before_Frame() {};
virtual void Do_End_Frame() {};
Cast Component
GameObject* gm = this->m_gameobject->cast_component<GameObject>(); // Get this gameobj's transform
Mesh* mesh = this->m_gameobject->cast_component<Mesh>(); // Get this gameobj's Mesh component
- class GameObject : public Component , public UiPanel
- GameObject are created with TransformObject.
Create gameobject
GameObject obj = GameObject("Slime");
obj.set_name("Slime"); // or set its name via function
Hierarchy::instance().add_object(&obj);
Attach Component
// Add Mesh object.
Mesh* mesh_b1 = new Mesh(src_path + "\\assets\\models\\bush\\grassB.obj");
obj.add_component(dog_mesh);
- Gameobject can use m_transform to set the transform. (Model matrix will be updated in main logic)
obj.m_transform->m_rotation = vec3(-30, 0, 0);
obj.m_transform->m_position = vec3(0, 0, 50);
obj.m_transform->m_scale = vec3(1, 1,1);
class Mesh : public UiableComponent
Load Model
Mesh* dog_mesh =new Mesh(src_path + "\\assets\\models\\cute_dog\\cute_dg.obj" , s_default_shader); //give render shader
Mesh* mesh_b1 = new Mesh(src_path + "\\assets\\models\\bush\\grassB.obj"); //or only get the mesh data.
obj.add_component(dog_mesh); // Attach to gameobject , it will be rendered in main logic.
Create
Texture(); //empty
Texture(unsigned _width , unsigned int _height); //create blank buffer
Texture(const string _file_path); // load image
See BasicFlags.h
- Material will set this as uniform variables.
- When loading a model, Mesh class will set them if they exist is obj file.
const enum class Bind_Type
{
DIFFUSE,
NORMAL,
};
- To access them, simply use these keyword.
uniform sampler2D DIFFUSE;
uniform sampler2D NORMAL;
Usage: See Material.cpp
Create Shader
Shader s_default_shader(
src_path + string("\\assets\\shaders\\default_vert.glsl"),
src_path + string("\\assets\\shaders\\default_frag.glsl"));
Create Compute Shader
If you only pass in the vert shader, I will be compiled as compute shader.
this->cs_reset_shader = Shader(GET_SRC_FOLDER() + string("\\assets\\shaders\\hw3_reset_cs.glsl"));
class IndirectInstancedMesh: public UiableComponent
vector<Mesh> ind_mesh_list = {*mesh_b1 , *mesh_b2 , *mesh_b3 }; //Loaded 3 mesh
IndirectInstancedMesh id_mesh(ind_mesh_list); // pass in to create IndirectInstancedMesh
Render
ToDo: merge it into Hierarchy pipeline.
// reset
id_mesh.cs_reset_shader.activate();
id_mesh.dispatch_reset();
// culling
id_mesh.cs_view_culling_shader.activate();
id_mesh.dispatch_culling();
// Render
id_mesh.indirect_render_shader.activate();
id_mesh.Do();
Create fbo:
static const GLenum draw_buffers[]={
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2
};
FramebufferObject* fbo = frame_buffer_debugger.gen_frame_object_and_registor(&frameBuffer_shader , &draw_buffers[0], 1, HALF_SCR_WIDTH , SCR_HEIGHT);
// It is the same as below but frame_buffer_debugger will log it on an UI.
// FramebufferObject* game_fbo = FramebufferObject(&frameBuffer_shader , &draw_buffers[0], 1, HALF_SCR_WIDTH , SCR_HEIGHT);
Blit
Blit with bloom screen shader.
// Bloom
FramebufferObject* bloom_fbo = frame_buffer_debugger.gen_frame_object_and_registor(&frame_bloom_shader, &draw_buffers[0], 1, SCR_WIDTH, SCR_HEIGHT);
fbo->blit(fbo->framebuffer_texture[0], *bloom_fbo);
bloom_fbo->blit(bloom_fbo->framebuffer_texture[0], *compare_fbo); // blit to othere fbo
//.... Render fbo
compare_fbo->shader->activate();
// set up your uniform....
compare_fbo->blit(compare_fbo->framebuffer_texture[0], 0); // blit main screen texture
compare_fbo->blit(compare_fbo->framebuffer_texture[0], 0, fbo->framebuffer_texture[0]);
Read in frag shader.
//in frag
layout (binding = 0) uniform sampler2D screenTexture;
layout (binding = 1) uniform sampler2D texture2; // additional texture
layout (binding = 2) uniform sampler2D texture3;
//.....texture4,texture5...
class Camera : public Component
Create Camera object
Camera* game_camera = new Camera(glm::vec3(0.0f, 0.0f, 0.001f) , (float)SCR_WIDTH / (float)SCR_HEIGHT ,1,150);
GameObject game_camera_obj = GameObject();
game_camera_obj.add_component((Component*)game_camera); // Attach it to game object
Move Camera along its forward direction.
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
game_camera_obj.m_transform->m_position -= vec3( vec4(game_camera_obj.m_transform->m_forward * vec3(dt), 1.0));
}
Create your own ui on screen.
Example : create nav bar with button action.
auto my_button_with_action = [&]() { if (Button("Button text")) {
cout<<"hi";
return true;
} };
ui_manager.m_menu_cmds.push_back(my_button_with_action);
Render UI at the end of the rendering stage.
ui_manager.create_hierarchy_window(Hierarchy::instance().m_game_objects); //update hierarchy
ui_manager.create_menubar();
ui_manager.render_ui();
glfwSwapBuffers(window);
glfwPollEvents();
Hierarchy::instance().execute(EXECUTE_TIMING::AFTER_FRAME);
Bind your ui to heriarchy.
class TransformObject :public UiableComponent
class UiableComponent : virtual public UiPanel, virtual public Component
Example : Binding Transform value. (TransformObject inherit from UiableComponent.)
TransformObject::TransformObject()
{
this->m_position = vec3(0.0f);
this->m_scale = vec3(1.0f);
this->m_rotation = vec3(0.0f);
auto pos_inp= [&]() { return InputFloat3("Position", &this->m_position.x); };
auto rot_inp = [&]() { return InputFloat3("Rotation", &this->m_rotation.x); };
auto scale_inp = [&]() { return InputFloat3("Scale", &this->m_scale.x); };
this->add_draw_item(pos_inp);
this->add_draw_item(rot_inp);
this->add_draw_item(scale_inp);
}
//In render loop:
frame_buffer_debugger.Init_Panel(0, 150);
frame_buffer_debugger.Begin_Panel();
// Render.....
frame_buffer_debugger.End_Panel();
frame_buffer_debugger.create_hw2_panel(hw2_effect_panel);
Demo :(https://www.youtube.com/watch?v=WuO4l4AzwXs&feature=youtu.be&ab_channel=CuneiSolar%E6%A5%94%E9%99%BD)
// Init
ShaderEditor shaderEditor;
// In render Loop
shaderEditor.begin_panel();