diff options
author | makamys <makamys@outlook.com> | 2022-06-09 20:29:59 +0200 |
---|---|---|
committer | makamys <makamys@outlook.com> | 2022-06-10 19:20:56 +0200 |
commit | 5ef1149341554fa51cf852d78ef8e9963c248152 (patch) | |
tree | d02adf449bec5964e4dbbd6db301c74d187ed115 | |
parent | bed1d48eff24795c52465d10c81ace37823e2d16 (diff) | |
download | Neodymium-5ef1149341554fa51cf852d78ef8e9963c248152.tar.gz Neodymium-5ef1149341554fa51cf852d78ef8e9963c248152.tar.bz2 Neodymium-5ef1149341554fa51cf852d78ef8e9963c248152.zip |
mesh simplification WIP
3 files changed, 118 insertions, 349 deletions
diff --git a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java index d58f5b8..958b941 100644 --- a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java +++ b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java @@ -61,8 +61,7 @@ public class ChunkMesh extends Mesh { this.quadCount = quadCount; this.pass = pass; - NBTBase nbtData = toNBT(quads, quadCount); - buffer = createBuffer(((NBTTagByteArray)nbtData).func_150292_c(), nameList); + buffer = createBuffer(quads, quadCount); usedRAM += buffer.limit(); instances++; } @@ -89,18 +88,18 @@ public class ChunkMesh extends Mesh { ChunkMesh.Flags flags = new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals); - if(optimize) { + if(true) { List<MeshQuad> quads = new ArrayList<>(); for(int quadI = 0; quadI < t.vertexCount / 4; quadI++) { - MeshQuad quad = new MeshQuad(t.rawBuffer, quadI * 32, flags, tessellatorXOffset, tessellatorYOffset, tessellatorZOffset); + MeshQuad quad = new MeshQuad(t.rawBuffer, quadI * 32, flags, wr.posX, wr.posY, wr.posZ); //if(quad.bUs[0] == quad.bUs[1] && quad.bUs[1] == quad.bUs[2] && quad.bUs[2] == quad.bUs[3] && quad.bUs[3] == quad.bVs[0] && quad.bVs[0] == quad.bVs[1] && quad.bVs[1] == quad.bVs[2] && quad.bVs[2] == quad.bVs[3] && quad.bVs[3] == 0) { // quad.deleted = true; //} - if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) { + /*if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) { // water hack quad.deleted = true; - } + }*/ quads.add(quad); } @@ -196,6 +195,8 @@ public class ChunkMesh extends Mesh { int color = t.rawBuffer[i + 5]; out.writeInt(color); + //System.out.println("[" + vertexI + "] x: " + x + ", y: " + y + " z: " + z + ", u: " + u + ", v: " + v + ", b: " + brightness + ", c: " + color); + i += 8; } } @@ -231,20 +232,21 @@ public class ChunkMesh extends Mesh { return quadCount; } - private NBTBase toNBT(List<? extends MeshQuad> quads, int quadCount) { - ByteArrayOutputStream byteOut = new ByteArrayOutputStream(quadCount * (2 + 4 * (3 + 2 + 2 + 4))); - DataOutputStream out = new DataOutputStream(byteOut); + private ByteBuffer createBuffer(List<? extends MeshQuad> quads, int quadCount) { + ByteBuffer buffer = BufferUtils.createByteBuffer(quadCount * 6 * 7 * 4); + BufferWriter out = new BufferWriter(buffer); + try { - for(int pass = 0; pass <= 9; pass++){ - for(MeshQuad quad : quads) { - quad.writeToDisk(out, pass); - } + for(MeshQuad quad : quads) { + quad.writeToBuffer(out); } - } catch(IOException e) {} + } catch(IOException e) { + e.printStackTrace(); + } + - NBTTagByteArray arr = new NBTTagByteArray(byteOut.toByteArray()); - usedRAM += arr.func_150292_c().length; - return arr; + buffer.flip(); + return buffer; } void destroy() { @@ -263,74 +265,6 @@ public class ChunkMesh extends Mesh { public void destroyBuffer() { destroy(); } - - private ByteBuffer createBuffer(byte[] data, List<String> stringTable) { - if(!(flags.hasTexture && flags.hasColor && flags.hasBrightness && !flags.hasNormals)) { - // for simplicity's sake we just assume this setup - System.out.println("invalid mesh properties, expected a chunk"); - return null; - } - int coordsOffset = quadCount * 2; - int textureOffset = quadCount * (2 + 4 + 4 + 4); - int brightnessOffset = quadCount * (2 + 4 + 4 + 4 + 4 + 4); - int colorOffset = quadCount * (2 + 4 + 4 + 4 + 4 + 4 + 4 + 4); - - ByteBuffer buffer = BufferUtils.createByteBuffer(quadCount * 6 * getStride()); - FloatBuffer floatBuffer = buffer.asFloatBuffer(); - ShortBuffer shortBuffer = buffer.asShortBuffer(); - IntBuffer intBuffer = buffer.asIntBuffer(); - - try { - for(int quadI = 0; quadI < quadCount; quadI++) { - short spriteIndex = readShortAt(data, quadI * 2); - String spriteName = stringTable.get(spriteIndex); - - TextureAtlasSprite tas = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).getAtlasSprite(spriteName); - - for (int vertexNum = 0; vertexNum < 6; vertexNum++) { - int vi = new int[]{0, 1, 3, 1, 2, 3}[vertexNum]; - int vertexI = 4 * quadI + vi; - int offset = vertexI * getStride(); - int simpleX = Byte.toUnsignedInt(data[coordsOffset + 0 * 4 * quadCount + 4 * quadI + vi]); - if(simpleX == 255) simpleX = 256; - int simpleY = Byte.toUnsignedInt(data[coordsOffset + 1 * 4 * quadCount + 4 * quadI + vi]); - if(simpleY == 255) simpleY = 256; - int simpleZ = Byte.toUnsignedInt(data[coordsOffset + 2 * 4 * quadCount + 4 * quadI + vi]); - if(simpleZ == 255) simpleZ = 256; - floatBuffer.put(x * 16 + simpleX / 16f); // x - floatBuffer.put(y * 16 + simpleY / 16f); // y - floatBuffer.put(z * 16 + simpleZ / 16f); // z - - byte relU = data[textureOffset + 0 * 4 * quadCount + 4 * quadI + vi]; - byte relV = data[textureOffset + 1 * 4 * quadCount + 4 * quadI + vi]; - - floatBuffer.put(tas.getMinU() + (tas.getMaxU() - tas.getMinU()) * (relU / 16f)); // u - floatBuffer.put(tas.getMinV() + (tas.getMaxV() - tas.getMinV()) * (relV / 16f)); // v - - shortBuffer.position(floatBuffer.position() * 2); - - shortBuffer.put((short)Byte.toUnsignedInt(data[brightnessOffset + 0 * 4 * quadCount + 4 * quadI + vi])); // bU - shortBuffer.put((short)Byte.toUnsignedInt(data[brightnessOffset + 1 * 4 * quadCount + 4 * quadI + vi])); // bV - - intBuffer.position(shortBuffer.position() / 2); - - int integet = readIntAt(data, colorOffset + 4 * 4 * quadI + 4 * vi); - intBuffer.put(integet); // c - - floatBuffer.position(intBuffer.position()); - } - } - } catch(Exception e) { - e.printStackTrace(); - } - - buffer.position(floatBuffer.position() * 4); - buffer.flip(); - - usedRAM += buffer.limit(); - - return buffer; - } public void update() { } diff --git a/src/main/java/makamys/neodymium/renderer/MeshQuad.java b/src/main/java/makamys/neodymium/renderer/MeshQuad.java index f0f7b41..42d07f8 100644 --- a/src/main/java/makamys/neodymium/renderer/MeshQuad.java +++ b/src/main/java/makamys/neodymium/renderer/MeshQuad.java @@ -6,33 +6,30 @@ import java.util.Comparator; import java.util.Locale; import java.util.Map; +import makamys.neodymium.util.BufferWriter; import makamys.neodymium.util.SpriteUtil; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.util.EnumFacing; public class MeshQuad { - public int spriteIndex; - public String spriteName; - public int[] xs = new int[4]; - public int[] ys = new int[4]; - public int[] zs = new int[4]; - public int baseX = -1, baseY, baseZ; - public int minX = Integer.MAX_VALUE; - public int minY = Integer.MAX_VALUE; - public int minZ = Integer.MAX_VALUE; - public int maxX = Integer.MIN_VALUE; - public int maxY = Integer.MIN_VALUE; - public int maxZ = Integer.MIN_VALUE; - public int[] relUs = new int[4]; - public int[] relVs = new int[4]; - public int[] bUs = new int[4]; - public int[] bVs = new int[4]; + public float[] xs = new float[4]; + public float[] ys = new float[4]; + public float[] zs = new float[4]; + public float minX = Float.POSITIVE_INFINITY; + public float minY = Float.POSITIVE_INFINITY; + public float minZ = Float.POSITIVE_INFINITY; + public float maxX = Float.NEGATIVE_INFINITY; + public float maxY = Float.NEGATIVE_INFINITY; + public float maxZ = Float.NEGATIVE_INFINITY; + public float[] us = new float[4]; + public float[] vs = new float[4]; + public int[] bs = new int[4]; public int[] cs = new int[4]; - public int[] normals = new int[4]; + // TODO normals? public boolean deleted; - public boolean isFullQuad; public static final int PLANE_NONE = -1, PLANE_XY = 0, PLANE_XZ = 1, PLANE_YZ = 2; public int plane = PLANE_NONE; @@ -56,89 +53,26 @@ public class MeshQuad { } } - public MeshQuad(int[] rawBuffer, int offset, ChunkMesh.Flags flags, int offsetX, int offsetY, int offsetZ) { - this.offset = offset; - this.flags = flags; - int i = offset; - float[] us = new float[4]; - float uSum = 0; - float[] vs = new float[4]; - float vSum = 0; - for(int vertexI = 0; vertexI < 4; vertexI++) { - float u = Float.intBitsToFloat(rawBuffer[vertexI * 8 + i + 3]); - float v = Float.intBitsToFloat(rawBuffer[vertexI * 8 + i + 4]); + private void read(int[] rawBuffer, int offset, int offsetX, int offsetY, int offsetZ) { + for(int vi = 0; vi < 4; vi++) { + int i = offset + vi * 8; - us[vertexI] = u; - vs[vertexI] = v; + xs[vi] = Float.intBitsToFloat(rawBuffer[i + 0]) + offsetX; + ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY; + zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ; - uSum += u; - vSum += v; - } - - float avgU = uSum / 4f; - float avgV = vSum / 4f; - - TextureAtlasSprite sprite = null; - Map<String, TextureAtlasSprite> uploadedSprites = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites; - - spriteIndex = SpriteUtil.getSpriteIndexForUV(avgU, avgV); - sprite = SpriteUtil.getSprite(spriteIndex); - - if(sprite == null) { - System.out.println("Error: couldn't find sprite"); - } else { - spriteName = sprite.getIconName(); - for(int vertexI = 0; vertexI < 4; vertexI++) { - float x = Float.intBitsToFloat(rawBuffer[i + 0]) - offsetX; - float y = Float.intBitsToFloat(rawBuffer[i + 1]) - offsetY; - float z = Float.intBitsToFloat(rawBuffer[i + 2]) - offsetZ; - - int simpleX = (int)(x * 16); - //if(simpleX == 256) simpleX = 255; - int simpleY = (int)(y * 16); - //if(simpleY == 256) simpleY = 255; - int simpleZ = (int)(z * 16); - //if(simpleZ == 256) simpleZ = 255; - - xs[vertexI] = simpleX; - ys[vertexI] = simpleY; - zs[vertexI] = simpleZ; - - // hasTexture - float u = us[vertexI]; - float v = vs[vertexI]; - - int simpleRelU = (int)((u - sprite.getMinU()) / (sprite.getMaxU() - sprite.getMinU()) * 16); - int simpleRelV = (int)((v - sprite.getMinV()) / (sprite.getMaxV() - sprite.getMinV()) * 16); - if(flags.hasTexture) { - relUs[vertexI] = simpleRelU; - relVs[vertexI] = simpleRelV; - } - - // hasBrightness - int brightness = rawBuffer[i + 7]; - int brightnessU = brightness & 0xFFFF; - int brightnessV = (brightness >> 16) & 0xFFFF; - if(flags.hasBrightness) { - bUs[vertexI] = (int)brightnessU; - bVs[vertexI] = (int)brightnessV; - } - - // hasColor - int color = rawBuffer[i + 5]; - if(flags.hasColor) { - cs[vertexI] = color; - } - - // hasNormals - int normal = rawBuffer[i + 6]; - if(flags.hasNormals) { - normals[vertexI] = normal; - } - - i += 8; - } + us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]); + vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]); + + bs[vi] = rawBuffer[i + 7]; + cs[vi] = rawBuffer[i + 5]; + + i += 8; } + } + + public MeshQuad(int[] rawBuffer, int offset, ChunkMesh.Flags flags, int offsetX, int offsetY, int offsetZ) { + read(rawBuffer, offset, offsetX, offsetY, offsetZ); updateMinMaxXYZ(); @@ -151,68 +85,78 @@ public class MeshQuad { } else { plane = PLANE_NONE; } - - boolean equalToAABB = true; - for(int minOrMaxX = 0; minOrMaxX < 2; minOrMaxX++) { - for(int minOrMaxY = 0; minOrMaxY < 2; minOrMaxY++) { - for(int minOrMaxZ = 0; minOrMaxZ < 2; minOrMaxZ++) { - if(getCornerVertex(minOrMaxX == 1, minOrMaxY == 1, minOrMaxZ == 1) == -1) { - equalToAABB = false; - break; - } - } - } - } - - switch(plane) { - case PLANE_XY: - isFullQuad = equalToAABB && (maxX - minX) == 16 && (maxY - minY) == 16; - break; - case PLANE_XZ: - isFullQuad = equalToAABB && (maxX - minX) == 16 && (maxZ - minZ) == 16; - break; - case PLANE_YZ: - isFullQuad = equalToAABB && (maxY - minY) == 16 && (maxZ - minZ) == 16; - break; - default: - isFullQuad = false; + } + + public void writeToBuffer(BufferWriter out) throws IOException { + for(int vertexI = 0; vertexI < 6; vertexI++) { + int vi = new int[]{0, 1, 2, 0, 2, 3}[vertexI]; + + float x = xs[vi]; + float y = ys[vi]; + float z = zs[vi]; + + out.writeFloat(x); + out.writeFloat(y); + out.writeFloat(z); + + float u = us[vi]; + float v = vs[vi]; + + out.writeFloat(u); + out.writeFloat(v); + + int b = bs[vi]; + + out.writeInt(b); + + int c = cs[vi]; + + out.writeInt(c); + + //System.out.println("[" + vertexI + "] x: " + x + ", y: " + y + " z: " + z + ", u: " + u + ", v: " + v + ", b: " + b + ", c: " + c); } + } + + private boolean isTranslatedCopyOf(MeshQuad o) { + if(!isValid(this) || !isValid(o) || plane != o.plane) return false; - for(int c = 0; c < 3; c++) { - if(getMin(c) < 0 || getMax(c) < 0 || getMax(c) - getMin(c) > 16 || getMin(c) > 256 || getMax(c) > 256) { - this.deleted = true; - // TODO handle weirdness more gracefully + for(int i = 1; i < 4; i++) { + double relX = xs[i] - xs[0]; + double relY = xs[i] - xs[0]; + double relZ = xs[i] - xs[0]; + + if(o.xs[i] != o.xs[0] + relX || o.ys[i] != o.ys[0] + relY || o.zs[i] != o.zs[0] + relZ) { + return false; } } - } - - // yeah this is kinda unoptimal - private int getCornerVertex(boolean minOrMaxX, boolean minOrMaxY, boolean minOrMaxZ) { - int aabbCornerX = !minOrMaxX ? minX : maxX; - int aabbCornerY = !minOrMaxY ? minY : maxY; - int aabbCornerZ = !minOrMaxZ ? minZ : maxZ; - for(int vi = 0; vi < 4; vi++) { - if(xs[vi] == aabbCornerX && ys[vi] == aabbCornerY && zs[vi] == aabbCornerZ) { - return vi; + for(int i = 0; i < 4; i++) { + if(us[i] != o.us[i] || vs[i] != o.vs[i] || bs[i] != o.bs[i] || cs[i] != o.cs[i]) { + return false; } } - return -1; + + return true; } public void tryToMerge(MeshQuad o) { - if(isValid(this) && isValid(o) && plane == o.plane - && spriteIndex == o.spriteIndex && isFullQuad && o.isFullQuad) { + if(isTranslatedCopyOf(o)) { int numVerticesTouching = 0; + boolean[] verticesTouching = new boolean[4]; for(int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { if(xs[i] == o.xs[j] && ys[i] == o.ys[j] && zs[i] == o.zs[j]) { + verticesTouching[i] = true; numVerticesTouching++; } } } if(numVerticesTouching == 2) { - mergeWithQuad(o); + for(int i = 0; i < 4; i++) { + if(verticesTouching[i]) { + copyVertexFrom(o, i, i); + } + } totalMergeCountByPlane[plane]++; @@ -221,60 +165,14 @@ public class MeshQuad { } } - private void mergeWithQuad(MeshQuad o) { - if(minX < o.minX) { - copyEdgeFrom(o, EnumFacing.EAST); - } else if(minX > o.minX) { - copyEdgeFrom(o, EnumFacing.WEST); - } else if(minY < o.minY) { - copyEdgeFrom(o, EnumFacing.UP); - } else if(minY > o.minY) { - copyEdgeFrom(o, EnumFacing.DOWN); - } else if(minZ < o.minZ) { - copyEdgeFrom(o, EnumFacing.NORTH); - } else if(minX > o.minX) { - copyEdgeFrom(o, EnumFacing.SOUTH); - } - } - - private void copyEdgeFrom(MeshQuad o, EnumFacing side) { - int whichX, whichY, whichZ; - whichX = whichY = whichZ = -1; - - switch(plane) { - case PLANE_XY: - whichZ = 0; - break; - case PLANE_XZ: - whichY = 0; - break; - case PLANE_YZ: - whichX = 0; - break; - } - - switch(side) { - case EAST: - copyCornerVertexFrom(o, 1, whichY, whichZ); - break; - case WEST: - copyCornerVertexFrom(o, 0, whichY, whichZ); - break; - case UP: - copyCornerVertexFrom(o, whichX, 1, whichZ); - break; - case DOWN: - copyCornerVertexFrom(o, whichX, 0, whichZ); - break; - case NORTH: - copyCornerVertexFrom(o, whichX, whichY, 1); - break; - case SOUTH: - copyCornerVertexFrom(o, whichX, whichY, 0); - break; - } - - updateMinMaxXYZ(); + private void copyVertexFrom(MeshQuad o, int src, int dest) { + xs[dest] = o.xs[src]; + ys[dest] = o.ys[src]; + zs[dest] = o.zs[src]; + us[dest] = o.us[src]; + vs[dest] = o.vs[src]; + bs[dest] = o.bs[src]; + cs[dest] = o.cs[src]; } private void updateMinMaxXYZ() { @@ -288,77 +186,12 @@ public class MeshQuad { } } - private void copyCornerVertexFrom(MeshQuad o, int whichX, int whichY, int whichZ) { - int whichXMin, whichXMax, whichYMin, whichYMax, whichZMin, whichZMax; - whichXMin = whichYMin = whichZMin = 0; - whichXMax = whichYMax = whichZMax = 1; - - if(whichX != -1) whichXMin = whichXMax = whichX; - if(whichY != -1) whichYMin = whichYMax = whichY; - if(whichZ != -1) whichZMin = whichZMax = whichZ; - - for(int minOrMaxX = whichXMin; minOrMaxX <= whichXMax; minOrMaxX++) { - for(int minOrMaxY = whichYMin; minOrMaxY <= whichYMax; minOrMaxY++) { - for(int minOrMaxZ = whichZMin; minOrMaxZ <= whichZMax; minOrMaxZ++) { - copyVertexFrom(o, - o.getCornerVertex(minOrMaxX == 1, minOrMaxY == 1, minOrMaxZ == 1), - getCornerVertex(minOrMaxX == 1, minOrMaxY == 1, minOrMaxZ == 1)); - } - } - } - } - - private void copyVertexFrom(MeshQuad o, int src, int dest) { - xs[dest] = o.xs[src]; - ys[dest] = o.ys[src]; - zs[dest] = o.zs[src]; - relUs[dest] = o.relUs[src]; - relVs[dest] = o.relVs[src]; - bUs[dest] = o.bUs[src]; - bVs[dest] = o.bVs[src]; - cs[dest] = o.cs[src]; - normals[dest] = o.normals[src]; - } - - public void writeToDisk(DataOutputStream out, int pass) throws IOException { - if(deleted) { - return; - } - - if(flags.hasTexture) { - if(pass == 0) out.writeShort(spriteIndex); - } - for (int vertexI = 0; vertexI < 4; vertexI++) { - if(pass == 1) out.writeByte(xs[vertexI] == 256 ? 255 : xs[vertexI]); - if(pass == 2) out.writeByte(ys[vertexI] == 256 ? 255 : ys[vertexI]); - if(pass == 3) out.writeByte(zs[vertexI] == 256 ? 255 : zs[vertexI]); - - if (flags.hasTexture) { - if(pass == 4) out.writeByte(relUs[vertexI]); - if(pass == 5) out.writeByte(relVs[vertexI]); - } - - if (flags.hasBrightness) { - if(pass == 6) out.writeByte(bUs[vertexI]); - if(pass == 7) out.writeByte(bVs[vertexI]); - } - - if (flags.hasColor) { - if(pass == 8) out.writeInt(cs[vertexI]); - } - - if (flags.hasNormals) { - if(pass == 9) out.writeInt(normals[vertexI]); - } - } - } - // maybe minXYZ and maxXYZ should be arrays instead - public int getMin(int coord) { + public double getMin(int coord) { return coord == 0 ? minX : coord == 1 ? minY : coord == 2 ? minZ : -1; } - public int getMax(int coord) { + public double getMax(int coord) { return coord == 0 ? maxX : coord == 1 ? maxY : coord == 2 ? maxZ : -1; } @@ -380,7 +213,7 @@ public class MeshQuad { @Override public String toString() { - return String.format(Locale.ENGLISH, "%s(%.1f, %.1f, %.1f -- %.1f, %.1f, %.1f) %s", deleted ? "XXX " : "", minX/16f, minY/16f, minZ/16f, maxX/16f, maxY/16f, maxZ/16f, spriteName); + return String.format(Locale.ENGLISH, "%s(%.1f, %.1f, %.1f -- %.1f, %.1f, %.1f)", deleted ? "XXX " : "", minX, minY, minZ, maxX, maxY, maxZ); } public static class QuadPlaneComparator implements Comparator<MeshQuad> { diff --git a/src/main/java/makamys/neodymium/renderer/NeoRenderer.java b/src/main/java/makamys/neodymium/renderer/NeoRenderer.java index a49a77a..54d1763 100644 --- a/src/main/java/makamys/neodymium/renderer/NeoRenderer.java +++ b/src/main/java/makamys/neodymium/renderer/NeoRenderer.java @@ -392,10 +392,12 @@ public class NeoRenderer { glBindVertexArray(VAO); GL11.glDisable(GL11.GL_BLEND); + GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); glMultiDrawArrays(GL_TRIANGLES, piFirst[0], piCount[0]); + GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - glMultiDrawArrays(GL_TRIANGLES, piFirst[1], piCount[1]); + //glMultiDrawArrays(GL_TRIANGLES, piFirst[1], piCount[1]); glBindVertexArray(0); glUseProgram(0); |