我使用以下代码合并多个网格:
import java.util.ArrayList;
import java.util.Arrays;
import org.obsgolem.crystalia.gfx.Renderer;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import java.util.*;
public class MeshBatch
{
private final static VertexAttribute[] attributeConfig = new VertexAttribute[]{
new VertexAttribute(Usage.Position, 3, "a_position"),
new VertexAttribute(Usage.ColorPacked, 4, "a_color"),
new VertexAttribute(Usage.Normal, 3, "a_normal")};
private final static int VERTEX_SIZE = 3 + 1 + 3;
private Mesh m;
private List<Float> vertices = new ArrayList<Float>();
private List<Short> indices = new ArrayList<Short>();
public void addMesh(float[] vert, short[] ind)
{
int offset = (vertices.size() / VERTEX_SIZE);
//You have to throw an exception when you get over the limit of short indices
if (offset + vert.length / VERTEX_SIZE > Short.MAX_VALUE) {
throw new RuntimeException("blablabla");
}
for (short i : addOffset(ind, offset)) {
indices.add(i);
}
for (float v : vert) {
vertices.add(v);
}
}
public short[] addOffset(short[] ind, int offset)
{
short[] indarr = new short[ind.length];
for (int i = 0; i < ind.length; ++i) {
//Do you really need this check? You are the only one using this code
//so make sure that you never provide a null value. If you really want to have a chekc throw an exception instead
short value = ind[i];//ind[i] == null ? 0 : ind[i];
indarr[i] = (short) (value + offset);
}
return indarr;
}
public void end()
{
m = new Mesh(false, vertices.size(), indices.size(), attributeConfig);
m.setVertices(Renderer.makeFloatArray(vertices));
m.setIndices(Renderer.makeShortArray(indices));
}
public void render()
{
Renderer.getInstance().render(m);
}
}
然而,当我使用这个类画画时,我会发现奇怪的灯光效果。使用此网格,所有其他对象的光线更亮,而渲染的光线看起来更平坦。通过正常的方式(每个对象的单独网格),我得到了很好的平滑照明。这是我拍摄的两个截图:
使用合并网格:
没有合并网格:
导致此问题的原因是什么,它如何影响另一个网格的照明?我的顶点以正确的格式发送(顶点为3个浮点数,1为彩色,3为法线)。我的指数也在发挥作用。仅在实际渲染网格时才会出现此问题。没有它,照明效果很好。我认为问题与法线有关,但我无法弄清楚问题可能是什么。
编辑:我想我已解决了这个问题。当我将瓷砖从使用单独的网格切换到网格化时,照明固定了自己。怎么会发生这种情况?
答案 0 :(得分:0)
这对于question:
的Asker似乎很有效public static Mesh mergeMeshes(AbstractList<Mesh> meshes, AbstractList<Matrix4> transformations)
{
if(meshes.size() == 0) return null;
int vertexArrayTotalSize = 0;
int indexArrayTotalSize = 0;
VertexAttributes va = meshes.get(0).getVertexAttributes();
int vaA[] = new int [va.size()];
for(int i=0; i<va.size(); i++)
{
vaA[i] = va.get(i).usage;
}
for(int i=0; i<meshes.size(); i++)
{
Mesh mesh = meshes.get(i);
if(mesh.getVertexAttributes().size() != va.size())
{
meshes.set(i, copyMesh(mesh, true, false, vaA));
}
vertexArrayTotalSize += mesh.getNumVertices() * mesh.getVertexSize() / 4;
indexArrayTotalSize += mesh.getNumIndices();
}
final float vertices[] = new float[vertexArrayTotalSize];
final short indices[] = new short[indexArrayTotalSize];
int indexOffset = 0;
int vertexOffset = 0;
int vertexSizeOffset = 0;
int vertexSize = 0;
for(int i=0; i<meshes.size(); i++)
{
Mesh mesh = meshes.get(i);
int numIndices = mesh.getNumIndices();
int numVertices = mesh.getNumVertices();
vertexSize = mesh.getVertexSize() / 4;
int baseSize = numVertices * vertexSize;
VertexAttribute posAttr = mesh.getVertexAttribute(Usage.Position);
int offset = posAttr.offset / 4;
int numComponents = posAttr.numComponents;
{ //uzupelnianie tablicy indeksow
mesh.getIndices(indices, indexOffset);
for(int c = indexOffset; c < (indexOffset + numIndices); c++)
{
indices[c] += vertexOffset;
}
indexOffset += numIndices;
}
mesh.getVertices(0, baseSize, vertices, vertexSizeOffset);
Mesh.transform(transformations.get(i), vertices, vertexSize, offset, numComponents, vertexOffset, numVertices);
vertexOffset += numVertices;
vertexSizeOffset += baseSize;
}
Mesh result = new Mesh(true, vertexOffset, indices.length, meshes.get(0).getVertexAttributes());
result.setVertices(vertices);
result.setIndices(indices);
return result;
}
public static Mesh copyMesh(Mesh meshToCopy, boolean isStatic, boolean removeDuplicates, final int[] usage) {
// TODO move this to a copy constructor?
// TODO duplicate the buffers without double copying the data if possible.
// TODO perhaps move this code to JNI if it turns out being too slow.
final int vertexSize = meshToCopy.getVertexSize() / 4;
int numVertices = meshToCopy.getNumVertices();
float[] vertices = new float[numVertices * vertexSize];
meshToCopy.getVertices(0, vertices.length, vertices);
short[] checks = null;
VertexAttribute[] attrs = null;
int newVertexSize = 0;
if (usage != null) {
int size = 0;
int as = 0;
for (int i = 0; i < usage.length; i++)
if (meshToCopy.getVertexAttribute(usage[i]) != null) {
size += meshToCopy.getVertexAttribute(usage[i]).numComponents;
as++;
}
if (size > 0) {
attrs = new VertexAttribute[as];
checks = new short[size];
int idx = -1;
int ai = -1;
for (int i = 0; i < usage.length; i++) {
VertexAttribute a = meshToCopy.getVertexAttribute(usage[i]);
if (a == null)
continue;
for (int j = 0; j < a.numComponents; j++)
checks[++idx] = (short)(a.offset/4 + j);
attrs[++ai] = new VertexAttribute(a.usage, a.numComponents, a.alias);
newVertexSize += a.numComponents;
}
}
}
if (checks == null) {
checks = new short[vertexSize];
for (short i = 0; i < vertexSize; i++)
checks[i] = i;
newVertexSize = vertexSize;
}
int numIndices = meshToCopy.getNumIndices();
short[] indices = null;
if (numIndices > 0) {
indices = new short[numIndices];
meshToCopy.getIndices(indices);
if (removeDuplicates || newVertexSize != vertexSize) {
float[] tmp = new float[vertices.length];
int size = 0;
for (int i = 0; i < numIndices; i++) {
final int idx1 = indices[i] * vertexSize;
short newIndex = -1;
if (removeDuplicates) {
for (short j = 0; j < size && newIndex < 0; j++) {
final int idx2 = j*newVertexSize;
boolean found = true;
for (int k = 0; k < checks.length && found; k++) {
if (tmp[idx2+k] != vertices[idx1+checks[k]])
found = false;
}
if (found)
newIndex = j;
}
}
if (newIndex > 0)
indices[i] = newIndex;
else {
final int idx = size * newVertexSize;
for (int j = 0; j < checks.length; j++)
tmp[idx+j] = vertices[idx1+checks[j]];
indices[i] = (short)size;
size++;
}
}
vertices = tmp;
numVertices = size;
}
}
Mesh result;
if (attrs == null)
result = new Mesh(isStatic, numVertices, indices == null ? 0 : indices.length, meshToCopy.getVertexAttributes());
else
result = new Mesh(isStatic, numVertices, indices == null ? 0 : indices.length, attrs);
result.setVertices(vertices, 0, numVertices * newVertexSize);
result.setIndices(indices);
return result;
}