Very significant improvement in performance by using glSubImage to upload data. Inspired by frequent complaints about performance of hires
texture packs. They probably still need a beefy system but should work. Hopefully I can figure out why the subImage GL side copy isn't working properly for an even more significant speed boost. But this gets things started.
This commit is contained in:
parent
bc44fbe7dd
commit
10f08460a6
4 changed files with 162 additions and 0 deletions
|
@ -0,0 +1,30 @@
|
|||
package cpw.mods.fml.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import net.minecraft.client.renderer.texture.Texture;
|
||||
import net.minecraft.client.renderer.texture.TextureStitched;
|
||||
|
||||
public class CopySubimageTextureHelper extends TextureHelper {
|
||||
@Override
|
||||
public void doTextureCopy(Texture atlas, Texture source, int atlasX, int atlasY)
|
||||
{
|
||||
if (atlas.func_94282_c() == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
atlas.func_94277_a(0);
|
||||
ByteBuffer buffer = source.func_94273_h();
|
||||
buffer.position(0);
|
||||
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, atlasX, atlasY, source.func_94275_d(), source.func_94276_e(), GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doTextureUpload(TextureStitched source)
|
||||
{
|
||||
// NO OP for copysubimage
|
||||
}
|
||||
|
||||
}
|
30
fml/client/cpw/mods/fml/client/OpenGL43TextureHelper.java
Normal file
30
fml/client/cpw/mods/fml/client/OpenGL43TextureHelper.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package cpw.mods.fml.client;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL43;
|
||||
|
||||
import net.minecraft.client.renderer.texture.Texture;
|
||||
import net.minecraft.client.renderer.texture.TextureStitched;
|
||||
|
||||
public class OpenGL43TextureHelper extends TextureHelper {
|
||||
|
||||
public OpenGL43TextureHelper()
|
||||
{
|
||||
// GL43.
|
||||
// glCopyMethod = Class.forName("org.lwjgl.OpenGL")
|
||||
}
|
||||
@Override
|
||||
public void doTextureCopy(Texture atlas, Texture source, int atlasX, int atlasY)
|
||||
{
|
||||
// System.out.printf("Src: %d Targ: %d, Coords %d %d %d %d\n", source.func_94282_c(), atlas.func_94282_c(), atlasX, atlasY, source.func_94275_d(), source.func_94276_e());
|
||||
// GL43.glCopyImageSubData(source.func_94282_c(), GL11.GL_TEXTURE_2D, 0, 0, 0, 0, atlas.func_94282_c(), GL11.GL_TEXTURE_2D, 0, atlasX, atlasY, 0, source.func_94275_d(), source.func_94276_e(), 1);
|
||||
// System.out.printf("Err: %x\n", GL11.glGetError());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doTextureUpload(TextureStitched source)
|
||||
{
|
||||
// source.createAndUploadTextures();
|
||||
}
|
||||
|
||||
}
|
|
@ -20,8 +20,13 @@ import java.util.Map;
|
|||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.opengl.ContextCapabilities;
|
||||
import org.lwjgl.opengl.GLContext;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
|
||||
|
@ -34,6 +39,8 @@ public class TextureFXManager
|
|||
private Map<Integer,TextureHolder> texturesById = Maps.newHashMap();
|
||||
private Map<String, TextureHolder> texturesByName = Maps.newHashMap();
|
||||
|
||||
private TextureHelper helper;
|
||||
|
||||
void setClient(Minecraft client)
|
||||
{
|
||||
this.client = client;
|
||||
|
@ -102,4 +109,35 @@ public class TextureFXManager
|
|||
{
|
||||
return texturesByName.containsKey(texture) ? new Dimension(texturesByName.get(texture).x, texturesByName.get(texture).y) : new Dimension(1,1);
|
||||
}
|
||||
|
||||
|
||||
public TextureHelper getHelper()
|
||||
{
|
||||
if (helper == null)
|
||||
{
|
||||
ContextCapabilities capabilities = GLContext.getCapabilities();
|
||||
boolean has43 = false;
|
||||
try
|
||||
{
|
||||
has43 = capabilities.getClass().getField("GL_ARB_copy_image").getBoolean(capabilities);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
// NOOP - LWJGL needs updating
|
||||
FMLLog.info("Forge Mod Loader has detected an older LWJGL version, new advanced texture animation features are disabled");
|
||||
}
|
||||
// if (has43 && Boolean.parseBoolean(System.getProperty("fml.useGL43","true")))
|
||||
// {
|
||||
// FMLLog.info("Using the new OpenGL 4.3 advanced capability for animations");
|
||||
// helper = new OpenGL43TextureHelper();
|
||||
// }
|
||||
// else
|
||||
{
|
||||
FMLLog.info("Not using advanced OpenGL 4.3 advanced capability for animations : OpenGL 4.3 is %s", has43 ? "available" : "not available");
|
||||
helper = new CopySubimageTextureHelper();
|
||||
}
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
}
|
||||
|
|
64
fml/client/cpw/mods/fml/client/TextureHelper.java
Normal file
64
fml/client/cpw/mods/fml/client/TextureHelper.java
Normal file
|
@ -0,0 +1,64 @@
|
|||
package cpw.mods.fml.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.renderer.texture.Texture;
|
||||
import net.minecraft.client.renderer.texture.TextureStitched;
|
||||
|
||||
public abstract class TextureHelper {
|
||||
|
||||
/**
|
||||
* Copy the texture from the source to the atlas at the specified position
|
||||
*
|
||||
* This will use the devised GL helper to do either GL-side copy or a subimage upload
|
||||
*
|
||||
* @param atlas The atlas texture we're copying into
|
||||
* @param source The source texture we're copying from (complete)
|
||||
* @param atlasX The X position on the atlas
|
||||
* @param atlasY The Y position on the atlas
|
||||
*/
|
||||
public abstract void doTextureCopy(Texture atlas, Texture source, int atlasX, int atlasY);
|
||||
|
||||
/**
|
||||
* Upload the texture to the GPU for GL side copying operations
|
||||
* This may be a no-op depending on the active implementation.
|
||||
*
|
||||
* @param source The texture to upload
|
||||
*/
|
||||
public abstract void doTextureUpload(TextureStitched source);
|
||||
|
||||
/**
|
||||
* Rotate the texture so that it doesn't need a rotational transform applied each tick
|
||||
*
|
||||
* @param texture The texture to rotate
|
||||
* @param buffer The buffer for the texture
|
||||
*/
|
||||
public void rotateTexture(Texture texture, ByteBuffer buffer)
|
||||
{
|
||||
ByteBuffer bytebuffer = buffer;
|
||||
buffer.position(0);
|
||||
ByteBuffer other = ByteBuffer.allocateDirect(buffer.capacity());
|
||||
other.position(0);
|
||||
|
||||
for (int k = 0; k < texture.func_94276_e(); ++k)
|
||||
{
|
||||
int l = texture.func_94276_e() - k - 1;
|
||||
int i1 = k * texture.func_94275_d() * 4;
|
||||
|
||||
for (int k1 = 0; k1 < texture.func_94275_d(); ++k1)
|
||||
{
|
||||
int l1 = k1 * texture.func_94276_e() * 4 + l * 4;
|
||||
int i2 = i1 + k1 * 4;
|
||||
|
||||
other.put(l1 + 0, bytebuffer.get(i2 + 0));
|
||||
other.put(l1 + 1, bytebuffer.get(i2 + 1));
|
||||
other.put(l1 + 2, bytebuffer.get(i2 + 2));
|
||||
other.put(l1 + 3, bytebuffer.get(i2 + 3));
|
||||
}
|
||||
}
|
||||
buffer.position(0);
|
||||
buffer.put(other);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue