Commit 6b93d716 authored by Johannes Braun's avatar Johannes Braun
Browse files

Added basic methods for instanced rendering and first working sample.

parent b3c5ceea
#version 430
//in vec4 out_position;
//layout(location = 0) out vec4 out_final_color;
void main()
{
//I am very empty.
//Only need depth, no color.
//out_final_color = vec4(1, 0, 0, 1);
}
\ No newline at end of file
#version 430
#extension GL_ARB_bindless_texture : require
#extension GL_ARB_shading_language_include : require
#include <util/scene/material.glsl>
#include <util/globals.glsl>
in vec2 out_texcoord;
uniform Material u_material;
layout(location = 0) out vec4 output_base_ior;
void main()
{
output_base_ior.rgb = u_material.getBase(out_texcoord);
output_base_ior.a = 1;
}
#version 430
#extension GL_ARB_shading_language_include : require
#include <util/globals.glsl>
layout(location=0) in vec4 in_position;
layout(location=1) in vec4 in_normal;
layout(location=2) in vec2 in_texcoord;
layout(location=3) in vec4 in_tangent;
layout(location=4) in vec4 in_bitangent;
layout(location=5) in mat4 in_modelmatrix;
out vec2 out_texcoord;
void main()
{
out_texcoord = in_texcoord;
gl_Position = globals.camera.view_projection_matrix * in_modelmatrix * in_position;
}
int main()
#include <core/state.h>
#include <core/res/res.h>
#include <core/objects/skybox.h>
#include <components/PlayerController.h>
#include <core/rendering/mesh_drawable.h>
#include <core/rendering/batch_renderer.h>
#include <core/rendering/batch_render_list.h>
#include <core/objects/camera.h>
#include "util/files.h"
using namespace glare;
int main(int argc, char* argv[])
{
auto context_id = core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
// Create a skybox
core::Context::current().skybox()->reset(core::Skybox::collectFilesFrom(files::asset("textures/ryfjallet/")));
// Add a PlayerController to move around
core::Context::current().camera()->owner()->makeComponent<component::PlayerController>();
// Render the scene with the pathtracer
core::Context::current().loop([]() { core::Context::current().draw(core::Context::DrawMode::eGBuffer); });
}
\ No newline at end of file
......@@ -16,14 +16,45 @@ int main(int argc, char* argv[])
auto context_id = core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
//core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
// Create a skybox
core::Context::current().skybox()->reset(core::Skybox::collectFilesFrom(files::asset("textures/ryfjallet/")));
// Add a PlayerController to move around
core::Context::current().camera()->owner()->makeComponent<component::PlayerController>();
static auto default_shader_program = std::make_shared<core::Program>(std::vector<std::shared_ptr<core::Shader>>{
std::make_shared<core::Shader>(gl::ShaderType::eVertex, files::shader("simple_instanced/simple.vert")),
std::make_shared<core::Shader>(gl::ShaderType::eFragment, files::shader("simple_instanced/simple.frag"))
});
std::shared_ptr<core::MeshDrawable> drawable = std::make_shared<core::MeshDrawable>();
core::Buffer mat_bfr;
std::vector<glm::mat4> matrices;
for (auto y = 0; y < 100; ++y)
{
for (auto x = 0; x < 200; ++x)
{
matrices.push_back(glm::translate(glm::mat4(1.f), glm::vec3(3.f*x, 0, 3.f*y)));
}
}
mat_bfr.upload(matrices, gl::BufferUsage::eDynamicCopy);
drawable->mesh = std::make_shared<core::Mesh>();
drawable->mesh->vertexArray().linkAttributeMatrix4(mat_bfr.id(), 5, sizeof(glm::mat4), 0, 1);
// Render the scene with the pathtracer
core::Context::current().loop([]() { core::Context::current().draw(core::Context::DrawMode::eGBuffer); });
core::Context::current().loop([&drawable, &mat_bfr]() {
core::Context::current().renderList().submit(default_shader_program, std::make_shared<core::BatchDrawable>([&drawable, &mat_bfr](std::shared_ptr<core::Program> shader) {
if (drawable->material)
shader->uniformStruct("u_material", *(drawable->material));
drawable->mesh->drawInstanced(mat_bfr.size() / sizeof(glm::mat4));
}), glm::mat4(1.f));
core::Context::current().draw(core::Context::DrawMode::eColors);
});
}
\ No newline at end of file
......@@ -33,8 +33,22 @@ namespace glare::core
linkAttribute(buffer, 0, attribute, components, type, normalize, stride, first_index);
}
void VertexArray::linkAttributeMatrix4(unsigned buffer, unsigned attribute, size_t stride, size_t first_index, unsigned instance_divisor) const
{
for (auto i = 0; i < 4; ++i)
{
linkAttribute(buffer, attribute + i, 4, gl::Type::eFloat, false, stride, first_index + sizeof(float) * i * 4);
instanceDivisor(5 + i, instance_divisor);
}
}
void VertexArray::linkIndices(unsigned buffer) const
{
gl::vertexArrayElementBuffer(m_handle, buffer);
}
void VertexArray::instanceDivisor(unsigned attribute, unsigned switch_on_instance) const
{
gl::vertexArrayBindingDivisor(m_handle, attribute, switch_on_instance);
}
}
......@@ -21,7 +21,9 @@ namespace glare::core
void linkAttribute(unsigned buffer, size_t buffer_offset, unsigned attribute, size_t components, gl::Type type, bool normalized, size_t stride, size_t first_index) const;
void linkAttribute(unsigned buffer, unsigned attribute, size_t components, gl::Type type, bool normalize, size_t stride, size_t first_index) const;
void linkAttributeMatrix4(unsigned buffer, unsigned attribute, size_t stride, size_t first_index, unsigned instance_divisor = 0) const;
void linkIndices(unsigned buffer) const;
void instanceDivisor(unsigned attribute, unsigned switch_on_instance) const;
private:
gl::handle::vertex_array m_handle;
......
......@@ -173,6 +173,18 @@ namespace glare::core
}
}
const VertexArray& Mesh::vertexArray() const
{
return m_vertex_array;
}
void Mesh::drawInstanced(unsigned count)
{
m_vertex_array.bind();
gl::drawElementsInstanced(gl::PrimitiveType::eTriangles, m_indices.size(), gl::Type::eUInt, nullptr, count);
m_vertex_array.unbind();
}
void Mesh::draw()
{
m_vertex_array.bind();
......
......@@ -30,12 +30,15 @@ namespace glare::core
virtual ~Mesh() = default;
virtual void draw();
virtual void drawInstanced(unsigned count);
void initialize();
const std::vector<math::Vertex>& getVertices() const;
const std::vector<unsigned>& getIndices() const;
const VertexArray& vertexArray() const;
int64_t id() const;
protected:
......
......@@ -12,6 +12,13 @@ namespace glare::core
if (m_shader_mapping.count(shader->id()) == 0)
{
m_shader_mapping.emplace(shader->id(), std::make_pair(shader, m_render_list.size()));
//Maybe: check if Batchdrawable being a mesh drawable exists having the same mesh?
// If so: convert to InstancedBatchDrawable.
// Also: check if InstancedBatchDrawable exists.
//Or: have multiple render lists, e.g. one for BatchDrawables and one for special "InstancedBatchDrawables"
m_render_list.push_back(std::vector<std::pair<std::shared_ptr<BatchDrawable>, glm::mat4>>(1, std::make_pair(renderable, model_matrix)));
}
else
......
......@@ -11,7 +11,7 @@
namespace glare::core
{
// mesh and material
class MeshDrawable : public BatchDrawable {
class MeshDrawableInstanced : public BatchDrawable {
public:
void onDraw(std::shared_ptr<Program> shader) override
......@@ -28,6 +28,8 @@ namespace glare::core
std::shared_ptr<Material> material;
protected:
Buffer m_per_instance_data;
void onDebugGui() override
{
material->gui();
......
......@@ -44,7 +44,7 @@ namespace glare::raytrace
}
m_bvh->apply(m_vertices, m_triangles);
if (!m_triangle_buffer)
m_triangle_buffer = std::make_shared<core::Buffer>();
if (!m_vertex_buffer)
......
......@@ -203,6 +203,11 @@ namespace gl
glDrawElements(static_cast<GLenum>(primitive), static_cast<int>(count), static_cast<GLenum>(indices_type), elements);
}
void drawElementsInstanced(PrimitiveType primitive, size_t count, Type indices_type, const void* elements, unsigned instances)
{
glDrawElementsInstanced(static_cast<GLenum>(primitive), static_cast<int>(count), static_cast<GLenum>(indices_type), elements, instances);
}
void bindVertexArray(unsigned vertex_array)
{
glBindVertexArray(vertex_array);
......@@ -243,6 +248,11 @@ namespace gl
glVertexArrayElementBuffer(vertex_array, buffer);
}
void vertexArrayBindingDivisor(unsigned vertex_array, unsigned attribute, unsigned divisor)
{
glVertexArrayBindingDivisor(vertex_array, attribute, divisor);
}
void genBuffers(unsigned count, unsigned* target)
{
glGenBuffers(count, target);
......
......@@ -875,6 +875,7 @@ namespace gl
void drawArrays(PrimitiveType primitive, int first, size_t count);
void drawElements(PrimitiveType primitive, size_t count, Type indices_type, const void* elements);
void drawElementsInstanced(PrimitiveType primitive, size_t count, Type indices_type, const void* elements, unsigned instances);
void bindVertexArray(unsigned vertex_array);
void enableVertexAttribArray(unsigned index);
void vertexAttribPointer(unsigned attribute, int num_components, Type type, bool normalize, int stride, size_t start_index);
......@@ -883,6 +884,7 @@ namespace gl
void vertexArrayAttribFormat(unsigned vertex_array, unsigned attribute, size_t components, Type type, bool normalized, size_t start_index);
void vertexArrayAttribBinding(unsigned vertex_array, unsigned attribute, unsigned binding);
void vertexArrayElementBuffer(unsigned vertex_array, unsigned buffer);
void vertexArrayBindingDivisor(unsigned vertex_array, unsigned attribute, unsigned divisor);
void genBuffers(unsigned count, unsigned* target);
void deleteBuffers(unsigned count, unsigned* target);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment