Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: OpenGL glDrawElements

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    6

    OpenGL glDrawElements

    Hello guys, first post here hopefully I can find some help.

    I am fairly new to opengl but I like it so far. I wrote a .obj parser and it works great if I use gl_drawArrays() which works great but if I use gl_drawElements() its all funky.... I get the feeling I am doing something incorrectly but I hope that someone here can help me figure out what i'm doing.

    Here is my parser and vbo setup code so far.

    Code :
    private void parseData(String data){
    			String[] lines = data.split("\n");
    			for (int i = 0; i < lines.length; i++) {
    				String l = lines[i];
    				if(l.startsWith("#")){
    					continue;
    				}
     
    				if(l.startsWith("v ")){
    					String[] verts = l.split("[ ]");
    					parseVertex(l, verts);
    					numberOfVertexAttributes++;
    					continue;
    				}
     
    				if(l.startsWith("vn ")){
    					String[] normals = l.split("[ ]");
    					parseNormals(l, normals);
    					numberOfNormalAttributes++;
    					continue;
    				}
     
    				if(l.startsWith("vt ")){
    					//String[] texture = l.split("[ ]+");
    					//nothing for now					
    					continue;
    				}
     
    				if(l.startsWith("f ")){
    					String[] faces = l.split("[ ]+");
    					parseFaces(l, faces);
    					faceIndex++;
    					if(faceIndex % 2 == 0)
    						numberOfFaces++;
    					continue;
    				}
    				}
    			}
     
    		private String load(int id){
    			String data = "";
    			try {
    			    InputStream is = context.getResources().openRawResource(id);
     
    				BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    				StringBuffer b = new StringBuffer();
    				String l = reader.readLine();
    					while(l != null){
    						b.append(l);
    						b.append("\n");
    						l = reader.readLine();
    					}
    				data = b.toString();
    				reader.close();
    				}catch(Exception ex){
    					Log.d("model loader load data", "exception "+ex);
    				}
    			return data;
    			}
     
     
    			private void parseVertex(String l, String[] vert){
    				String[] v = l.split("[ ]");
    				vertices.add(new vec3(Float.parseFloat(v[1]), Float.parseFloat(v[2]), Float.parseFloat(v[3])));
    			}
     
    			private void parseNormals(String l, String[] normal){
    				String[] n = l.split("[ ]");
    				normals.add(new vec3(Float.parseFloat(n[1]), Float.parseFloat(n[2]), Float.parseFloat(n[3])));
    			}
     
    			private void parseFaces(String s, String[] index){
    				String[] fi = s.split("[ ]");
     
    				String[] a = fi[1].split("[/]");		
    				String[] b = fi[2].split("[/]");
    				String[] c = fi[3].split("[/]");				
     
    				indices.add(new vec3(Integer.parseInt(a[0]), Integer.parseInt(b[0]), Integer.parseInt(c[0])));
    				faces.add(new face(Integer.parseInt(a[0]), Integer.parseInt(b[0]), Integer.parseInt(c[0]), Integer.parseInt(a[2])));
    				numberOfVertices+=3;
    				numberOfFacesAttributes++;
    			}
     
    	private class vec3{
    		float x, y, z;
     
    		public vec3(float x, float y, float z){
    			this.x = x;
    			this.y = y;
    			this.z = z;
    		}
     
    		@SuppressWarnings("unused")
    		public String printout(){
    			return "x "+this.x+" y "+this.y+" z "+this.z;
    		}
    	}
     
    	private class face{
    		int[] data;
     
    		public face(int v1, int v2, int v3, int n1){
    			data = new int[6];
    			data[0] = v1;
    			data[1] = v2;
    			data[2] = v3;
     
    			data[3] = n1;
    		}
     
    	}

    here is how i setup my vbo
    Code :
     
    vertexArray = new float[numberOfFacesAttributes*9];
    		normalArray = new float[numberOfFacesAttributes*9];
    		indexArray =  new short[numberOfFacesAttributes*3];
     
    		int va = 0;
    		int ia = 0;
    		int na = 0;
    		//System.out.println(numberOfFacesAttributes);
    		for(int i = 0; i < numberOfFacesAttributes; i++){
     
    			vertexArray[va++] = vertices.get((faces.get(i).data[0]-1)).x;
    			vertexArray[va++] = vertices.get((faces.get(i).data[0]-1)).y;
    			vertexArray[va++] = vertices.get((faces.get(i).data[0]-1)).z;
     
    			vertexArray[va++] = vertices.get((faces.get(i).data[1]-1)).x;
    			vertexArray[va++] = vertices.get((faces.get(i).data[1]-1)).y;
    			vertexArray[va++] = vertices.get((faces.get(i).data[1]-1)).z;
     
    			vertexArray[va++] = vertices.get((faces.get(i).data[2]-1)).x;
    			vertexArray[va++] = vertices.get((faces.get(i).data[2]-1)).y;
    			vertexArray[va++] = vertices.get((faces.get(i).data[2]-1)).z;
     
     
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).x;
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).y;
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).z;
     
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).x;
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).y;
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).z;
     
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).x;
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).y;
    			normalArray[na++] = normals.get((faces.get(i).data[3]-1)).z;
     
     
    			indexArray[ia++] = (short) (faces.get(i).data[0]);
    			indexArray[ia++] = (short) (faces.get(i).data[1]);
    			indexArray[ia++] = (short) (faces.get(i).data[2]);
    		}

    if I use gl_drawArrays() and use the vertex arrays I get a nice drawing, if i use gl_drawElements i get really terrible rendering.
    See videos below, i really appreciate you guys help.

    cube rendered with gl_drawarrays() : http://www.youtube.com/watch?v=c78Rr5IawzE&feature=plcp
    same model drawn gl_drawelements() : http://www.youtube.com/watch?v=Kn9gAo-5K8g&feature=plcp

    monkey with per fragment lighting gl_drawarrays() : http://www.youtube.com/watch?v=yOq_paczs8g&feature=plcp
    same monkey no lighting gl_drawelements() : http://www.youtube.com/watch?v=SDeJk7sv2ZA&feature=plcp

  2. #2
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,421
    Verify your indices. Make sure they start at 0.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  3. #3
    Junior Member Newbie
    Join Date
    Oct 2008
    Posts
    9
    Post your code on how you bound the data (glBufferData) and when you call you call glDrawElements. I've had problems where I've passed in the wrong values in the arguments.

  4. #4
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    6
    V-man i indeed start the indexing at zero

    mrmoo

    Code :
    private FloatBuffer vertsBuffer;
    private ShortBuffer indicesBuffer;
     
    l = new OBJLoader(c);
    l.load(R.raw.cu);
    verts = l.vertexArray; 
    index = l.indexArray;
    number = l.numVertices;
     
    vertsBuffer = ByteBuffer.allocateDirect(verts.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    		vertsBuffer.put(verts).position(0);
     
    		indicesBuffer = ByteBuffer.allocateDirect(index.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
    		indicesBuffer.put(index).position(0);
     
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     
    		GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    		final float eyeX = 0.0f;
    		final float eyeY = 0.0f;
    		final float eyeZ = 0.0f;
    		final float centerX = 0.0f;
    		final float centerY = 0.0f;
    		final float centerZ = -1.0f;
    		final float upX = 0.0f;
    		final float upY = 1.0f;
    		final float upZ = 0.0f;
    		Matrix.setLookAtM(viewMatrix, 0, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
    		Matrix.translateM(viewMatrix, 0, 0.0f, 0.0f, -4.0f);
     
     
     
    		vShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    		GLES20.glShaderSource(vShader, vCode);
    		GLES20.glCompileShader(vShader);
     
    		fShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    		GLES20.glShaderSource(fShader, fCode);
    		GLES20.glCompileShader(fShader);
     
    		sProgram = GLES20.glCreateProgram();
    		GLES20.glAttachShader(sProgram, vShader);
    		GLES20.glAttachShader(sProgram, fShader);
    		GLES20.glLinkProgram(sProgram);
     
    	}
    public void onSurfaceChanged(GL10 gl, int width, int height) {
    		GLES20.glViewport(0, 0, width, height);
     
    		final float ratio = (float)width/height;
    		final float left = -ratio;
    		final float right = ratio;
    		final float bottom = -1.0f;
    		final float top = 1.0f;
    		final float near = 1.0f;
    		final float far = 100.0f;
    		Matrix.frustumM(projMatrix, 0, left, right, bottom, top, near, far);
    	}
     
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    	    GLES20.glUseProgram(sProgram);
     
     
    	    long time = SystemClock.uptimeMillis() % 10000L;
            float angleInDegrees = (360.0f / 10000.0f) * ((int) time);
     
     
    	    Matrix.setIdentityM(modelMatrix, 0);
    	    Matrix.rotateM(modelMatrix, 0, angleInDegrees, 0.0f, 1.0f, 0.0f);
     
    	    vertsBuffer.position(0);
    		GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(sProgram, "aPos"));
    		GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(sProgram, "aPos"), 3, GLES20.GL_FLOAT, false, 0, vertsBuffer);
     
    		GLES20.glVertexAttrib4f(GLES20.glGetAttribLocation(sProgram, "aCol"), 1.0f, 1.0f, 0.0f, 1.0f);
     
    		Matrix.multiplyMM(modViewProjMatrix, 0, viewMatrix, 0, modelMatrix, 0);
    		Matrix.multiplyMM(modViewProjMatrix, 0, projMatrix, 0, modViewProjMatrix, 0);
     
    		GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(sProgram, "uMVPMat"), 1, false, modViewProjMatrix, 0);
     
    		//GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, number);
    		GLES20.glDrawElements(GLES20.GL_LINE_LOOP, number, GLES20.GL_UNSIGNED_SHORT, indicesBuffer);
     
    private final String vCode = 
    			 "uniform mat4 uMVPMat;              \n"
    			+"uniform mat4 uMVMat;               \n"
    			+"attribute vec3 aPos;        \n"
    			+"attribute vec4 aCol;       \n"
    			+"varying vec4 vCol;         \n"
    			+"void main(){               \n"
    			+" vCol = aCol;              \n"
    			+" gl_Position = uMVPMat * vec4(aPos, 1.0); \n"
    			+"}                          \n";
     
    	private final String fCode =
    			"precision mediump float;    \n"
    			+"varying vec4 vCol;         \n"
    			+"void main(){               \n"
    			+"gl_FragColor = vCol;       \n"
    			+"}                          \n";
     
    	}

  5. #5
    Junior Member Newbie
    Join Date
    Oct 2008
    Posts
    9
    As this is OpenGL ES, I don't know all the idiosyncrasies but I do see something that might be the problem. When you call glDrawElements, the second arg (count) needs to be the number of indices, not the number of vertices.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •