|
|
@@ -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<vec3, vec3, vec4> m_lines; |
|
|
|
Shader *m_line_shader; |
|
|
|
VertexDeclaration *m_line_vdecl; |
|
|
|
|
|
|
|
Array<Tile> m_tiles; |
|
|
|
Array<Light *> m_lights; |
|
|
|
|
|
|
|
Shader *m_shader; |
|
|
|
VertexDeclaration *m_vdecl; |
|
|
|
Array<VertexBuffer *> bufs; |
|
|
|
Shader *m_tile_shader; |
|
|
|
VertexDeclaration *m_tile_vdecl; |
|
|
|
Array<VertexBuffer *> m_tile_bufs; |
|
|
|
|
|
|
|
Camera *m_default_cam; |
|
|
|
Array<Camera *> 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<vec3>(VertexUsage::Position), |
|
|
|
VertexStream<vec2>(VertexUsage::TexCoord)); |
|
|
|
data->m_tile_shader = 0; |
|
|
|
data->m_tile_vdecl = new VertexDeclaration(VertexStream<vec3>(VertexUsage::Position), |
|
|
|
VertexStream<vec2>(VertexUsage::TexCoord)); |
|
|
|
|
|
|
|
data->m_line_shader = 0; |
|
|
|
data->m_line_vdecl = new VertexDeclaration(VertexStream<vec3,vec4>(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<Light *> 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 |
|
|
|
} |
|
|
|