diff --git a/src/Makefile.am b/src/Makefile.am index 68a6f085..f6fe843d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,6 +50,9 @@ liblolcore_headers = \ lol/gpu/shader.h lol/gpu/indexbuffer.h lol/gpu/vertexbuffer.h \ lol/gpu/framebuffer.h lol/gpu/texture.h lol/gpu/lolfx.h \ \ + lol/debug/debug.h \ + lol/debug/line.h \ + \ lol/unit.h liblolcore_sources = \ @@ -80,7 +83,7 @@ liblolcore_sources = \ input/stick.cpp input/stick.h \ \ gpu/defaultmaterial.lolfx \ - gpu/tile.lolfx \ + gpu/tile.lolfx gpu/line.lolfx \ gpu/emptymaterial.lolfx \ gpu/testmaterial.lolfx \ \ @@ -101,7 +104,7 @@ liblolcore_sources = \ image/color/cie1931.cpp \ \ loldebug.h \ - debug/fps.cpp debug/fps.h \ + debug/fps.cpp debug/fps.h debug/lines.cpp \ debug/record.cpp debug/record.h debug/stats.cpp debug/stats.h sdl_sources = \ diff --git a/src/core.h b/src/core.h index 182f2d2e..3804109d 100644 --- a/src/core.h +++ b/src/core.h @@ -84,6 +84,7 @@ static inline int isnan(float f) #include #include #include +#include #include "numeric.h" diff --git a/src/debug/lines.cpp b/src/debug/lines.cpp new file mode 100644 index 00000000..3c7e108a --- /dev/null +++ b/src/debug/lines.cpp @@ -0,0 +1,52 @@ +// +// 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 "core.h" + +namespace lol +{ + +void Debug::DrawLine(vec3 a, vec3 b, vec4 color) +{ + Scene::GetDefault()->AddLine(a, b, color); +} + +void Debug::DrawBox(vec3 a, vec3 b, vec4 color) +{ + vec3 v[8]; + for (int i = 0; i < 8; i++) + { + v[i].x = i & 1 ? a.x : b.x; + v[i].y = i & 2 ? a.y : b.y; + v[i].z = i & 4 ? a.z : b.z; + } + + Scene::GetDefault()->AddLine(v[0], v[1], color); + Scene::GetDefault()->AddLine(v[1], v[3], color); + Scene::GetDefault()->AddLine(v[3], v[2], color); + Scene::GetDefault()->AddLine(v[2], v[0], color); + + Scene::GetDefault()->AddLine(v[4], v[5], color); + Scene::GetDefault()->AddLine(v[5], v[7], color); + Scene::GetDefault()->AddLine(v[7], v[6], color); + Scene::GetDefault()->AddLine(v[6], v[4], color); + + Scene::GetDefault()->AddLine(v[0], v[4], color); + Scene::GetDefault()->AddLine(v[1], v[5], color); + Scene::GetDefault()->AddLine(v[2], v[6], color); + Scene::GetDefault()->AddLine(v[3], v[7], color); +} + +} /* namespace lol */ + diff --git a/src/gpu/line.lolfx b/src/gpu/line.lolfx new file mode 100644 index 00000000..a0fe1703 --- /dev/null +++ b/src/gpu/line.lolfx @@ -0,0 +1,54 @@ +[vert.glsl] + +#version 130 + +attribute vec3 in_Position; +attribute vec4 in_Color; +varying vec4 pass_Color; + +uniform mat4 proj_matrix; +uniform mat4 view_matrix; + +void main() +{ + gl_Position = proj_matrix * view_matrix + * vec4(in_Position, 1.0); + pass_Color = in_Color; +} + +[frag.glsl] + +#version 130 + +#if defined GL_ES +precision mediump float; +#endif + +varying vec4 pass_Color; + +void main() +{ + gl_FragColor = pass_Color; +} + +[vert.hlsl] + +void main(float4 in_Position : POSITION, + float4 in_Color : COLOR, + uniform float4x4 proj_matrix, + uniform float4x4 view_matrix, + out float4 out_Color : COLOR, + out float4 out_Position : POSITION) +{ + out_Position = mul(proj_matrix, mul(view_matrix, in_Position)); + out_Color = in_Color; +} + +[frag.hlsl] + +void main(float4 in_Color : COLOR, + out float4 out_FragColor : COLOR) +{ + out_FragColor = in_Color; +} + diff --git a/src/lol/debug/debug.h b/src/lol/debug/debug.h new file mode 100644 index 00000000..5c2532f2 --- /dev/null +++ b/src/lol/debug/debug.h @@ -0,0 +1,17 @@ +// +// 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 __LOL_DEBUG_DEBUG_H__ +#define __LOL_DEBUG_DEBUG_H__ + +#include + +#endif // __LOL_DEBUG_DEBUG_H__ + diff --git a/src/lol/debug/lines.h b/src/lol/debug/lines.h new file mode 100644 index 00000000..bd47a3eb --- /dev/null +++ b/src/lol/debug/lines.h @@ -0,0 +1,35 @@ +// +// 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. +// + +// +// Debug line primitives +// --------------------- +// + +#if !defined __LOL_DEBUG_LINES_H__ +#define __LOL_DEBUG_LINES_H__ + +#include + +namespace lol +{ + +namespace Debug +{ + +void DrawLine(vec3 a, vec3 b, vec4 color); +void DrawBox(vec3 a, vec3 b, vec4 color); + +} /* namespace Debug */ + +} /* namespace lol */ + +#endif // __LOL_DEBUG_LINES_H__ + diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj index 522a04c8..1fd0da3a 100644 --- a/src/lolcore.vcxproj +++ b/src/lolcore.vcxproj @@ -95,6 +95,7 @@ + @@ -203,6 +204,8 @@ + + @@ -263,6 +266,7 @@ + diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters index d27e774c..a2b883d6 100644 --- a/src/lolcore.vcxproj.filters +++ b/src/lolcore.vcxproj.filters @@ -592,6 +592,9 @@ ... + + ... + ... diff --git a/src/scene.cpp b/src/scene.cpp index c1e3bf84..db110418 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -23,6 +23,7 @@ #include "lolgl.h" LOLFX_RESOURCE_DECLARE(tile); +LOLFX_RESOURCE_DECLARE(line); namespace lol { @@ -57,12 +58,16 @@ private: return 0; } + Array m_lines; + Shader *m_line_shader; + VertexDeclaration *m_line_vdecl; + Array m_tiles; Array m_lights; - Shader *m_shader; - VertexDeclaration *m_vdecl; - Array bufs; + Shader *m_tile_shader; + VertexDeclaration *m_tile_vdecl; + Array m_tile_bufs; Camera *m_default_cam; Array m_camera_stack; @@ -86,9 +91,12 @@ Scene::Scene() data->m_default_cam->SetProjection(proj); PushCamera(data->m_default_cam); - data->m_shader = 0; - data->m_vdecl = new VertexDeclaration(VertexStream(VertexUsage::Position), - VertexStream(VertexUsage::TexCoord)); + data->m_tile_shader = 0; + data->m_tile_vdecl = new VertexDeclaration(VertexStream(VertexUsage::Position), + VertexStream(VertexUsage::TexCoord)); + + data->m_line_shader = 0; + data->m_line_vdecl = new VertexDeclaration(VertexStream(VertexUsage::Position, VertexUsage::Color)); } Scene::~Scene() @@ -101,7 +109,8 @@ Scene::~Scene() * reallocate stuff */ Reset(); - delete data->m_vdecl; + delete data->m_line_vdecl; + delete data->m_tile_vdecl; delete data; } @@ -142,9 +151,10 @@ Camera *Scene::GetCamera() void Scene::Reset() { - for (int i = 0; i < data->bufs.Count(); i++) - delete data->bufs[i]; - data->bufs.Empty(); + for (int i = 0; i < data->m_tile_bufs.Count(); i++) + delete data->m_tile_bufs[i]; + data->m_tile_bufs.Empty(); + data->m_lights.Empty(); } @@ -162,6 +172,11 @@ void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale) data->m_tiles.Push(t); } +void Scene::AddLine(vec3 a, vec3 b, vec4 color) +{ + data->m_lines.Push(a, b, color); +} + void Scene::AddLight(Light *l) { data->m_lights.Push(l); @@ -174,48 +189,8 @@ Array const &Scene::GetLights() const void Scene::Render() // XXX: rename to Blit() { - /* Early exit if nothing needs to be rendered */ - if (!data->m_tiles.Count()) - return; - - if (!data->m_shader) - data->m_shader = Shader::Create(LOLFX_RESOURCE_NAME(tile)); - -#if 0 - // Randomise, then sort. - for (int i = 0; i < data->m_tiles.Count(); i++) - { - Tile tmp = data->m_tiles[i]; - int j = std::rand() % data->m_tiles.Count(); - data->m_tiles[i] = data->m_tiles[j]; - data->m_tiles[j] = tmp; - } -#endif - qsort(&data->m_tiles[0], data->m_tiles.Count(), - sizeof(Tile), SceneData::Compare); - - ShaderUniform uni_mat, uni_tex; - ShaderAttrib attr_pos, attr_tex; - attr_pos = data->m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0); - attr_tex = data->m_shader->GetAttribLocation("in_TexCoord", VertexUsage::TexCoord, 0); - - data->m_shader->Bind(); - - uni_mat = data->m_shader->GetUniformLocation("proj_matrix"); - data->m_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); - uni_mat = data->m_shader->GetUniformLocation("view_matrix"); - data->m_shader->SetUniform(uni_mat, GetCamera()->GetView()); - uni_mat = data->m_shader->GetUniformLocation("model_matrix"); - data->m_shader->SetUniform(uni_mat, mat4(1.f)); - #if defined USE_D3D9 || defined _XBOX #else - uni_tex = data->m_shader->GetUniformLocation("in_Texture"); - data->m_shader->SetUniform(uni_tex, 0); - -#if !defined HAVE_GLES_2X - glEnable(GL_TEXTURE_2D); -#endif glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); #if defined HAVE_GL_2X && !defined __APPLE__ @@ -226,61 +201,151 @@ void Scene::Render() // XXX: rename to Blit() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #endif - for (int buf = 0, i = 0, n; i < data->m_tiles.Count(); i = n, buf += 2) + /* Early test if nothing needs to be rendered */ + if (data->m_tiles.Count()) { - /* Count how many quads will be needed */ - for (n = i + 1; n < data->m_tiles.Count(); n++) - if (data->m_tiles[i].tileset != data->m_tiles[n].tileset) - break; +#if defined USE_D3D9 || defined _XBOX +#elif !defined HAVE_GLES_2X + glEnable(GL_TEXTURE_2D); +#endif + if (!data->m_tile_shader) + data->m_tile_shader = Shader::Create(LOLFX_RESOURCE_NAME(tile)); + +#if 0 + // Randomise, then sort. + for (int i = 0; i < data->m_tiles.Count(); i++) + { + Tile tmp = data->m_tiles[i]; + int j = std::rand() % data->m_tiles.Count(); + data->m_tiles[i] = data->m_tiles[j]; + data->m_tiles[j] = tmp; + } +#endif + qsort(&data->m_tiles[0], data->m_tiles.Count(), + sizeof(Tile), SceneData::Compare); - /* Create a vertex array object */ - VertexBuffer *vb1 = new VertexBuffer(6 * 3 * (n - i) * sizeof(float)); - float *vertex = (float *)vb1->Lock(0, 0); - VertexBuffer *vb2 = new VertexBuffer(6 * 2 * (n - i) * sizeof(float)); - float *texture = (float *)vb2->Lock(0, 0); + ShaderUniform uni_mat, uni_tex; + ShaderAttrib attr_pos, attr_tex; + attr_pos = data->m_tile_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0); + attr_tex = data->m_tile_shader->GetAttribLocation("in_TexCoord", VertexUsage::TexCoord, 0); - data->bufs.Push(vb1); - data->bufs.Push(vb2); + data->m_tile_shader->Bind(); - for (int j = i; j < n; j++) + uni_mat = data->m_tile_shader->GetUniformLocation("proj_matrix"); + data->m_tile_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); + uni_mat = data->m_tile_shader->GetUniformLocation("view_matrix"); + data->m_tile_shader->SetUniform(uni_mat, GetCamera()->GetView()); + uni_mat = data->m_tile_shader->GetUniformLocation("model_matrix"); + data->m_tile_shader->SetUniform(uni_mat, mat4(1.f)); + + uni_tex = data->m_tile_shader->GetUniformLocation("in_Texture"); + data->m_tile_shader->SetUniform(uni_tex, 0); + + for (int buf = 0, i = 0, n; i < data->m_tiles.Count(); i = n, buf += 2) { - data->m_tiles[i].tileset->BlitTile(data->m_tiles[j].id, - data->m_tiles[j].pos, data->m_tiles[j].o, - data->m_tiles[j].scale, - vertex + 18 * (j - i), texture + 12 * (j - i)); + /* Count how many quads will be needed */ + for (n = i + 1; n < data->m_tiles.Count(); n++) + if (data->m_tiles[i].tileset != data->m_tiles[n].tileset) + break; + + /* Create a vertex array object */ + VertexBuffer *vb1 = new VertexBuffer(6 * 3 * (n - i) * sizeof(float)); + float *vertex = (float *)vb1->Lock(0, 0); + VertexBuffer *vb2 = new VertexBuffer(6 * 2 * (n - i) * sizeof(float)); + float *texture = (float *)vb2->Lock(0, 0); + + data->m_tile_bufs.Push(vb1); + data->m_tile_bufs.Push(vb2); + + for (int j = i; j < n; j++) + { + data->m_tiles[i].tileset->BlitTile(data->m_tiles[j].id, + data->m_tiles[j].pos, data->m_tiles[j].o, + data->m_tiles[j].scale, + vertex + 18 * (j - i), texture + 12 * (j - i)); + } + + vb1->Unlock(); + vb2->Unlock(); + + /* Bind texture */ + data->m_tiles[i].tileset->Bind(); + + /* Bind vertex and texture coordinate buffers */ + data->m_tile_vdecl->Bind(); + data->m_tile_vdecl->SetStream(vb1, attr_pos); + data->m_tile_vdecl->SetStream(vb2, attr_tex); + + /* Draw arrays */ + data->m_tile_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); + data->m_tile_vdecl->Unbind(); + data->m_tiles[i].tileset->Unbind(); } - vb1->Unlock(); - vb2->Unlock(); - - /* Bind texture */ - data->m_tiles[i].tileset->Bind(); + data->m_tiles.Empty(); - /* Bind vertex and texture coordinate buffers */ - data->m_vdecl->Bind(); - data->m_vdecl->SetStream(vb1, attr_pos); - data->m_vdecl->SetStream(vb2, attr_tex); + data->m_tile_shader->Unbind(); - /* Draw arrays */ - data->m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); - data->m_vdecl->Unbind(); - data->m_tiles[i].tileset->Unbind(); +#if defined USE_D3D9 || defined _XBOX + /* TODO */ +#elif !defined HAVE_GLES_2X + glDisable(GL_TEXTURE_2D); +#endif } - data->m_tiles.Empty(); + if (data->m_lines.Count()) + { + int linecount = data->m_lines.Count(); + + if (!data->m_line_shader) + data->m_line_shader = Shader::Create(LOLFX_RESOURCE_NAME(line)); + + VertexBuffer *vb = new VertexBuffer((sizeof(vec3) + sizeof(vec4)) * 2 * linecount); + float *vertex = (float *)vb->Lock(0, 0); + for (int i = 0; i < linecount; i++) + { + memcpy(vertex, &data->m_lines[i].m1, sizeof(vec3)); + vertex += 3; + memcpy(vertex, &data->m_lines[i].m3, sizeof(vec4)); + vertex += 4; + memcpy(vertex, &data->m_lines[i].m2, sizeof(vec3)); + vertex += 3; + memcpy(vertex, &data->m_lines[i].m3, sizeof(vec4)); + vertex += 4; + } + vb->Unlock(); + + data->m_line_shader->Bind(); + + ShaderUniform uni_mat, uni_tex; + ShaderAttrib attr_pos, attr_col; + attr_pos = data->m_line_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0); + attr_col = data->m_line_shader->GetAttribLocation("in_Color", VertexUsage::Color, 0); + + data->m_line_shader->Bind(); + + uni_mat = data->m_line_shader->GetUniformLocation("proj_matrix"); + data->m_line_shader->SetUniform(uni_mat, GetCamera()->GetProjection()); + uni_mat = data->m_line_shader->GetUniformLocation("view_matrix"); + data->m_line_shader->SetUniform(uni_mat, GetCamera()->GetView()); - data->m_shader->Unbind(); + data->m_line_vdecl->Bind(); + data->m_line_vdecl->SetStream(vb, attr_pos, attr_col); + data->m_line_vdecl->DrawElements(MeshPrimitive::Lines, 0, 2 * linecount); + data->m_line_vdecl->Unbind(); + data->m_line_shader->Unbind(); + + data->m_lines.Empty(); + delete vb; + } #if defined USE_D3D9 || defined _XBOX /* TODO */ #else -#if !defined HAVE_GLES_2X - glDisable(GL_TEXTURE_2D); -#endif glDisable(GL_DEPTH_TEST); -#if defined HAVE_GL_2X && !defined __APPLE__ +# if defined HAVE_GL_2X && !defined __APPLE__ glDisable(GL_ALPHA_TEST); -#endif +# endif glDisable(GL_BLEND); #endif } diff --git a/src/scene.h b/src/scene.h index 90b1473b..440621e1 100644 --- a/src/scene.h +++ b/src/scene.h @@ -45,6 +45,7 @@ public: /* 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); + void AddLine(vec3 a, vec3 b, vec4 color); void AddLight(Light *light); Array const &GetLights() const;