|
|
@@ -56,18 +56,6 @@ class SceneData |
|
|
|
friend class Scene; |
|
|
|
|
|
|
|
private: |
|
|
|
static int Compare(void const *p1, void const *p2) |
|
|
|
{ |
|
|
|
Tile const *t1 = (Tile const *)p1; |
|
|
|
Tile const *t2 = (Tile const *)p2; |
|
|
|
|
|
|
|
if (t1->pos.z > t2->pos.z) |
|
|
|
return 1; |
|
|
|
if (t1->pos.z < t2->pos.z) |
|
|
|
return -1; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
Array<vec3, vec3, vec4> m_lines; |
|
|
|
Shader *m_line_shader; |
|
|
|
VertexDeclaration *m_line_vdecl; |
|
|
@@ -187,162 +175,156 @@ Array<Light *> const &Scene::GetLights() const |
|
|
|
return data->m_lights; |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::Render() // XXX: rename to Blit() |
|
|
|
void Scene::RenderPrimitives() |
|
|
|
{ |
|
|
|
/* TODO: this should be the main entry for rendering of all |
|
|
|
* primitives found in the scene graph. When we have one. */ |
|
|
|
} |
|
|
|
|
|
|
|
void Scene::RenderTiles() // XXX: rename to Blit() |
|
|
|
{ |
|
|
|
RenderContext rc; |
|
|
|
|
|
|
|
/* Early test if nothing needs to be rendered */ |
|
|
|
if (data->m_tiles.Count()) |
|
|
|
{ |
|
|
|
rc.SetDepthFunc(DepthFunc::LessOrEqual); |
|
|
|
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); |
|
|
|
rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); |
|
|
|
if (!data->m_tiles.Count()) |
|
|
|
return; |
|
|
|
|
|
|
|
PushCamera(data->m_default_cam); |
|
|
|
rc.SetDepthFunc(DepthFunc::LessOrEqual); |
|
|
|
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); |
|
|
|
rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); |
|
|
|
|
|
|
|
#if defined USE_D3D9 || defined _XBOX |
|
|
|
#elif !defined HAVE_GLES_2X |
|
|
|
glEnable(GL_TEXTURE_2D); |
|
|
|
glEnable(GL_TEXTURE_2D); |
|
|
|
#endif |
|
|
|
if (!data->m_tile_shader) |
|
|
|
data->m_tile_shader = Shader::Create(LOLFX_RESOURCE_NAME(tile)); |
|
|
|
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 = rand<int>() % 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, uni_texsize; |
|
|
|
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); |
|
|
|
|
|
|
|
ShaderUniform uni_mat, uni_tex, uni_texsize; |
|
|
|
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->m_tile_shader->Bind(); |
|
|
|
|
|
|
|
data->m_tile_shader->Bind(); |
|
|
|
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_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); |
|
|
|
uni_texsize = data->m_tile_shader->GetUniformLocation("in_TexSize"); |
|
|
|
|
|
|
|
for (int buf = 0, i = 0, n; i < data->m_tiles.Count(); i = n, buf += 2) |
|
|
|
{ |
|
|
|
/* 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; |
|
|
|
|
|
|
|
uni_tex = data->m_tile_shader->GetUniformLocation("in_Texture"); |
|
|
|
data->m_tile_shader->SetUniform(uni_tex, 0); |
|
|
|
uni_texsize = data->m_tile_shader->GetUniformLocation("in_TexSize"); |
|
|
|
/* 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); |
|
|
|
|
|
|
|
for (int buf = 0, i = 0, n; i < data->m_tiles.Count(); i = n, buf += 2) |
|
|
|
data->m_tile_bufs.Push(vb1); |
|
|
|
data->m_tile_bufs.Push(vb2); |
|
|
|
|
|
|
|
for (int j = i; j < n; j++) |
|
|
|
{ |
|
|
|
/* 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(); |
|
|
|
data->m_tile_shader->SetUniform(uni_texsize, |
|
|
|
(vec2)data->m_tiles[i].tileset->GetTextureSize()); |
|
|
|
|
|
|
|
/* 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(); |
|
|
|
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)); |
|
|
|
} |
|
|
|
|
|
|
|
data->m_tiles.Empty(); |
|
|
|
vb1->Unlock(); |
|
|
|
vb2->Unlock(); |
|
|
|
|
|
|
|
/* Bind texture */ |
|
|
|
data->m_tiles[i].tileset->Bind(); |
|
|
|
data->m_tile_shader->SetUniform(uni_texsize, |
|
|
|
(vec2)data->m_tiles[i].tileset->GetTextureSize()); |
|
|
|
|
|
|
|
data->m_tile_shader->Unbind(); |
|
|
|
/* 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(); |
|
|
|
} |
|
|
|
|
|
|
|
data->m_tiles.Empty(); |
|
|
|
|
|
|
|
data->m_tile_shader->Unbind(); |
|
|
|
|
|
|
|
#if defined USE_D3D9 || defined _XBOX |
|
|
|
/* TODO */ |
|
|
|
/* TODO */ |
|
|
|
#elif !defined HAVE_GLES_2X |
|
|
|
glDisable(GL_TEXTURE_2D); |
|
|
|
glDisable(GL_TEXTURE_2D); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
PopCamera(data->m_default_cam); |
|
|
|
} |
|
|
|
void Scene::RenderLines() // XXX: rename to Blit() |
|
|
|
{ |
|
|
|
RenderContext rc; |
|
|
|
|
|
|
|
if (data->m_lines.Count()) |
|
|
|
{ |
|
|
|
rc.SetDepthFunc(DepthFunc::LessOrEqual); |
|
|
|
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); |
|
|
|
rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); |
|
|
|
if (!data->m_lines.Count()) |
|
|
|
return; |
|
|
|
|
|
|
|
int linecount = data->m_lines.Count(); |
|
|
|
rc.SetDepthFunc(DepthFunc::LessOrEqual); |
|
|
|
rc.SetBlendFunc(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha); |
|
|
|
rc.SetAlphaFunc(AlphaFunc::GreaterOrEqual, 0.01f); |
|
|
|
|
|
|
|
if (!data->m_line_shader) |
|
|
|
data->m_line_shader = Shader::Create(LOLFX_RESOURCE_NAME(line)); |
|
|
|
int linecount = data->m_lines.Count(); |
|
|
|
|
|
|
|
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(); |
|
|
|
if (!data->m_line_shader) |
|
|
|
data->m_line_shader = Shader::Create(LOLFX_RESOURCE_NAME(line)); |
|
|
|
|
|
|
|
data->m_line_shader->Bind(); |
|
|
|
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(); |
|
|
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
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_line_shader->Bind(); |
|
|
|
|
|
|
|
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(); |
|
|
|
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_lines.Empty(); |
|
|
|
delete vb; |
|
|
|
} |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
} /* namespace lol */ |
|
|
|