Yo. I have next task: load heightmap and visualize it like a 3D object. Actually I already did it using simple GL_ARRAY_BUFFER and DrawArrays.
But my image totally has not any normals, or seems that all normals are the same. (Lighting is enabled). I tried example where was used glVertexAttribPointer, but i got fatal error when try assign color's data. Here is my 3 main functions. public void CreateBuffer(GL2 gl) // creating buffers with vertex and color data { this.gl=gl; targetsBuffer = Buffers.newDirectIntBuffer(2); gl.glGenBuffers(2, targetsBuffer); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, targetsBuffer.get(0)); gl.glBufferData(GL.GL_ARRAY_BUFFER, fBuff.capacity() * Buffers.SIZEOF_FLOAT, fBuff, GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, targetsBuffer.get(1)); gl.glBufferData(GL.GL_ARRAY_BUFFER, cBuff.capacity() * Buffers.SIZEOF_FLOAT, cBuff, GL.GL_STATIC_DRAW); // here I got exception (fatal error) CreateVAO(); } public void CreateVAO() // creating something that should help me to colorize my object { IntBuffer id = Buffers.newDirectIntBuffer(1); gl.glGenVertexArrays(1,id); gl.glBindVertexArray(id.get(0)); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, targetsBuffer.get(0)); gl.glVertexAttribPointer(0, 3, GL2.GL_FLOAT,false,0,0); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,targetsBuffer.get(1)); gl.glVertexAttribPointer(1, 3, GL2.GL_FLOAT,false,0,0); } @Override public void Draw(){ gl.glEnableVertexAttribArray(0); gl.glEnableVertexAttribArray(1); gl.glBindVertexArray(0); gl.glDrawArrays(GL2.GL_QUADS, 0, fBuff.capacity() / 3); gl.glDisableVertexAttribArray(0); gl.glDisableVertexAttribArray(1); } So what I do wrong? UPD: Actually I understood where is was 1 of my faults - i have to call rewind() for cBuff. And I had change Draw function to this public void Draw(){ gl.glBindVertexArray(1); gl.glEnableVertexAttribArray(0); gl.glEnableVertexAttribArray(1); gl.glDrawArrays(GL2.GL_QUADS, 0, fBuff.capacity() / 3); gl.glDisableVertexAttribArray(0); gl.glDisableVertexAttribArray(1); } Now I don't got exceptions, but I still don't see colors on my object. Here is function in which I initialize and filling the buffers. private void Import(String path) throws Exception { byte[] bytes = Files.readAllBytes(Paths.get(path)); int resolution = (int)Math.sqrt(bytes.length/4); float[] floats=new float[resolution*resolution]; ByteBuffer.wrap(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer().get(floats); this.heightStickLength=this.widthStickLength=resolution; this.heightScale=1; minHeight=Float.MAX_VALUE; maxHeight = Float.MIN_VALUE; for(int i = 0; i<floats.length; i++) { floats[i]=floats[i]*600f; } for(float f : floats) { if(f>maxHeight) maxHeight=f; if(f<minHeight) minHeight=f; } CreateColliderShape(floats); System.out.println("Max height: "+maxHeight+" Min height: "+minHeight); float step = 2000/513f; float optiStep=1; fBuff = Buffers.newDirectFloatBuffer(resolution*resolution*3*4/(int)optiStep); cBuff = Buffers.newDirectFloatBuffer(resolution*resolution*3*4/(int)optiStep); for(int i =0; i<resolution-1; i+=optiStep) { for(int j =0; j<resolution-1; j+=optiStep) { float x1=i*step,y1=floats[(j)*resolution+(resolution-1-i)],z1=j*step; float x2=i*step+step,y2=floats[(j)*resolution+(resolution-2-i)],z2=j*step; float x3=i*step+step,y3=floats[(j+1)*resolution+(resolution-2-i)],z3=j*step+step; float x4=i*step,y4=floats[(j+1)*resolution+(resolution-1-i)],z4=j*step+step; fBuff.put(x1); cBuff.put(1); fBuff.put(y1); cBuff.put(0); fBuff.put(z1); cBuff.put(0); fBuff.put(x2); cBuff.put(1); fBuff.put(y2); cBuff.put(0); fBuff.put(z2); cBuff.put(0); fBuff.put(x3); cBuff.put(1); fBuff.put(y3); cBuff.put(0); fBuff.put(z3); cBuff.put(0); fBuff.put(x4); cBuff.put(1); fBuff.put(y4); cBuff.put(0); fBuff.put(z4); cBuff.put(0); } } fBuff.rewind(); cBuff.rewind(); } |
Administrator
|
Hi
Why not looking at this example? http://jogamp.org/git/?p=jogl-demos.git;a=blob;f=src/demos/es2/RawGL2ES2demo.java;hb=HEAD Your source code is incomplete, maybe your object is simply not in the view frustum.
Julien Gouesse | Personal blog | Website
|
Now all right. Problem was in light position. It was (x,y,z,0), instead of (x,y,z,1) xD
|
In reply to this post by gouessej
No no no! I was wrong. I saw shape of the terrain just because my light was in point mode with light fading. And different parts of shape has different colours. But my normals still does not works.
In your example I see shaders and do not see any VBO and DrawArray call so I guess it useful for me. Now I changed my code to this. private void Import(String path) throws Exception { byte[] bytes = Files.readAllBytes(Paths.get(path)); int resolution = (int)Math.sqrt(bytes.length/4); float[] floats=new float[resolution*resolution]; ByteBuffer.wrap(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer().get(floats); this.heightStickLength=this.widthStickLength=resolution; this.heightScale=1; minHeight=Float.MAX_VALUE; maxHeight = Float.MIN_VALUE; for(int i = 0; i<floats.length; i++) { floats[i]=floats[i]*600f; } for(float f : floats) { if(f>maxHeight) maxHeight=f; if(f<minHeight) minHeight=f; } CreateColliderShape(floats); System.out.println("Max height: "+maxHeight+" Min height: "+minHeight); float step = 2000/513f; float optiStep=1; fBuff = Buffers.newDirectFloatBuffer(resolution*resolution*3*4/(int)optiStep); nBuff = Buffers.newDirectFloatBuffer(fBuff.capacity()/3); for(int i =0; i<resolution-1; i+=optiStep) { for(int j =0; j<resolution-1; j+=optiStep) { float x1=i*step,y1=floats[(j)*resolution+(resolution-1-i)],z1=j*step; float x2=i*step+step,y2=floats[(j)*resolution+(resolution-2-i)],z2=j*step; float x3=i*step+step,y3=floats[(j+1)*resolution+(resolution-2-i)],z3=j*step+step; float x4=i*step,y4=floats[(j+1)*resolution+(resolution-1-i)],z4=j*step+step; fBuff.put(x1); fBuff.put(y1); fBuff.put(z1); fBuff.put(x2); fBuff.put(y2); fBuff.put(z2); fBuff.put(x3); fBuff.put(y3); fBuff.put(z3); fBuff.put(x4); fBuff.put(y4); fBuff.put(z4); float n = 0.5f; nBuff.put(n); nBuff.put(n); nBuff.put(n); nBuff.put(n); } } fBuff.rewind(); nBuff.rewind(); } public void CreateBuffer(GL2 gl) { this.gl=gl; targetsBuffer = Buffers.newDirectIntBuffer(2); gl.glGenBuffers(2, targetsBuffer); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, targetsBuffer.get(0)); gl.glBufferData(GL.GL_ARRAY_BUFFER, fBuff.capacity() * Buffers.SIZEOF_FLOAT, fBuff, GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, targetsBuffer.get(1)); gl.glBufferData(GL.GL_ARRAY_BUFFER, nBuff.capacity() * Buffers.SIZEOF_FLOAT, nBuff, GL.GL_STATIC_DRAW); CreateVAO(); } public void CreateVAO() { IntBuffer id = Buffers.newDirectIntBuffer(1); gl.glGenVertexArrays(1,id); gl.glBindVertexArray(id.get(0)); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, targetsBuffer.get(0)); gl.glVertexAttribPointer(0, 3, GL2.GL_FLOAT,false,0,0); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,targetsBuffer.get(1)); gl.glVertexAttribPointer(1, 3, GL2.GL_FLOAT,false,0,0); } @Override public void Draw(){ gl.glEnable(GL2.GL_NORMALIZE); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, targetsBuffer.get(0)); gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0); gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,targetsBuffer.get(1)); gl.glNormalPointer(GL2.GL_FLOAT, 0, 0); gl.glDrawArrays(GL2.GL_QUADS, 0, fBuff.capacity()/3); } As you can see, I don't calculate any normals, just assign the same normal for each vertex. But it looks strange. Because normals did not assigned for some part of terrain. Watch screenshot please. http://puu.sh/g9eFY/54d10e7f98.png |
In reply to this post by Chaz
Man, i'm sorry for spending your time. My problem was in don't understanding some words in documentation, so after using some logic I realized, that something wrong in
gl.glNormalPointer(GL2.GL_FLOAT, 0, 0); so now I understand what is means - stride. Ahahah!!! With gl.glNormalPointer(GL2.GL_FLOAT, 4, 0); all looks nice! Going to calculate normals! |
i meant gl.glNormalPointer(GL2.GL_FLOAT, 3, 0); , not 4. xD
|
Administrator
|
The example calls glDrawArrays. I thought that you wanted to use VAO and now you call glNormalPointer :s
Julien Gouesse | Personal blog | Website
|
I just wanted to apply normals xD
One more question. I guess that normal - it is float number in range from 0 to 1, right? So how to calculate that float number? Because in google I see examples, where normal has Vector3 type. |
Administrator
|
You don't really understand what you do, you mix some methods of the fixed pipeline with some methods of the programmable pipeline. Using VAOs with glNormalPointer is nonsensical.
A normal should be normalized, i.e its norm should be equal to one. "google" doesn't have the answers to all questions. "For a convex polygon (such as a triangle), a surface normal can be calculated as the vector cross product of two (non-parallel) edges of the polygon" (see Wikipedia: https://en.wikipedia.org/wiki/Normal_%28geometry%29).
Julien Gouesse | Personal blog | Website
|
Actually now I don't use VAO. Forget to delete that method.
|
After thousand years...
Vector3f dest1=new Vector3f(); VectorUtil.sub(dest1,new Vector3f(x4,y4,z4),new Vector3f(x1,y1,z1)); Vector3f dest2=new Vector3f(); VectorUtil.sub(dest2,new Vector3f(x2,y2,z2),new Vector3f(x1,y1,z1)); float xn = (dest1.y*dest2.z)-(dest1.z*dest2.y); float yn = (dest1.z*dest2.x)-(dest1.x*dest2.z); float zn = (dest1.x*dest2.y)-(dest1.y*dest2.x); float n1 = (float)Math.sqrt(xn*xn+yn*yn+zn*zn); nBuff.put(xn/n1+yn/n1+zn/n1); VectorUtil.sub(dest1,new Vector3f(x1,y1,z1),new Vector3f(x2,y2,z2)); VectorUtil.sub(dest2,new Vector3f(x3,y3,z3),new Vector3f(x2,y2,z2)); xn = (dest1.y*dest2.z)-(dest1.z*dest2.y); yn = (dest1.z*dest2.x)-(dest1.x*dest2.z); zn = (dest1.x*dest2.y)-(dest1.y*dest2.x); n1 = (float)Math.sqrt(xn*xn+yn*yn+zn*zn); nBuff.put(xn/n1+yn/n1+zn/n1); VectorUtil.sub(dest1,new Vector3f(x2,y2,z2),new Vector3f(x3,y3,z3)); VectorUtil.sub(dest2,new Vector3f(x4,y4,z4),new Vector3f(x3,y3,z3)); xn = (dest1.y*dest2.z)-(dest1.z*dest2.y); yn = (dest1.z*dest2.x)-(dest1.x*dest2.z); zn = (dest1.x*dest2.y)-(dest1.y*dest2.x); n1 = (float)Math.sqrt(xn*xn+yn*yn+zn*zn); nBuff.put(xn/n1+yn/n1+zn/n1); VectorUtil.sub(dest1,new Vector3f(x3,y3,z3),new Vector3f(x4,y4,z4)); VectorUtil.sub(dest2,new Vector3f(x1,y1,z1),new Vector3f(x4,y4,z4)); xn = (dest1.y*dest2.z)-(dest1.z*dest2.y); yn = (dest1.z*dest2.x)-(dest1.x*dest2.z); zn = (dest1.x*dest2.y)-(dest1.y*dest2.x); n1 = (float)Math.sqrt(xn*xn+yn*yn+zn*zn); nBuff.put(xn/n1+yn/n1+zn/n1); |
Administrator
|
You could have called getNormalVec3 instead of reinventing the wheel.
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |