Sample Scene

Simple application - 3D scene example

Let's #1. Setup includes and global resources

demo_scene.cpp
// 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-only
using namespace VAPE;
using namespace graphics;
using namespace camera;

// TimeStep global init. (provides time and deltaTime)
TimeStep time;
// the size of the meshes for the scene
constexpr size_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
int main()
{
	// 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
void load()
{
	// Compile shaders
	basic.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 mesh
		mesh->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
void update(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
void render(ForwardRenderer& renderer)
{
	// Bind current shader
	basic.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 material
		basic.setUniform("mat.emissive", glm::vec4(1.0f, .5f, 0.2f, 1.0f));

		// Submit meshes in the renderer
		renderer.SubmitMesh(mesh);

		// Display everything submitted in the renderer
		renderer.Present();
	});
	
	// Optimize renderer queue (batching, sorting...)
	renderer.End();	
}

Last updated