2012-02-07 2 views
2

어제 나는 WaveFront .obj 3D 모델 로더를 작성했는데, 이제는 잘 작동한다. (모든 것을 지원하지는 않는다.) 그래서 나는 추가 할 때까지 모든 3D 모델을 화면에 그리는 간단한 테스트를 작성했다. 조명 장면. 빛이 나타나지만 법선이 여전히 기본 상태에있는 것처럼 보입니다.안드로이드 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

을 : 나는 법선을 위해 (GL_NORMAL_ARRAY, GL_ARRAY_BUFFER 등을 프로그래머로)는 사람들을 위해 버퍼 오브젝트를 사용하는 방법에 대해 내가 어떤 자습서를 찾을 수 없습니다로 버퍼를 생성 할 때 내가 대상으로 무엇을 사용해야 매우 확실하지 오전

그래서 기본 법선은 0, 0, -1 또는 0, 0, 1이며 기본 카메라는 -5를 보게됩니다. 모델이 회전 할 때 조명은 그냥 법선이없는 것처럼 사라집니다. 컴퓨터에서이 작업과 비슷한 것을 얻었지만 VBO 등을 사용하지 않았으므로 코드를 비교할 수 없으므로 일반 버퍼를 업로드하거나 바인딩 할 때 오류가 있다고 확신합니다! 도와 :(:(

+0

빠른 추측 : 내 보낸 법선이 정규화 되었습니까? 그렇지 않다면 언젠가는 정상화합니까 (잠깐 살펴본 후 코드에서 그 증거를 찾을 수 없었기 때문에)? – Erik

+0

그래, 법선은 .obj 파일에서 내보내지고로드됩니다. 또한 법선이로드되는지 확인했습니다. 내 질문이 아닌 – Ruuhkis

+0

; 객체 법선을로드해야합니다. 내가 묻는 것은 그들이 정규화 된 것인가? 다른 말로하면 : 길이가 1입니까? 그렇지 않은 경우 정확한 조명을 할 수 없습니다. – Erik

답변

1

이 조금 더 귀하의 질문에 내 의견을 설명하려면!

ou는 당신의 법선은 "정상화"되어 있는지 확인해야을, 즉 자신의 크기 (길이) 1. 일부가 될해야 함을 의미 .OBJ 수출은 당신을 위해이 작업을 수행,하지만이 스스로 할 수있는 좋은 일

에서 인용 : 벡터 "A"(또는 보통의 "A")을 감안할 때 http://www.fundza.com/vectors/normalize/index.html

: A [3 1 2]. (그래서 : ax = 3, ay = 1, az = 2)

크기 (leng th)는 | a | = SQRT ((도끼 * 도끼) + (AY * 님) + (AZ * AZ))

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

하는 벡터를 정상화하려면 "A는"우리가 길이에 의해 분할 :

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