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);