diff --git a/src/Makefile.am b/src/Makefile.am index 8cb87c5c..c03c90df 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -100,6 +100,7 @@ liblolcore_sources = \ generated/lolfx-scanner.cpp \ \ mesh/mesh.cpp mesh/mesh.h \ + mesh/primitive.cpp mesh/primitive.h \ \ sys/init.cpp sys/timer.cpp sys/file.cpp \ sys/threadbase.h \ diff --git a/src/core.h b/src/core.h index 91e7bc44..a28556d7 100644 --- a/src/core.h +++ b/src/core.h @@ -183,6 +183,7 @@ static inline int isnan(float f) #include "map.h" #include "layer.h" #include "mesh/mesh.h" +#include "mesh/primitive.h" #include "application/application.h" #include "easymesh/csgbsp.h" #include "easymesh/easymesh.h" diff --git a/src/gpu/line.lolfx b/src/gpu/line.lolfx index a0fe1703..468b0922 100644 --- a/src/gpu/line.lolfx +++ b/src/gpu/line.lolfx @@ -6,12 +6,12 @@ attribute vec3 in_Position; attribute vec4 in_Color; varying vec4 pass_Color; -uniform mat4 proj_matrix; -uniform mat4 view_matrix; +uniform mat4 u_projection; +uniform mat4 u_view; void main() { - gl_Position = proj_matrix * view_matrix + gl_Position = u_projection * u_view * vec4(in_Position, 1.0); pass_Color = in_Color; } @@ -35,12 +35,12 @@ void main() void main(float4 in_Position : POSITION, float4 in_Color : COLOR, - uniform float4x4 proj_matrix, - uniform float4x4 view_matrix, + uniform float4x4 u_projection, + uniform float4x4 u_view, out float4 out_Color : COLOR, out float4 out_Position : POSITION) { - out_Position = mul(proj_matrix, mul(view_matrix, in_Position)); + out_Position = mul(u_projection, mul(u_view, in_Position)); out_Color = in_Color; } diff --git a/src/gpu/tile.lolfx b/src/gpu/tile.lolfx index 8e373b83..bdae6389 100644 --- a/src/gpu/tile.lolfx +++ b/src/gpu/tile.lolfx @@ -6,13 +6,13 @@ attribute vec3 in_Position; attribute vec2 in_TexCoord; varying vec2 pass_TexCoord; -uniform mat4 proj_matrix; -uniform mat4 view_matrix; -uniform mat4 model_matrix; +uniform mat4 u_projection; +uniform mat4 u_view; +uniform mat4 u_model; void main() { - gl_Position = proj_matrix * view_matrix * model_matrix + gl_Position = u_projection * u_view * u_model * vec4(in_Position, 1.0); pass_TexCoord = in_TexCoord; } @@ -39,9 +39,9 @@ void main() void main(float4 in_Position : POSITION, float2 in_TexCoord : TEXCOORD0, - uniform float4x4 proj_matrix, - uniform float4x4 view_matrix, - uniform float4x4 model_matrix, + uniform float4x4 u_projection, + uniform float4x4 u_view, + uniform float4x4 u_model, uniform float2 in_TexSize, out float2 out_TexCoord : TEXCOORD0, out float4 out_Position : POSITION) @@ -51,7 +51,7 @@ void main(float4 in_Position : POSITION, #else float2 delta = float2(0.0, 0.0); #endif - out_Position = mul(proj_matrix, mul(view_matrix, mul(model_matrix, in_Position))); + out_Position = mul(u_projection, mul(u_view, mul(u_model, in_Position))); out_TexCoord = in_TexCoord + delta; } diff --git a/src/gradient.cpp b/src/gradient.cpp index 1aba8d8d..7d6b5504 100644 --- a/src/gradient.cpp +++ b/src/gradient.cpp @@ -93,11 +93,11 @@ void Gradient::TickDraw(float seconds) data->shader->Bind(); - uni_mat = data->shader->GetUniformLocation("proj_matrix"); + uni_mat = data->shader->GetUniformLocation("u_projection"); data->shader->SetUniform(uni_mat, g_scene->GetCamera()->GetProjection()); - uni_mat = data->shader->GetUniformLocation("view_matrix"); + uni_mat = data->shader->GetUniformLocation("u_view"); data->shader->SetUniform(uni_mat, g_scene->GetCamera()->GetView()); - uni_mat = data->shader->GetUniformLocation("model_matrix"); + uni_mat = data->shader->GetUniformLocation("u_model"); data->shader->SetUniform(uni_mat, model_matrix); data->shader->Bind(); diff --git a/src/gradient.lolfx b/src/gradient.lolfx index ca36870d..527ba9f0 100644 --- a/src/gradient.lolfx +++ b/src/gradient.lolfx @@ -6,13 +6,13 @@ attribute vec3 in_Position; attribute vec4 in_Color; varying vec4 pass_Color; -uniform mat4 proj_matrix; -uniform mat4 view_matrix; -uniform mat4 model_matrix; +uniform mat4 u_projection; +uniform mat4 u_view; +uniform mat4 u_model; void main() { - gl_Position = proj_matrix * view_matrix * model_matrix + gl_Position = u_projection * u_view * u_model * vec4(in_Position, 1.0); pass_Color = in_Color; } @@ -81,13 +81,13 @@ void main() void main(float4 in_Vertex : POSITION, float4 in_Color : COLOR, - uniform float4x4 proj_matrix, - uniform float4x4 view_matrix, - uniform float4x4 model_matrix, + uniform float4x4 u_projection, + uniform float4x4 u_view, + uniform float4x4 u_model, out float4 out_Color : COLOR, out float4 out_Position : POSITION) { - out_Position = mul(proj_matrix, mul(view_matrix, mul(model_matrix, in_Vertex))); + out_Position = mul(u_projection, mul(u_view, mul(u_model, in_Vertex))); out_Color = in_Color; } diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj index 520053d7..08ac98f9 100644 --- a/src/lolcore.vcxproj +++ b/src/lolcore.vcxproj @@ -158,6 +158,7 @@ + @@ -307,6 +308,7 @@ + diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters index 78712f7c..893166dc 100644 --- a/src/lolcore.vcxproj.filters +++ b/src/lolcore.vcxproj.filters @@ -117,6 +117,9 @@ mesh + + mesh + gpu @@ -378,6 +381,9 @@ mesh + + mesh + application @@ -715,4 +721,4 @@ - \ No newline at end of file + diff --git a/src/mesh/mesh.cpp b/src/mesh/mesh.cpp index 7d4fe264..da8abbbb 100644 --- a/src/mesh/mesh.cpp +++ b/src/mesh/mesh.cpp @@ -46,9 +46,6 @@ SubMesh::SubMesh(lol::VertexDeclaration* vdecl) : m_mesh_prim(MeshPrimitive::Triangles) { m_vdecl = vdecl; - m_vbos = new VertexBuffer*[vdecl->GetStreamCount()]; - memset(m_vbos, 0, sizeof(VertexBuffer*) * vdecl->GetStreamCount()); - m_vertex_count = -1; } SubMesh::~SubMesh() @@ -63,9 +60,10 @@ void SubMesh::SetMeshPrimitive(MeshPrimitive mesh_primitive) void SubMesh::SetVertexBuffer(int index, VertexBuffer* vbo) { + while (index >= m_vbos.Count()) + m_vbos.Push(nullptr); + m_vbos[index] = vbo; - if (m_vertex_count < 0) - m_vertex_count = vbo->GetSize() / m_vdecl->GetStream(index).GetSize(); } void SubMesh::AddTexture(const char* name, Texture* texture) @@ -75,10 +73,9 @@ void SubMesh::AddTexture(const char* name, Texture* texture) void SubMesh::Render(Shader* shader) { - ShaderAttrib attribs[12]; + int vertex_count = 0; - int c = 0; - for (int i = 0; i < m_vdecl->GetStreamCount(); ++i) + for (int i = 0; i < m_vbos.Count(); ++i) { ShaderAttrib attribs[12]; @@ -98,18 +95,20 @@ void SubMesh::Render(Shader* shader) attribs[j] = shader->GetAttribLocation(usage, indices[usage]++); } + vertex_count = m_vbos[i]->GetSize() / m_vdecl->GetStream(i).GetSize(); + m_vdecl->SetStream(m_vbos[i], attribs); } for (int i = 0; i < m_textures.Count(); ++i) { // TODO: might be good to cache this - ShaderUniform uniform = shader->GetUniformLocation(m_textures[i].m1.C()); - shader->SetUniform(uniform, m_textures[i].m2->GetTexture(), i); + ShaderUniform u_tex = shader->GetUniformLocation(m_textures[i].m1.C()); + shader->SetUniform(u_tex, m_textures[i].m2->GetTexture(), i); } m_vdecl->Bind(); - m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, m_vertex_count); + m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, vertex_count); m_vdecl->Unbind(); } diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h index 4101ee95..cc1a321a 100644 --- a/src/mesh/mesh.h +++ b/src/mesh/mesh.h @@ -19,6 +19,31 @@ namespace lol { +/* + * A mesh contains a list of submeshes. This is a convenient way to + * handle different materials or mesh types (static, skeletal, morph + * targets, etc.) within the same container object. + */ + +class Mesh +{ +public: + Mesh(); + ~Mesh(); + + void Render(mat4 const &model); + +private: + Array m_submeshes; +}; + +/* + * A submesh contains: + * - a vertex declaration + * - a list of VBOs + * - a list of textures + */ + class SubMesh { public: @@ -34,24 +59,11 @@ public: protected: VertexDeclaration* m_vdecl; MeshPrimitive m_mesh_prim; - VertexBuffer** m_vbos; - int m_vertex_count; + Array m_vbos; Array m_textures; }; -class Mesh -{ -public: - Mesh(); - ~Mesh(); - - void Render(mat4 const &model); - -private: - Array m_submeshes; -}; - } /* namespace lol */ #endif /* __MESH_MESH_H__ */ diff --git a/src/mesh/primitive.cpp b/src/mesh/primitive.cpp new file mode 100644 index 00000000..e8c79c2e --- /dev/null +++ b/src/mesh/primitive.cpp @@ -0,0 +1,39 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2013 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "core.h" + +namespace lol +{ + +/* + * Primitive class + */ + +Primitive::Primitive(Mesh *mesh, Shader *shader, mat4 const &matrix) + : m_mesh(mesh), + m_shader(shader), + m_matrix(matrix) +{ +} + +Primitive::~Primitive() +{ +} + +} /* namespace lol */ + diff --git a/src/mesh/primitive.h b/src/mesh/primitive.h new file mode 100644 index 00000000..9a319659 --- /dev/null +++ b/src/mesh/primitive.h @@ -0,0 +1,42 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2013 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +// +// The Primitive class +// ------------------- +// + +#if !defined __MESH_PRIMITIVE_H__ +#define __MESH_PRIMITIVE_H__ + +#include "mesh/mesh.h" + +namespace lol +{ + +class Primitive +{ + friend class Scene; + +public: + Primitive(Mesh *mesh, Shader *shader, mat4 const &matrix); + ~Primitive(); + +private: + Mesh *m_mesh; + Shader *m_shader; + + mat4 m_matrix; +}; + +} /* namespace lol */ + +#endif /* __MESH_PRIMITIVE_H__ */ + diff --git a/src/scene.cpp b/src/scene.cpp index 4ed6a231..d675accb 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -56,6 +56,10 @@ class SceneData friend class Scene; private: + /* New scenegraph */ + Array m_primitives; + + /* Old API */ Array m_lines; Shader *m_line_shader; VertexDeclaration *m_line_vdecl; @@ -144,6 +148,11 @@ void Scene::Reset() data->m_lights.Empty(); } +void Scene::AddPrimitive(Mesh *mesh, Shader *shader, mat4 const &matrix) +{ + data->m_primitives.Push(Primitive(mesh, shader, matrix)); +} + void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale) { ASSERT(id < tileset->GetTileCount()); @@ -179,6 +188,36 @@ void Scene::RenderPrimitives() { /* TODO: this should be the main entry for rendering of all * primitives found in the scene graph. When we have one. */ + + Shader *shader = nullptr; + ShaderUniform u_model, uni_tex, uni_texsize; + ShaderAttrib a_pos, a_tex; + + for (int i = 0; i < data->m_primitives.Count(); ++i) + { + Primitive &p = data->m_primitives[i]; + + /* If this primitive uses a new shader, update attributes */ + if (p.m_shader != shader) + { + shader = p.m_shader; + + a_pos = shader->GetAttribLocation(VertexUsage::Position, 0); + a_tex = shader->GetAttribLocation(VertexUsage::TexCoord, 0); + + shader->Bind(); + + ShaderUniform u_mat; + u_mat = shader->GetUniformLocation("u_projection"); + shader->SetUniform(u_mat, GetCamera()->GetProjection()); + u_mat = shader->GetUniformLocation("u_view"); + shader->SetUniform(u_mat, GetCamera()->GetView()); + + u_model = shader->GetUniformLocation("u_model"); + } + + shader->SetUniform(u_model, p.m_matrix); + } } void Scene::RenderTiles() // XXX: rename to Blit() @@ -207,11 +246,11 @@ void Scene::RenderTiles() // XXX: rename to Blit() data->m_tile_shader->Bind(); - uni_mat = data->m_tile_shader->GetUniformLocation("proj_matrix"); + uni_mat = data->m_tile_shader->GetUniformLocation("u_projection"); data->m_tile_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); - uni_mat = data->m_tile_shader->GetUniformLocation("view_matrix"); + uni_mat = data->m_tile_shader->GetUniformLocation("u_view"); data->m_tile_shader->SetUniform(uni_mat, GetCamera()->GetView()); - uni_mat = data->m_tile_shader->GetUniformLocation("model_matrix"); + uni_mat = data->m_tile_shader->GetUniformLocation("u_model"); data->m_tile_shader->SetUniform(uni_mat, mat4(1.f)); uni_tex = data->m_tile_shader->GetUniformLocation("in_Texture"); @@ -312,9 +351,9 @@ void Scene::RenderLines() // XXX: rename to Blit() data->m_line_shader->Bind(); - uni_mat = data->m_line_shader->GetUniformLocation("proj_matrix"); + uni_mat = data->m_line_shader->GetUniformLocation("u_projection"); data->m_line_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); - uni_mat = data->m_line_shader->GetUniformLocation("view_matrix"); + uni_mat = data->m_line_shader->GetUniformLocation("u_view"); data->m_line_shader->SetUniform(uni_mat, GetCamera()->GetView()); data->m_line_vdecl->Bind(); diff --git a/src/scene.h b/src/scene.h index 92fc6357..3baf38de 100644 --- a/src/scene.h +++ b/src/scene.h @@ -21,6 +21,7 @@ #include "tileset.h" #include "light.h" #include "camera.h" +#include "mesh/primitive.h" namespace lol { @@ -46,6 +47,9 @@ public: void RenderTiles(); void RenderLines(); + /* New scenegraph */ + void AddPrimitive(Mesh *mesh, Shader *shader, mat4 const &matrix); + /* FIXME: this should be deprecated -- it doesn't really match * the architecture we want to build */ void AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale);