OMG THE FOOL I WAS
- Faces are now grouped by texture primitive they use - Massive FPS increase - TexturePrimitive receive an additional unique ID immediately upon instantiation
This commit is contained in:
parent
cd6e6d7d9c
commit
8977f460ca
@ -23,7 +23,7 @@ import java.util.Objects;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
|
||||
public class Face {
|
||||
public class Face implements Comparable<Face> {
|
||||
|
||||
private static final ShortBuffer GENERATE_SUCCESSIVE_LATER = null;
|
||||
|
||||
@ -240,4 +240,13 @@ public class Face {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Face o) {
|
||||
return Integer.compare(getSortingIndex(), o.getSortingIndex());
|
||||
}
|
||||
|
||||
public int getSortingIndex() {
|
||||
return texture == null ? -1 : texture.getSprite().getPrimitive().getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
package ru.windcorp.progressia.client.graphics.model;
|
||||
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
|
||||
|
||||
public class FaceGroup {
|
||||
|
||||
private final TexturePrimitive texture;
|
||||
private final int indexCount;
|
||||
private final int byteOffsetOfIndices;
|
||||
|
||||
FaceGroup(Face[] faces, int start, int end) {
|
||||
|
||||
Texture t = faces[start].getTexture();
|
||||
this.texture = t == null ? null : t.getSprite().getPrimitive();
|
||||
this.byteOffsetOfIndices = faces[start].getByteOffsetOfIndices();
|
||||
|
||||
int indexCount = 0;
|
||||
|
||||
for (int i = start; i < end; ++i) {
|
||||
Face face = faces[i];
|
||||
|
||||
assert this.texture == null
|
||||
? (face.getTexture() == null)
|
||||
: (face.getTexture().getSprite().getPrimitive() == this.texture);
|
||||
|
||||
indexCount += face.getIndexCount();
|
||||
}
|
||||
|
||||
this.indexCount = indexCount;
|
||||
}
|
||||
|
||||
public TexturePrimitive getTexture() {
|
||||
return this.texture;
|
||||
}
|
||||
|
||||
public int getIndexCount() {
|
||||
return this.indexCount;
|
||||
}
|
||||
|
||||
public int getByteOffsetOfIndices() {
|
||||
return this.byteOffsetOfIndices;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ package ru.windcorp.progressia.client.graphics.model;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
@ -31,6 +32,8 @@ public class Shape implements Renderable {
|
||||
private final Face[] faces;
|
||||
private final Usage usage;
|
||||
|
||||
private FaceGroup[] groups;
|
||||
|
||||
private ByteBuffer vertices;
|
||||
private ShortBuffer indices;
|
||||
|
||||
@ -61,6 +64,7 @@ public class Shape implements Renderable {
|
||||
private void assembleBuffers() {
|
||||
// TODO optimize: only update faces that requested it
|
||||
|
||||
sortFaces();
|
||||
resizeBuffers();
|
||||
|
||||
for (Face face : faces) {
|
||||
@ -72,6 +76,8 @@ public class Shape implements Renderable {
|
||||
this.vertices.flip();
|
||||
this.indices.flip();
|
||||
|
||||
assembleGroups();
|
||||
|
||||
needsAssembly = false;
|
||||
needsVBOUpdate = true;
|
||||
}
|
||||
@ -143,6 +149,51 @@ public class Shape implements Renderable {
|
||||
}
|
||||
}
|
||||
|
||||
private void sortFaces() {
|
||||
Arrays.sort(faces);
|
||||
}
|
||||
|
||||
private void assembleGroups() {
|
||||
int unique = countUniqueFaces();
|
||||
this.groups = new FaceGroup[unique];
|
||||
|
||||
if (faces.length == 0) return;
|
||||
|
||||
int previousHandle = faces[0].getSortingIndex();
|
||||
int start = 0;
|
||||
int groupIndex = 0;
|
||||
|
||||
for (int i = 1; i < faces.length; ++i) {
|
||||
if (previousHandle != faces[i].getSortingIndex()) {
|
||||
|
||||
groups[groupIndex] = new FaceGroup(faces, start, i);
|
||||
start = i;
|
||||
groupIndex++;
|
||||
|
||||
previousHandle = faces[i].getSortingIndex();
|
||||
}
|
||||
}
|
||||
|
||||
assert groupIndex == groups.length - 1;
|
||||
groups[groupIndex] = new FaceGroup(faces, start, faces.length);
|
||||
}
|
||||
|
||||
private int countUniqueFaces() {
|
||||
if (faces.length == 0) return 0;
|
||||
|
||||
int result = 1;
|
||||
int previousHandle = faces[0].getSortingIndex();
|
||||
|
||||
for (int i = 1; i < faces.length; ++i) {
|
||||
if (previousHandle != faces[i].getSortingIndex()) {
|
||||
result++;
|
||||
previousHandle = faces[i].getSortingIndex();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void markForReassembly() {
|
||||
needsAssembly = true;
|
||||
}
|
||||
@ -187,6 +238,10 @@ public class Shape implements Renderable {
|
||||
return faces;
|
||||
}
|
||||
|
||||
public FaceGroup[] getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public Usage getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
|
||||
import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.*;
|
||||
import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.*;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Sprite;
|
||||
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||
import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
|
||||
public class ShapeRenderProgram extends Program {
|
||||
@ -117,8 +117,8 @@ public class ShapeRenderProgram extends Program {
|
||||
|
||||
try {
|
||||
enableAttributes();
|
||||
for (Face face : shape.getFaces()) {
|
||||
renderFace(face);
|
||||
for (FaceGroup group : shape.getGroups()) {
|
||||
renderFaceGroup(group);
|
||||
}
|
||||
} finally {
|
||||
disableAttributes();
|
||||
@ -170,13 +170,11 @@ public class ShapeRenderProgram extends Program {
|
||||
indices.bind(BindTarget.ELEMENT_ARRAY);
|
||||
}
|
||||
|
||||
protected void renderFace(Face face) {
|
||||
Texture texture = face.getTexture();
|
||||
protected void renderFaceGroup(FaceGroup group) {
|
||||
TexturePrimitive texture = group.getTexture();
|
||||
|
||||
if (texture != null) {
|
||||
Sprite sprite = texture.getSprite();
|
||||
|
||||
sprite.getPrimitive().bind(0);
|
||||
texture.bind(0);
|
||||
textureSlotUniform.set(0);
|
||||
useTextureUniform.set(1);
|
||||
} else {
|
||||
@ -185,9 +183,9 @@ public class ShapeRenderProgram extends Program {
|
||||
|
||||
GL11.glDrawElements(
|
||||
GL11.GL_TRIANGLES,
|
||||
face.getIndexCount(),
|
||||
group.getIndexCount(),
|
||||
GL11.GL_UNSIGNED_SHORT,
|
||||
face.getByteOffsetOfIndices()
|
||||
group.getByteOffsetOfIndices()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,9 @@ public class TexturePrimitive implements OpenGLDeletable {
|
||||
Arrays.fill(currentlyBound, NOT_LOADED);
|
||||
}
|
||||
|
||||
private static int nextId = 0;
|
||||
|
||||
private int id = nextId++;
|
||||
private int handle = NOT_LOADED;
|
||||
private TextureData pixels;
|
||||
|
||||
@ -99,4 +102,9 @@ public class TexturePrimitive implements OpenGLDeletable {
|
||||
public int getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class WorldData {
|
||||
}
|
||||
|
||||
public void tmp_generate() {
|
||||
final int size = 2;
|
||||
final int size = 6;
|
||||
Vec3i cursor = new Vec3i(0, 0, 0);
|
||||
|
||||
for (cursor.x = -(size / 2); cursor.x <= (size / 2); ++cursor.x) {
|
||||
|
Reference in New Issue
Block a user