Thanks for the responses guys.
Below is the slice of code where things are going awry. Basically my eventual goal is to allow the user to open a file via URL (CityGML file…much like an XML file), send it through a parser to strip out the vertices, then render it.
I’m currently hard-coding in a simple scene consisting of two, side-by-side, rectangular buildings, because four months ago I had never touched OpenGL and I’m still struggling to teach myself.
The trouble I may run into using your suggestion, David, is that scenes could reach upwards of a few hundred thousand vertices, so adding more would just take space, which is valuable on a mobile device (Android).
mhagain, I think I understand your suggestion. If I understand correctly, I would then just run a loop for i < theNumberOfVertices and number the indices as you indicated?
(Also, don’t hesitate to point out any other blatant errors you see…I’m still struggling with generating normals.)
package com.android.aliaga;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class AliagaRenderer implements GLSurfaceView.Renderer {
private FloatBuffer _vertexBuffer, _normalBuffer;
private int _nrOfVertices = 0;
float[][] point;
float[][] out;
float[] normalCoords;
public int detail = GL10.GL_TRIANGLE_FAN;
private float _xAngle;
private float _yAngle;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glFrontFace(GL10.GL_CCW);
gl.glCullFace(GL10.GL_BACK);
gl.glEnable(GL10.GL_CULL_FACE);
initShape();
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
}
public void setXAngle(float angle) {
_xAngle = angle;
}
public float getXAngle() {
return _xAngle;
}
public void setYAngle(float angle) {
_yAngle = angle;
}
public float getYAngle() {
return _yAngle;
}
public void onDrawFrame(GL10 gl) {
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
if(_xAngle > 0 && _xAngle <= 90) {
gl.glRotatef(_xAngle, 1.0f, 0.0f, 0.0f);
}
if(_xAngle > 90) {
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
}
gl.glRotatef(_yAngle, 0.0f, 1.0f, 0.0f);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(-50.0f, 50.0f, -50.0f, 50.0f, -50.0f, 50.0f);
gl.glClearColor(0.0f, 0.1f, 1.0f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glNormalPointer(GL10.GL_FLOAT, 0, _normalBuffer);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_LIGHTING);
FloatBuffer light0 = FloatBuffer.allocate(4);
light0.put(2.0f); light0.put(2.0f); light0.put(0.0f); light0.put(1.0f);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, light0);
FloatBuffer light1 = FloatBuffer.allocate(4);
light1.put(0.5f); light1.put(5.0f); light1.put(2.0f); light1.put(1.0f);
gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, light1);
gl.glEnable(GL10.GL_LIGHT0);
gl.glEnable(GL10.GL_LIGHT1);
gl.glDrawArrays(detail, 0, _nrOfVertices);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
gl.glFlush();
}
public void detail(int d) {
detail = d;
}
private void initShape() {
float[] coords = {
-37.7409625706199f, -17.9680353881589f, -5.77529135625809e-015f, -37.7409625706199f, 20.9752646118411f, -5.77529135625809e-015f, -15.8699625706199f, 20.9752646118411f, -5.77529135625809e-015f, -15.8699625706199f, -17.9680353881589f, -5.77529135625809e-015f, -37.7409625706199f, -17.9680353881589f, -5.77529135625809e-015f, -37.7409625706199f, 20.9752646118411f, 9.690299999999f, -37.7409625706199f, -17.9680353881589f, 9.690299999999f, -15.8699625706199f, -17.9680353881589f, 9.690299999999f, -15.8699625706199f, 20.9752646118411f, 9.690299999999f, -37.7409625706199f, 20.9752646118411f, 9.690299999999f, -37.7409625706199f, 20.9752646118411f, -5.77529135625809e-015f, -37.7409625706199f, -17.9680353881589f, -5.77529135625809e-015f, -37.7409625706199f, -17.9680353881589f, 9.690299999999f, -37.7409625706199f, 20.9752646118411f, 9.690299999999f, -37.7409625706199f, 20.9752646118411f, -5.77529135625809e-015f, -15.8699625706199f, 20.9752646118411f, -5.77529135625809e-015f, -37.7409625706199f, 20.9752646118411f, -5.77529135625809e-015f, -37.7409625706199f, 20.9752646118411f, 9.690299999999f, -15.8699625706199f, 20.9752646118411f, 9.690299999999f, -15.8699625706199f, 20.9752646118411f, -5.77529135625809e-015f, -15.8699625706199f, -17.9680353881589f, -5.77529135625809e-015f, -15.8699625706199f, 20.9752646118411f, -5.77529135625809e-015f, -15.8699625706199f, 20.9752646118411f, 9.690299999999f, -15.8699625706199f, -17.9680353881589f, 9.690299999999f, -15.8699625706199f, -17.9680353881589f, -5.77529135625809e-015f, -37.7409625706199f, -17.9680353881589f, -5.77529135625809e-015f, -15.8699625706199f, -17.9680353881589f, -5.77529135625809e-015f, -15.8699625706199f, -17.9680353881589f, 9.690299999999f, -37.7409625706199f, -17.9680353881589f, 9.690299999999f, -37.7409625706199f, -17.9680353881589f, -5.77529135625809e-015f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f, -0.605428229284897f, 21.2264989808161f, -8.99301431951953e-029f, 21.2655717707151f, 21.2264989808161f, -8.99301431951953e-029f, 21.2655717707151f, -17.7168010191839f, -8.99301431951953e-029f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f, -0.605428229284897f, 21.2264989808161f, 9.6903f, -0.605428229284897f, -17.7168010191839f, 9.6903f, 21.2655717707151f, -17.7168010191839f, 9.6903f, 21.2655717707151f, 21.2264989808161f, 9.6903f, -0.605428229284897f, 21.2264989808161f, 9.6903f, -0.605428229284897f, 21.2264989808161f, -8.99301431951953e-029f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f, -0.605428229284897f, -17.7168010191839f, 9.6903f, -0.605428229284897f, 21.2264989808161f, 9.6903f, -0.605428229284897f, 21.2264989808161f, -8.99301431951953e-029f, 21.2655717707151f, 21.2264989808161f, -8.99301431951953e-029f, -0.605428229284897f, 21.2264989808161f, -8.99301431951953e-029f, -0.605428229284897f, 21.2264989808161f, 9.6903f, 21.2655717707151f, 21.2264989808161f, 9.6903f, 21.2655717707151f, 21.2264989808161f, -8.99301431951953e-029f, 21.2655717707151f, -17.7168010191839f, -8.99301431951953e-029f, 21.2655717707151f, 21.2264989808161f, -8.99301431951953e-029f, 21.2655717707151f, 21.2264989808161f, 9.6903f, 21.2655717707151f, -17.7168010191839f, 9.6903f, 21.2655717707151f, -17.7168010191839f, -8.99301431951953e-029f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f, 21.2655717707151f, -17.7168010191839f, -8.99301431951953e-029f, 21.2655717707151f, -17.7168010191839f, 9.6903f, -0.605428229284897f, -17.7168010191839f, 9.6903f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f, 21.2655717707151f, -17.7168010191839f, -8.99301431951953e-029f, 21.2655717707151f, -17.7168010191839f, 9.6903f, -0.605428229284897f, -17.7168010191839f, 9.6903f, -0.605428229284897f, -17.7168010191839f, -8.99301431951953e-029f
};
_nrOfVertices = coords.length;
ByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4);
vbb.order(ByteOrder.nativeOrder());
_vertexBuffer = vbb.asFloatBuffer();
_vertexBuffer.put(coords);
_vertexBuffer.position(0);
// Fills vertex array with coordinates
point = new float[_nrOfVertices/3][3];
int i = 0;
int j = 0;
while(i<_nrOfVertices) {
point[j][0] = coords[i++]; // x
point[j][1] = coords[i++]; // y
point[j++][2] = coords[i++]; // z
}
// Normal function called
normalCoords = new float[(_nrOfVertices/3)];
normal();
ByteBuffer nb = ByteBuffer.allocateDirect(normalCoords.length*4);
nb.order(ByteOrder.nativeOrder());
_normalBuffer = nb.asFloatBuffer();
_normalBuffer.put(normalCoords);
_normalBuffer.position(0);
}
void normal() {
float[] v1 = new float[3];
float[] v2 = new float[3];
int i = 0;
int j = 0;
while(i<(_nrOfVertices/3)) {
v1[0] = point[i+1][0] - point[i][0];
v1[1] = point[i+1][1] - point[i][1];
v1[2] = point[i+1][2] - point[i][2];
v2[0] = point[i+2][0] - point[i][0];
v2[1] = point[i+2][1] - point[i][1];
v2[2] = point[i+2][2] - point[i][2];
normalCoords[j++] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
normalCoords[j++] = -(v1[2] * v2[0]) - (v1[0] * v2[2]);
normalCoords[j++] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
// Normalize normals to unit length
float x = normalCoords[j-3];
float y = normalCoords[j-2];
float z = normalCoords[j-1];
float len = (float)(Math.sqrt((x*x)+(y*y)+(z*z)));
if(len == 0.0f)
len = 1.0f;
normalCoords[j-3] /= len;
normalCoords[j-2] /= len;
normalCoords[j-1] /= len;
i += 3;
}
}
}