// engine includes#include"app/Application.hpp"#include"graphics/shaders/GLSLProgram.hpp"#include"graphics/Mesh.hpp"// std includes#include<iostream>#include<array>// using namespaces for testing purposes-onlyusingnamespace VAPE;usingnamespace graphics;usingnamespace camera;// TimeStep global init. (provides time and deltaTime)TimeStep time;// the size of the meshes for the sceneconstexprsize_t meshCount =3;// global resource objects// to be added in the appplication class (this is just for example)GLSLProgram basic;std::array<std::shared_ptr<Mesh>, meshCount> meshes;
Let's #2. Setting up the main() function
setLoad(), setUpdate() and setRender() accept a lambda / std::function as an argument inside their bodies.
demo_scene.cpp
intmain(){ // instantiate a new application (window, input handlers, etc.) Application app;app.setLoad([&]() { load(); });app.setUpdate([&](double deltaTime) { update(time.deltaTime); }); // the Renderer obj. is part of the Application obj.app.setRender([&]() { render(app.renderer); }); // Run the application with the already set functions (above)app.Run();return EXIT_SUCCESS;}
Let's #3. Define the load() function body
Its purpose is for initialization of shaders, meshes and resources in general.
demo_scene.cpp
voidload(){ // Compile shadersbasic.CompileShaderFile("Resources/Shaders/core.vert", GLSLShader::GLSLShaderType::VERTEX);basic.CompileShaderFile("Resources/Shaders/core.frag", GLSLShader::GLSLShaderType::FRAGMENT); // Build shader program. (link shaders). TODO: Add Exceptions to throw on errors.basic.Build();float span =0.0f; // Create meshes (cubes) std::for_each(meshes.begin(),meshes.end(), [&](std::shared_ptr<Mesh> &mesh) { // Instantiate the mesh mesh = std::make_shared<Mesh>(); // Transform the meshmesh->translate(glm::vec3(-1.5f+ span,0.0f,-10.0f));mesh->rotate(glm::vec3(1.0f,1.0f, glm::quarter_pi<float>()));mesh->getScale() = glm::vec3(0.55f); // TODO: Set Material, Set Shader !!! // ... That can be done here as well, when materials get implemented. span +=1.5f; }); // Init camera Application::cam.Init();}
Let's #4. Define the update() function body
Its purpose is for updating the meshes' transform matrix in world and local coordinates.
demo_scene.cpp
voidupdate(double deltaTime){ // e.g. rotate the cubes in 3D space std::for_each(meshes.begin(),meshes.end(), [&](std::shared_ptr<Mesh> &mesh) {mesh->rotate(glm::vec3(1.0f,1.0f, glm::quarter_pi<float>())); });}
Let's #5. Define the render() function body
Its purpose is for managing the current shader and the renderer queue.
demo_scene.cpp
voidrender(ForwardRenderer& renderer){ // Bind current shaderbasic.Enable(); // Create renderer queue (allocated 1000 rend. commands)renderer.Begin(); // Traverse the meshes std::for_each(meshes.begin(),meshes.end(), [&](const std::shared_ptr<Mesh> &mesh) {if (!mesh) return; // Get mesh transform glm::mat4 M =mesh->GetTransformMatrix(); // Bind MVP matrix basic.setUniform("projection", Application::cam.GetProj());basic.setUniform("model_view", Application::cam.GetView() * M); // Bind materialbasic.setUniform("mat.emissive", glm::vec4(1.0f,.5f,0.2f,1.0f)); // Submit meshes in the rendererrenderer.SubmitMesh(mesh); // Display everything submitted in the rendererrenderer.Present(); }); // Optimize renderer queue (batching, sorting...)renderer.End(); }