To date he has been using an open framework called whirlyglobe. This is a pretty impressive framework and I would recommend that you check it out but after testing it on an iPad2 and 'The New iPad' within the app it seemed a little slow. Vector files are being used to highlight the country, raising it above others when selected. All of this is in very high detail and looks excellent, but this detail does come at a cost. The response on the iPad is sluggish and would probably be even more so when there is an app sitting above it.
When looking into how we could improve the performance, I suggested that I could use the concepts that I developed when programming the original Decade Engine, along with the new features I have been learning with converting the original engine to OpenGL 3/OpenGL ES 2.0.
Here is the first rendering from Decade Mobile. Please note that this video was recorded off my Mac Mini but the same code (with minor changes which I shall document in a latter post) has been built and runs on an iPad and iPhone.
The textures used in this video have been purchased from here. Since zooming is only required to the country level and not to the cm or meter level as was possible in the original Decade Engine, I thought it overkill to use the procedural sphere technique so instead just use a normal sphere. Some webgl code for generating the vertices for a sphere can be found here.
_______________________________________________________________________________
Sphere Generation (Vertex and Index Buffer) Code
void Sphere::Create(const Vector3 center, GLfloat radius, GLuint precision)
{
vector
GLuint latitudeBands = precision;
GLuint longitudeBands = precision;
for (GLuint latNumber = 0; latNumber <= latitudeBands; latNumber++)
{
GLfloat theta = latNumber * M_PI / latitudeBands;
GLfloat sinTheta = sinf(theta);
GLfloat cosTheta = cosf(theta);
for (GLuint longNumber = 0; longNumber <= longitudeBands; longNumber++)
{
GLfloat phi = longNumber * 2 * M_PI / longitudeBands;
GLfloat sinPhi = sinf(phi);
GLfloat cosPhi = cosf(phi);
GLfloat x = cosPhi * sinTheta;
GLfloat y = cosTheta;
GLfloat z = sinPhi * sinTheta;
GLfloat u = 1.0f - ((GLfloat)longNumber / (GLfloat)longitudeBands);
GLfloat v = (GLfloat)latNumber / (GLfloat)latitudeBands;
VERTEX_POSITION_UV0 vertex;
vertex.Position = Point4(radius * x, radius * y, radius * z, 1.0f);
vertex.U0 = u;
vertex.V0 = 1.0f - v;
vertices.push_back(vertex);
}
}
vector
for (GLuint latNumber = 0; latNumber < latitudeBands; latNumber++)
{
for (GLuint longNumber = 0; longNumber < longitudeBands; longNumber++)
{
GLuint first = (latNumber * (longitudeBands + 1)) + longNumber;
GLuint second = first + longitudeBands + 1;
indices.push_back(first);
indices.push_back(second);
indices.push_back(first + 1);
indices.push_back(second);
indices.push_back(second + 1);
indices.push_back(first + 1);
}
}
vertexBuffer.Create((float*)vertices, VERTEX_POSITION_UV0::GetFloatsInFormat(), vertices,size(), VERTEX_POSITION_UV0::GetFormat());
indexBuffer.Create(indices, indices.size());
}
void Sphere::Bind()
{
vertexBuffer.Bind();
indexBuffer.Bind();
}
void Sphere::Render()
{
vertexBuffer.Render(&indexBuffer, GL_TRIANGLES);
}
_________________________________________________________________________________
Vertex Shader
uniform mat4 mvp;
in vec4 position;
in vec2 uv0;
out vec2 textureCoord0;
void main (void)
{
textureCoord0 = uv0;
gl_Position = mvp * position;
}
_________________________________________________________________________________
Fragment Shader
in vec2 textureCoord0;
uniform sampler2D texture0;
out vec4 fragColor;
void main(void)
{
fragColor = texture(texture0, textureCoord0);
}
No comments:
Post a Comment