Итак, вчера я написал загрузчик 3D-моделей WaveFront .obj, который теперь отлично работает (не поддерживает все tho), поэтому я написал простой тест, чтобы нарисовать любую 3D-модель на экране, которая все работала нормально, пока я не добавлял освещение на сцене. Появился свет, но, похоже, нормали все еще находятся в состоянии по умолчанию. Я очень не уверен, что я должен использовать в качестве цели при создании буферов (как Theres GL_NORMAL_ARRAY, GL_ARRAY_BUFFER и т.д.) для нормалей, как я не мог найти любой учебник о том, что с помощью объектов буфера для тех, кто:Android openGL ES normals
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);
}
}
, так что нормальные значения по умолчанию: 0, 0, -1 или 0, 0, 1, а камера по умолчанию смотрит на -5, а по мере того, как модель вращается, свет просто уходит, как и когда нет нормалей, я «У меня есть что-то похожее на эту работу с компьютером, но я не использовал VBOs и т. д., поэтому я не могу сравнивать код, я уверен, что что-то не так с загрузкой обычного буфера или привязкой к нему! :(помогите мне :(
Просто быстрая догадка: нормализованные нормализованные нормали? Если нет, нормализуете ли вы их в какой-то момент (потому что я не смог найти доказательства этого в вашем коде после быстрого взгляда)? – Erik
Да, нормали экспортируются и загружаются из файла .obj, я сам сам проверяю, загружали ли нормали, и они были. – Ruuhkis
это не мой вопрос; Я уверен, что вы загружаете нормали объектов. Я спрашиваю: нормализуются ли они? Другими словами: их длина 1? Если это не так, вы не можете сделать правильное освещение. – Erik