2012-02-07 4 views
2

Donc hier, j'ai écrit WaveFront .obj modèle 3D chargeur qui fonctionne maintenant bien (ne supporte pas tout tho) donc j'ai écrit un test simple pour dessiner un modèle 3D sur l'écran qui a bien fonctionné jusqu'à ce que j'ajoute éclairage à la scène. La lumière est apparue mais il semble que les normales soient toujours dans leur état par défaut. Je suis très sûr que dois-je utiliser comme cible lors de la génération des tampons (comme GL_NORMAL_ARRAY theres, GL_ARRAY_BUFFER etc.) pour que Normales je ne pouvais pas trouver un tutoriel à ce sujet en utilisant des objets tampons pour ceux:Android openGL ES normales

package com.Ruuhkis.opengl; 

import static javax.microedition.khronos.opengles.GL10.GL_COLOR_BUFFER_BIT; 
import static javax.microedition.khronos.opengles.GL10.GL_VERTEX_ARRAY; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import java.nio.ShortBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 
import javax.microedition.khronos.opengles.GL11; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.BitmapFactory.Options; 
import android.opengl.GLSurfaceView.Renderer; 
import android.opengl.GLU; 
import android.opengl.GLUtils; 
import android.util.Log; 

import com.Ruuhkis.opengl.model.Indices; 
import com.Ruuhkis.opengl.model.Loader; 
import com.Ruuhkis.opengl.model.Model; 
import com.Ruuhkis.opengl.model.Polygon; 
import com.Ruuhkis.opengl.model.Vertex; 

public class TextureRenderer implements Renderer { 

    private FloatBuffer vertexBuffer, normalBuffer; 
    private ShortBuffer indexBuffer; 
    private int attribVBO, attribIBO, attribNBO; 
    private Context context; 
    private float rotation = 0; 
    private float[] vertices = 
     {-0.8f, -0.8f, 0f, 
     0.8f, -0.8f, 0f, 
     0.8f, 0.8f, 0f, 
     -0.8f, 0.8f, 0f}; 

    private float[] normals = 
     {0f}; 

    private short[] indices = 
     {0, 3, 2, 
     0, 2, 1}; 

    public TextureRenderer(Context context) { 
     this.context = context; 

     Model model = Loader.loadModel(context.getAssets(), "test.txt"); 

     vertices = new float[model.getVerticeList().size() * 3]; 

     int i = 0; 

     for(Vertex v: model.getVerticeList()) { 
      vertices[i++] = v.getX(); 
      vertices[i++] = v.getY(); 
      vertices[i++] = v.getZ(); 
      //Log.v("vertice", v.toString() + " sa"); 
     } 

     i = 0; 

     indices = new short[model.getPolygonList().size() * 3]; 
     normals = new float[model.getPolygonList().size() * 3]; 

     for(Polygon p: model.getPolygonList()) { 
      for(Indices in: p.getIndiceList()) { 
       normals[i] = vertices[in.getNormalIndex()]; 
       indices[i++] = (short) in.getVertexIndex();   
      } 
     } 

     ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * 4); 
     buffer.order(ByteOrder.nativeOrder()); 
     vertexBuffer = buffer.asFloatBuffer(); 
     vertexBuffer.put(vertices); 
     vertexBuffer.flip(); 

     buffer = ByteBuffer.allocateDirect(normals.length * 4); 
     buffer.order(ByteOrder.nativeOrder()); 
     normalBuffer = buffer.asFloatBuffer(); 
     normalBuffer.put(normals); 
     normalBuffer.flip(); 

     buffer = ByteBuffer.allocateDirect(indices.length * 2); 
     buffer.order(ByteOrder.nativeOrder()); 
     indexBuffer = buffer.asShortBuffer(); 
     indexBuffer.put(indices); 
     indexBuffer.flip(); 


    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 

     gl.glColor4f(1f, 0f, 0f, 1f); 
     gl.glClear(GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

     gl.glLoadIdentity(); 
     gl.glPushMatrix(); 
     gl.glTranslatef(0f, 0f, -10f); 
     rotation += 1f; 
     gl.glRotatef(rotation, 1f, 1f, 0f); 
     gl.glEnableClientState(GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL11.GL_NORMAL_ARRAY); 

     GL11 gl11 = (GL11) gl; 

     gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, attribVBO); 
     gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, attribIBO); 
     gl11.glBindBuffer(GL11.GL_NORMAL_ARRAY, attribNBO); 
     gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0); 
     gl11.glNormalPointer(3, GL10.GL_FLOAT, 0); 
     gl11.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, 0); 

     gl.glDisableClientState(GL11.GL_NORMAL_ARRAY); 
     gl.glDisableClientState(GL_VERTEX_ARRAY); 
     gl.glPopMatrix(); 
     gl.glFlush(); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     gl.glViewport(0, 0, width, height); 
     gl.glMatrixMode(GL10.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     GLU.gluPerspective(gl, 45f, (float)width/(float)height, 1f, 100f); 
     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glEnable(GL10.GL_DEPTH_TEST); 
     //gl.glEnable(GL10.GL_LIGHTING); 
     gl.glEnable(GL10.GL_LIGHTING); 
     gl.glEnable(GL10.GL_LIGHT1); 
     gl.glEnable(GL10.GL_COLOR_MATERIAL); 
     gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, FloatBuffer.wrap(new float[]{0f, 0f, 0f, 1f})); 
     gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, FloatBuffer.wrap(new float[]{1f, 1f, 1f, 1f})); 
     gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_SPECULAR, FloatBuffer.wrap(new float[]{1f, 1f, 1f, 1f})); 

     gl.glMaterialfv(GL10.GL_FRONT, GL10.GL_SPECULAR, FloatBuffer.wrap(new float[]{1f, 1f, 1f, 1f})); 
     gl.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS,128f); 
     gl.glShadeModel(GL10.GL_SMOOTH); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     gl.glClearColor(0.8f, 0.8f, 0.8f, 1f); 
     GL11 gl11 = (GL11) gl; 
     int[] buffer = new int[1]; 
     gl11.glGenBuffers(1, buffer, 0); 
     attribVBO = buffer[0]; 
     gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, attribVBO); 
     gl11.glBufferData(GL11.GL_ARRAY_BUFFER, vertices.length * 4, vertexBuffer, GL11.GL_STATIC_DRAW); 
     gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, -1); 

     gl11.glGenBuffers(1, buffer, 0); 
     attribIBO = buffer[0]; 
     gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, attribIBO); 
     gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, indices.length * 2, indexBuffer, GL11.GL_STATIC_DRAW); 
     gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, -1); 

     gl11.glGenBuffers(1, buffer, 0); 
     attribNBO = buffer[0]; 
     gl11.glBindBuffer(GL11.GL_NORMAL_ARRAY, attribNBO); 
     gl11.glBufferData(GL11.GL_NORMAL_ARRAY, normals.length * 4, normalBuffer, GL11.GL_STATIC_DRAW); 
     gl11.glBindBuffer(GL11.GL_NORMAL_ARRAY, -1); 
    } 
} 

enter image description here

Ainsi, les normales par défaut sont 0, 0, -1 ou 0, 0, 1 et la caméra par défaut regarde -5, et comme le modèle tourne la lumière disparaît juste comme c'est quand il n'y a pas de normales, je J'ai quelque chose de similaire à ce travail avec un ordinateur, mais je n'ai pas utilisé de VBO etc, donc je ne peux pas comparer le code, je suis sûr qu'il ya quelque chose de mal à télécharger le tampon normal ou le lier! :(:(me aider

+0

Juste une petite estimation: les normales exportées sont-elles normalisées? Si non, les normalisez-vous à un moment donné (parce que je ne pourrais pas trouver la preuve de cela dans votre code après un coup d'oeil rapide)? – Erik

+0

Ouais, les normales sont exportées et chargées à partir du fichier .obj, j'ai aussi moi-même vérifié si les normales se chargeaient, et elles l'étaient. – Ruuhkis

+0

ce n'est pas ma question; Je suis sûr que vous chargez les objets normaux. Ce que je demande est: sont-ils normalisés? En d'autres termes: est leur longueur 1? Si ce n'est pas le cas, vous ne pouvez pas faire un éclairage correct. – Erik

Répondre

1

Pour expliquer mon commentaire sur votre question un peu plus loin:

ous devez vous assurer que vos Normales sont « normalisées », cela signifie que leur grandeur (longueur) doit être 1. Certains obj exportateurs font pour vous, mais c'est une bonne chose à faire vous-même

Cité de: http://www.fundza.com/vectors/normalize/index.html

Étant donné un vecteur « un » (ou « une » normale): un [3 1 2]. (Donc: ax = 3, ay = 1, az = 2)

La magnitude (leng th) du vecteur est: | a | = Sqrt ((hache * hache) + (ay * ay) + (az * az))

length = sqrt((ax * ax) + (ay * ay) + (az * az)) 
length = sqrt(9 + 1 + 4) = 3.742 

Normaliser vecteur "un" on divise par la longueur:

x = ax/|a|; 
y = ay/|a|; 
z = az/|a|; 

x = 3.0/3.742 = 0.802 
y = 1.0/3.742 = 0.267 
z = 2.0/3.742 = 0.534 

Vous devez appliquez ceci à vos normales avant vous créez votre tampon afin d'obtenir l'éclairage correct.

+0

Merci d'avoir expliqué cela et d'essayer, mais il semble que ce n'est pas le problème. J'utilise blender qui les normalise automatiquement. Et comme je l'ai indiqué sur mon commentaire sur votre post avant, leurs valeurs vont de -1 à ~ 1.2, juste pour s'assurer qu'ils sont normalisés. : P – Ruuhkis

+0

Cela ne peut pas être juste; la longueur doit être * exactement * 1 (pas -1, pas 1.2). Ou .. si vous voulez dire par "valeurs" les composants xyz alors c'est faux aussi. Les composants xyz peuvent être négatifs ou positifs, mais toujours entre -1 et 1. – Erik

+0

De toute façon, si vous êtes convaincu que vos normales sont correctes, vous devriez poster une image et expliquer ce qui ne va pas avec l'éclairage. J'essaie de t'aider mais tu ne me rends pas facile. – Erik