2012-02-07 14 views
2

昨日私はWaveFront .obj 3Dモデルローダーを作成しました。これは今ではうまくいきます(すべてサポートしていない)ので、3Dモデルを描画する簡単なテストを書きました。シーンへの照明。光が現れましたが、法線がまだデフォルト状態にあるようです。 Iバッファを生成するとき(GL_NORMAL_ARRAY、GL_ARRAY_BUFFERなどのtheresのように)私はそれらのためのバッファオブジェクトを使用して、それについてのチュートリアルを見つけることができなかったとして、私は法線のためのターゲットとして使用すべきか非常に不確かだ:Android OpenGL ES法線

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

したがって、デフォルトの法線は0,0,1または0,0,1で、デフォルトのカメラは-5を見ています。モデルが回転するにつれて、法線がない場合私はコードを比較することができないので、VBOなどを使用していないので、私はかなり正常なバッファをアップロードするか、それをバインドして何か間違っていると確信しています! :(私を助け:(

+0

エクスポートされた法線は正規化されていますか?そうでない場合は、ある時点で正規化していますか(すばやく確認した後でコード内にその証拠が見つかりませんでした)。 – Erik

+0

ええ、法線は.objファイルからエクスポートされ、ロードされます。また、法線がロードされているかどうかを確認しました。 – Ruuhkis

+0

これは私の質問ではありません。私はあなたがオブジェクトの法線をロードすると確信しています。私が求めているのは、彼らが正規化されているかどうかです。言い換えれば:彼らの長さは1ですか?そうでない場合は、正しい照明を行うことができません。 – Erik

答えて

1

さらに少しあなたの質問に私のコメントを説明するために:

OUには、あなたの法線は、「正規化」されていることを確認する必要があり、それは彼らの大きさ(長さ)が1一部でなければならないことを意味します! .OBJ輸出業者はあなたのためにこれを行う。それは、この自分を行うには良いことだ

より引用:ベクター ""(または通常の "A")を考えるとhttp://www.fundza.com/vectors/normalize/index.html

:[3 1 2]。 (So:ax = 3、ay = 1、az = 2)

大きさ(leng th)は、| a | = SQRT((斧*斧)+(AY * AY)+(AZ * AZ))

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

ベクトルを正規化するには、 "" 私たちは長さで割る:

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 

あなたがする必要があります正常な照明を得るために、の前にのバッファを作成してください。

+0

それを説明してくれてありがとう、それは問題のようではないようです。私はそれらを自動的に正規化するブレンダーを使用しています。以前の投稿に対する私のコメントについて述べたように、それらの値は-1から〜1.2までで、正規化されていることを確認しています。 :P – Ruuhkis

+0

それは正しいことはできません。長さは*正確に* 1でなければなりません(-1ではなく1.2ではありません)。または..あなたが "値"によってxyzコンポーネントを意味するならば、それは間違っています。 xyz成分は負または正でもかまいませんが、常に-1と1の間です。 – Erik

+0

とにかく、法線が正しいと確信している場合は、画像を掲示して、照明に何が問題なのかを説明する必要があります。私はあなたを助けようとしていますが、あなたはそれを簡単にはできません。 – Erik