+++ /dev/null
-package com.badlogic.gdx.graphics.g3d;
-
-import com.badlogic.gdx.graphics.g3d.test.TestShader;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
-import com.badlogic.gdx.graphics.glutils.ShaderProgram;
-
-public class DefaultShader extends TestShader {
-// TODO implement a default shader, for now it's just a stub to TestShader
- public DefaultShader (long mask) {
- super(mask);
- // TODO Auto-generated constructor stub
- }
-
- /* public DefaultShader (ShaderProgram program) {
- super(program);
- // TODO Auto-generated constructor stub
- }
-
- public DefaultShader (String vertexShader, String fragmentShader) {
- super(vertexShader, fragmentShader);
- // TODO Auto-generated constructor stub
- }*/
-
-}
import com.badlogic.gdx.graphics.g3d.model.Model;
import com.badlogic.gdx.graphics.g3d.test.Light;
import com.badlogic.gdx.graphics.g3d.test.NewModel;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
+import com.badlogic.gdx.graphics.g3d.utils.DefaultTextureBinder;
+import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.graphics.g3d.utils.RenderInstancePool;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
protected final Array<Renderable> renderables = new Array<Renderable>();
/** Construct a BaseRenderBatch with the specified listener */
- public ModelBatch(RenderBatchListener listener, ExclusiveTextures textures) {
+ public ModelBatch(RenderBatchListener listener, DefaultTextureBinder textures) {
this.listener = listener;
this.context = new RenderContext(textures);
}
/** Construct a BaseRenderBatch with the default implementation and the specified texture range */
- public ModelBatch(ExclusiveTextures textures) {
+ public ModelBatch(DefaultTextureBinder textures) {
this(new RenderBatchAdapter(), textures);
}
/** Construct a BaseRenderBatch with the default implementation */
public ModelBatch() {
- this(new ExclusiveTextures(ExclusiveTextures.ROUNDROBIN));
+ this(new DefaultTextureBinder(DefaultTextureBinder.ROUNDROBIN));
}
public void begin (Camera cam) {
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.g3d.test.Light;
import com.badlogic.gdx.graphics.g3d.test.NewModel;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
+import com.badlogic.gdx.graphics.g3d.utils.DefaultTextureBinder;
+import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.graphics.g3d.utils.RenderInstancePool;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
private final RenderInstancePool renderInstancePool = new RenderInstancePool();
/** Construct a BaseRenderBatch with the specified listener */
- public RenderBatch(RenderBatchListener listener, ExclusiveTextures textures) {
+ public RenderBatch(RenderBatchListener listener, DefaultTextureBinder textures) {
this.listener = listener;
this.context = new RenderContext(textures);
}
/** Construct a BaseRenderBatch with the default implementation and the specified texture range */
- public RenderBatch(ExclusiveTextures textures) {
+ public RenderBatch(DefaultTextureBinder textures) {
this(new RenderBatchAdapter(), textures);
}
/** Construct a BaseRenderBatch with the default implementation */
public RenderBatch() {
- this((ExclusiveTextures)null);
+ this((DefaultTextureBinder)null);
}
public void begin (Camera cam) {
import com.badlogic.gdx.graphics.g3d.materials.NewMaterial;
import com.badlogic.gdx.graphics.g3d.old.materials.Material;
import com.badlogic.gdx.graphics.g3d.test.TestShader;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
+import com.badlogic.gdx.graphics.g3d.utils.DefaultTextureBinder;
import com.badlogic.gdx.utils.Array;
public class RenderBatchAdapter implements RenderBatchListener {
import com.badlogic.gdx.math.Matrix4;
/**
- * A renderable encapsulates all necessary information to render a {@link Node} within
- * a {@link Model}. A renderable defines a world {@link #transform}, the {@link Mesh} to render
+ * A renderable defines a world {@link #transform}, the {@link Mesh} to render
* along with the offset into the mesh's indices and the number of indices to use plus the
* primitive type to render the part of the mesh with. Finally, a renderable defines
* a {@link NewMaterial} to be applied to the mesh.</p>
import com.badlogic.gdx.graphics.g3d.old.materials.Material;
import com.badlogic.gdx.graphics.g3d.test.Light;
import com.badlogic.gdx.graphics.g3d.test.NewModel;
+import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.math.Matrix4;
public interface Shader extends Comparator<RenderInstance> {
package com.badlogic.gdx.graphics.g3d.model;
import com.badlogic.gdx.files.FileHandle;
+import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttribute;
for(ModelTexture tex: mtl.diffuseTextures) {
TextureDescriptor descriptor = new TextureDescriptor();
+ descriptor.texture = textures.get(tex.fileName);
+ descriptor.minFilter = GL20.GL_LINEAR;
+ descriptor.magFilter = GL20.GL_LINEAR;
+ descriptor.uWrap = GL20.GL_CLAMP_TO_EDGE;
+ descriptor.vWrap = GL20.GL_CLAMP_TO_EDGE;
result.add(new TextureAttribute(TextureAttribute.Diffuse, descriptor));
}
}
+++ /dev/null
-package com.badlogic.gdx.graphics.g3d.test;
-
-import java.util.Comparator;
-
-import com.badlogic.gdx.graphics.Camera;
-import com.badlogic.gdx.graphics.g3d.RenderInstance;
-import com.badlogic.gdx.graphics.glutils.ShaderProgram;
-import com.badlogic.gdx.utils.Array;
-
-public interface OldBatchRenderer extends Comparator<RenderInstance> {
- ShaderProgram getShader(RenderInstance instance);
- void render(Camera camera, Array<RenderInstance> instances /*, Array<Light> lights*/);
-}
+++ /dev/null
-package com.badlogic.gdx.graphics.g3d.test;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Camera;
-import com.badlogic.gdx.graphics.GL10;
-import com.badlogic.gdx.graphics.GL11;
-import com.badlogic.gdx.graphics.Mesh;
-import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.VertexAttribute;
-import com.badlogic.gdx.graphics.VertexAttributes.Usage;
-import com.badlogic.gdx.graphics.g3d.RenderInstance;
-import com.badlogic.gdx.graphics.g3d.old.materials.Material;
-import com.badlogic.gdx.graphics.g3d.old.materials.MaterialAttribute;
-import com.badlogic.gdx.graphics.g3d.old.materials.TextureAttribute;
-import com.badlogic.gdx.graphics.glutils.ShaderProgram;
-import com.badlogic.gdx.utils.Array;
-
-public class OldBatchRendererGLES11 implements OldBatchRenderer {
- final float[] lightColor = {1, 1, 1, 0};
- final float[] lightPosition = {2, 5, 10, 0};
-
- public final int textureUnitOffset = 3;
- public final int textureCount;
- final Texture[] textures;
- final int[] textureWeights;
- public int bindCount = 0;
- public int reuseCount = 0;
-
- public OldBatchRendererGLES11() {
- textureCount = Math.min(GL10.GL_MAX_TEXTURE_UNITS, 16) - textureUnitOffset;
- textures = new Texture[textureCount];
- textureWeights = new int[textureCount];
- }
-
- @Override
- public int compare (RenderInstance o1, RenderInstance o2) {
- return o1.distance > o2.distance ? 1 : (o1.distance < o2.distance ? -1 : 0);
- }
-
- @Override
- public ShaderProgram getShader (RenderInstance instance) {
- return null;
- }
-
- Material currentMaterial;
- boolean useTexture;
- int currentTexture; // for now only allow one textureattribute to be used at a time
- private final void setMaterial(final GL11 gl, final Material mat) {
- if (mat == currentMaterial)
- return;
-
- final boolean hasTex = mat.hasTexture();
-
- if (useTexture != hasTex || currentMaterial == null) {
- useTexture = hasTex;
- if (hasTex)
- gl.glEnable(GL11.GL_TEXTURE_2D);
- else
- gl.glDisable(GL11.GL_TEXTURE_2D);
- }
-
- currentMaterial = mat;
- for (MaterialAttribute attr : currentMaterial) {
- if (attr instanceof TextureAttribute)
- bindTextureAttribute(gl, (TextureAttribute)attr);
- else
- attr.bind();
- }
- }
-
- private final void bindTextureAttribute(final GL11 gl, final TextureAttribute attribute) {
- currentTexture = bindTexture(gl, attribute.texture);
- Gdx.gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, attribute.minFilter);
- Gdx.gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, attribute.magFilter);
- Gdx.gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, attribute.uWrap);
- Gdx.gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, attribute.vWrap);
- }
-
- private final int bindTexture(final GL11 gl, final Texture texture) {
- int result = -1;
- int weight = textureWeights[0];
- int windex = 0;
- for (int i = 0; i < textureCount; i++) {
- if (textures[i] == texture) {
- result = i;
- textureWeights[i]++;
- } else if (--textureWeights[i] < weight || textureWeights[i] < 0) {
- weight = textureWeights[i];
- windex = i;
- }
- }
- if (result < 0) {
- textures[windex] = texture;
- textureWeights[windex] = 100;
- result = windex;
- texture.bind(textureUnitOffset + windex);
- bindCount++;
- } else
- reuseCount++;
- return textureUnitOffset + result;
- }
-
- Mesh currentMesh;
- @Override
- public void render (Camera camera, Array<RenderInstance> instances) {
- final GL11 gl = Gdx.gl11;
- gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
- gl.glEnable(GL10.GL_DEPTH_TEST);
- gl.glEnable(GL10.GL_LIGHTING);
- gl.glEnable(GL10.GL_COLOR_MATERIAL);
- gl.glEnable(GL10.GL_TEXTURE_2D);
-
- gl.glEnable(GL10.GL_LIGHT0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightColor, 0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosition, 0);
-
- camera.apply(gl);
- currentMaterial = null;
- gl.glDisable(GL10.GL_TEXTURE_2D);
-
- for (int i = 0; i < textureCount; i++) {
- textureWeights[i] = 0;
- textures[i] = null;
- }
-
- for (int i = 0; i < instances.size; i++) {
- final RenderInstance instance = instances.get(i);
- // setMaterial(gl, instance.material);
- //if (instance.mesh != currentMesh) { // uncomment for GLES20
- if (currentMesh != null)
- currentMesh.unbind();
- currentMesh = instance.renderable.mesh;
- VertexAttribute a = currentMesh.getVertexAttribute(Usage.TextureCoordinates);
- if (a != null)
- a.alias = ShaderProgram.TEXCOORD_ATTRIBUTE + currentTexture;
- currentMesh.bind();
- //}
- gl.glPushMatrix();
- gl.glMultMatrixf(instance.transform.val, 0);
- instance.renderable.mesh.render(instance.renderable.primitiveType);
- gl.glPopMatrix();
- }
- if (currentMesh != null) {
- currentMesh.unbind();
- currentMesh = null;
- }
- }
-}
+++ /dev/null
-package com.badlogic.gdx.graphics.g3d.test;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.graphics.Camera;
-import com.badlogic.gdx.graphics.GL10;
-import com.badlogic.gdx.graphics.GL11;
-import com.badlogic.gdx.graphics.GL20;
-import com.badlogic.gdx.graphics.Mesh;
-import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.g3d.RenderInstance;
-import com.badlogic.gdx.graphics.g3d.old.materials.Material;
-import com.badlogic.gdx.graphics.g3d.old.materials.MaterialAttribute;
-import com.badlogic.gdx.graphics.g3d.old.materials.TextureAttribute;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
-import com.badlogic.gdx.graphics.glutils.ShaderProgram;
-import com.badlogic.gdx.math.Matrix4;
-import com.badlogic.gdx.utils.Array;
-import com.badlogic.gdx.utils.GdxRuntimeException;
-
-public class OldBatchRendererGLES20 implements OldBatchRenderer {
- public final static String PROJECTION_TRANSFORM = "u_projTrans";
- public final static String MODEL_TRANSFORM = "u_modelTrans";
-
- public final static String DEFAULT_VERTEX_SHADER =
- "attribute vec3 " + ShaderProgram.POSITION_ATTRIBUTE + ";" +
- "attribute vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;" +
- "uniform mat4 " + PROJECTION_TRANSFORM + ";" +
- "uniform mat4 " + MODEL_TRANSFORM + ";" +
- "varying vec2 v_texCoords;" +
- "void main() {"+
- " v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;" +
- " gl_Position = " + PROJECTION_TRANSFORM + " * (" + MODEL_TRANSFORM + " * vec4(" + ShaderProgram.POSITION_ATTRIBUTE + ", 1.0));" +
- "}";
-
- public final static String DEFAULT_FRAGMENT_SHADER =
- "#ifdef GL_ES\n" +
- "#define LOWP lowp\n" +
- "#define MED mediump\n" +
- "#define HIGH highp\n" +
- "precision mediump float;\n" +
- "#else\n" +
- "#define MED\n" +
- "#define LOWP\n" +
- "#endif\n" +
- "uniform sampler2D " + TextureAttribute.diffuseTexture + ";" +
- "varying MED vec2 v_texCoords;" +
- "void main() {" +
- " gl_FragColor = texture2D(" + TextureAttribute.diffuseTexture + ", v_texCoords);" +
- "}";
-
- public final ShaderProgram defaultShader;
-
- protected ExclusiveTextures textures;
-
- public OldBatchRendererGLES20(final ExclusiveTextures textures) {
- this.textures = textures;
- defaultShader = new ShaderProgram(DEFAULT_VERTEX_SHADER, DEFAULT_FRAGMENT_SHADER);
- if (!defaultShader.isCompiled())
- throw new GdxRuntimeException(defaultShader.getLog());
-
- }
-
- @Override
- public int compare (RenderInstance arg0, RenderInstance arg1) {
- // TODO
- return arg0.distance > arg1.distance ? 1 : (arg0.distance < arg1.distance ? -1 : 0);
- }
-
- @Override
- public ShaderProgram getShader (RenderInstance instance) {
- // TODO
- return defaultShader;
- }
-
- @Override
- public void render (final Camera camera, final Array<RenderInstance> instances) {
- // breakdown this method into smaller inline pieces for easy testing
- final GL20 gl = Gdx.gl20;
- begin(gl, camera);
- for (int i = 0; i < instances.size; i++) {
- final RenderInstance instance = instances.get(i);
- bindShader(gl, camera, instance);
- bindMaterial(gl, camera, instance);
- renderMesh(gl, camera, instance);
- }
- end(gl);
- }
-
- /////// bindShader /////////
- private ShaderProgram currentShader;
- private ShaderProgram previousShader;
- private boolean shaderChanged;
- private final void bindShader(final GL20 gl, final Camera camera, final RenderInstance instance) {
- shaderChanged = instance.shader != currentShader;
- if (!shaderChanged)
- return;
- if (currentShader != null)
- currentShader.end();
- previousShader = currentShader;
- //currentShader = instance.shader;
- currentShader.begin();
-
- currentShader.setUniformMatrix(PROJECTION_TRANSFORM, camera.combined);
- }
-
- /////// bindMaterial /////////
- Material currentMaterial;
- private final void bindMaterial(final GL20 gl, final Camera camera, final RenderInstance instance) {
- /*if (currentMaterial == instance.material)
- return;
- currentMaterial = instance.material;
- for (MaterialAttribute attr : currentMaterial) {
- if (attr instanceof TextureAttribute)
- bindTextureAttribute(gl, (TextureAttribute)attr);
- else
- attr.bind(currentShader);
- }*/
- }
-
- /////// bindTextureAttribute /////////
- TextureAttribute currentTextureAttribute;
- int unittmp = 0;
- private final void bindTextureAttribute(final GL20 gl, final TextureAttribute attribute) {
- if (attribute == currentTextureAttribute && !shaderChanged)
- return;
- final int unit = textures.bindTexture(attribute.texture);
- attribute.texture.bind(unit);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, attribute.minFilter);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, attribute.magFilter);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, attribute.uWrap);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, attribute.vWrap);
- currentShader.setUniformi(TextureAttribute.diffuseTexture, unit);
- currentTextureAttribute = attribute;
- }
-
- /////// renderMesh /////////
- private Mesh currentMesh;
- private Matrix4 currentTransform;
- private final void renderMesh(final GL20 gl, final Camera camera, final RenderInstance instance) {
- if (currentMesh != instance.renderable.mesh || shaderChanged) {
- if (currentMesh != null)
- currentMesh.unbind(shaderChanged ? previousShader : currentShader);
- (currentMesh = instance.renderable.mesh).bind(currentShader);
- }
- if (currentTransform != instance.transform || shaderChanged)
- currentShader.setUniformMatrix(MODEL_TRANSFORM, currentTransform = instance.transform);
- instance.renderable.mesh.render(currentShader, instance.renderable.primitiveType);
- }
-
- /////// begin /////////
- private final void begin(final GL20 gl, final Camera camera) {
- Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
- Gdx.gl.glDepthFunc(GL10.GL_LEQUAL);
- Gdx.gl.glEnable(GL10.GL_BLEND);
- Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
- }
-
- /////// end /////////
- private final void end(final GL20 gl) {
- if (currentMesh != null) {
- currentMesh.unbind(currentShader);
- currentMesh = null;
- }
- if (currentShader != null) {
- currentShader.end();
- currentShader = null;
- }
- }
-}
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
-import com.badlogic.gdx.graphics.g3d.RenderContext;
import com.badlogic.gdx.graphics.g3d.RenderInstance;
import com.badlogic.gdx.graphics.g3d.Renderable;
import com.badlogic.gdx.graphics.g3d.Shader;
import com.badlogic.gdx.graphics.g3d.materials.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.materials.NewMaterial;
import com.badlogic.gdx.graphics.g3d.materials.TextureAttribute;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
+import com.badlogic.gdx.graphics.g3d.utils.DefaultTextureBinder;
+import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
import com.badlogic.gdx.graphics.g3d.utils.RenderInstancePool;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix3;
/////// bindTextureAttribute /////////
TextureAttribute currentTextureAttribute;
private final void bindTextureAttribute(final int uniform, final TextureAttribute attribute) {
- final int unit = context.textures.bindTexture(attribute.textureDescription);
+ final int unit = context.textureBinder.bind(attribute.textureDescription);
program.setUniformi(uniform, unit);
currentTextureAttribute = attribute;
}
package com.badlogic.gdx.graphics.g3d.utils;
+import java.nio.IntBuffer;
+
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.utils.BufferUtils;
import com.badlogic.gdx.utils.GdxRuntimeException;
/** Class that you assign a range of texture units and binds textures for you within that range.
* It does some basic usage tracking to avoid unnessecary bind calls.
* @author xoppa */
-public final class ExclusiveTextures {
+public final class DefaultTextureBinder implements TextureBinder {
public final static int ROUNDROBIN = 0;
public final static int WEIGHTED = 1;
/** GLES only supports up to 32 textures */
- public final static int MAX_GLES_UNITS = 32;
+ public final static int MAX_GLES_UNITS = 4;
/** The index of the first exclusive texture unit */
private final int offset;
/** The amount of exclusive textures that may be used */
private int bindCount = 0; // TODO remove debug code
/** Uses all available texture units and reuse weight of 3 */
- public ExclusiveTextures(final int method) {
+ public DefaultTextureBinder(final int method) {
this(method, 0);
}
/** Uses all remaining texture units and reuse weight of 3 */
- public ExclusiveTextures(final int method, final int offset) {
- this(method, offset, GL10.GL_MAX_TEXTURE_UNITS - offset);
+ public DefaultTextureBinder(final int method, final int offset) {
+ this(method, offset, getMaxTextureUnits() - offset);
}
/** Uses reuse weight of 10 */
- public ExclusiveTextures(final int method, final int offset, final int count) {
+ public DefaultTextureBinder(final int method, final int offset, final int count) {
this(method, offset, count, 10);
}
- public ExclusiveTextures(final int method, final int offset, final int count, final int reuseWeight) {
- int max = Math.max(GL10.GL_MAX_TEXTURE_UNITS, MAX_GLES_UNITS - offset);
+ public DefaultTextureBinder(final int method, final int offset, final int count, final int reuseWeight) {
+ // FIXME this is wrong, GL_MATRX_TEXTURE_UNITS is a constant, doesn't return the #units for the current GPU
+ int max = Math.max(getMaxTextureUnits(), MAX_GLES_UNITS - offset);
if (offset < 0 || count < 0 || (offset + count) > max || reuseWeight < 1)
throw new GdxRuntimeException("Illegal arguments");
this.method = method;
this.weights = (method == WEIGHTED) ? new int[count] : null;
}
- private final TextureDescriptor tempDesc = new TextureDescriptor();
- /** @deprecated
- * Binds the texture if needed and sets it active, returns the unit */
- public final int bindTexture(final Texture texture) {
- tempDesc.reset();
- tempDesc.texture = texture;
- return bindTexture(tempDesc, false);
- }
-
- /** Binds the texture if needed and sets it active, returns the unit */
- public final int bindTexture(final TextureDescriptor textureDesc) {
- return bindTexture(textureDesc, false);
+ private static int getMaxTextureUnits () {
+ IntBuffer buffer = BufferUtils.newIntBuffer(16);
+ Gdx.gl.glGetIntegerv(GL20.GL_MAX_TEXTURE_UNITS, buffer);
+ return buffer.get(0);
}
- /** @deprecated
- * Force binds the texture and sets it active, returns the unit */
- public final int rebindTexture(final Texture texture) {
- tempDesc.reset();
- tempDesc.texture = texture;
- return bindTexture(tempDesc, true);
- }
-
- /** Force binds the texture and sets it active, returns the unit */
- public final int rebindTexture(final TextureDescriptor textureDesc) {
- return bindTexture(textureDesc, true);
+ @Override
+ public void begin () {
+ for(int i = 0; i < count; i++) {
+ textures[i].texture = null;
+ if(weights != null) weights[i] = 0;
+ }
}
-
- /** Removes the reference to the texture, to assure that it will be rebound at the next bind call */
- public final void unbindTexture(final Texture texture) {
- for (int i = 0; i < count; i++) {
- if (textures[i].texture == texture) {
- textures[i] = null;
- weights[i] = 0;
- return;
- }
+
+ @Override
+ public void end () {
+ // FIXME only unbind textures that are bound
+ for(int i = 0; i < count; i++) {
+ Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0 + i);
+ Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);
}
+ Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
}
+ /** Binds the texture if needed and sets it active, returns the unit */
+ @Override
+ public final int bind(final TextureDescriptor textureDesc) {
+ return bindTexture(textureDesc, false);
+ }
+
private final int bindTexture(final TextureDescriptor textureDesc, final boolean rebind) {
int idx, result;
reused = false;
return result;
}
+ @Override
public final int getBindCount() { return bindCount; }
+
+ @Override
public final int getReuseCount() { return reuseCount; }
- public final void resetCounter() { bindCount = reuseCount = 0; }
+
+ @Override
+ public final void resetCounts() { bindCount = reuseCount = 0; }
}
-package com.badlogic.gdx.graphics.g3d;
+package com.badlogic.gdx.graphics.g3d.utils;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
+/**
+ * Manages OpenGL state and tries to reduce state changes. Uses a {@link TextureBinder} to
+ * reduce texture binds as well. Call {@link #begin()} to setup the context, call {@link #end()}
+ * to undo all state changes. Use the setters to change state, use {@link #textureBinder} to bind textures.
+ * @author badlogic
+ *
+ */
public class RenderContext {
- public final ExclusiveTextures textures;
-
+ /** used to bind textures **/
+ public final TextureBinder textureBinder;
private boolean blending;
private int blendSFactor;
private int blendDFactor;
private boolean depthTest;
private int depthFunc;
- public RenderContext(ExclusiveTextures textures) {
- this.textures = textures;
+ public RenderContext(TextureBinder textures) {
+ this.textureBinder = textures;
}
+ /**
+ * Sets up the render context, must be matched with a call to {@link #end()}. Assumes
+ * that the OpenGL states are in their defaults.
+ */
public final void begin() {
Gdx.gl.glDisable(GL10.GL_DEPTH_TEST);
depthTest = false;
Gdx.gl.glDisable(GL10.GL_BLEND);
blending = false;
blendSFactor = blendDFactor = depthFunc = 0;
+ textureBinder.begin();
}
+ /**
+ * Resest all changed OpenGL states to their defaults.
+ */
public final void end() {
-
+ if(depthTest) Gdx.gl.glDisable(GL10.GL_DEPTH_TEST);
+ if(blending) Gdx.gl.glDisable(GL10.GL_BLEND);
+ textureBinder.end();
}
public final void setDepthTest(final boolean enabled, final int depthFunction) {
--- /dev/null
+package com.badlogic.gdx.graphics.g3d.utils;
+
+import com.badlogic.gdx.graphics.Texture;
+
+/**
+ * Responsible for binding textures, may implement a strategy to avoid binding a texture
+ * unnecessarily. A TextureBinder may decide to which texture unit it binds a texture.
+ * @author badlogic
+ *
+ */
+public interface TextureBinder {
+ /**
+ * Prepares the binder for operation, must be matched with a call
+ * to {@link #end()}.
+ */
+ public void begin();
+
+ /**
+ * Disables all used texture units and unbinds textures. Resets the counts.
+ */
+ public void end();
+
+ /**
+ * Binds the texture to an available unit and applies the
+ * filters in the descriptor.
+ * @param textureDescriptor the {@link TextureDescriptor}
+ * @return the unit the texture was bound to
+ */
+ public int bind(TextureDescriptor textureDescriptor);
+
+ /**
+ * @return the number of binds actualy executed since the last call to {@link #resetCounts()}
+ */
+ public int getBindCount();
+ /**
+ * @return the number of binds that could be avoided by reuse
+ */
+ public int getReuseCount();
+
+ /**
+ * Resets the bind/reuse counts
+ */
+ public void resetCounts();
+}
import com.badlogic.gdx.math.MathUtils;\r
import com.badlogic.gdx.tests.AnimationTest;\r
import com.badlogic.gdx.tests.ETC1Test;\r
-import com.badlogic.gdx.tests.FreeTypeDisposeTest;\r
import com.badlogic.gdx.tests.FullscreenTest;\r
import com.badlogic.gdx.tests.InputTest;\r
import com.badlogic.gdx.tests.SpriteCacheTest;\r
new SharedLibraryLoader("../../gdx/libs/gdx-natives.jar").load("gdx");\r
\r
\r
- GdxTest test = new FreeTypeDisposeTest();\r
+ GdxTest test = new NewModelTest();\r
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();\r
config.useGL20 = test.needsGL20();\r
new LwjglApplication(test, config);\r
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GL20;
-import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.g3d.RenderBatch;
-import com.badlogic.gdx.graphics.g3d.RenderContext;
-import com.badlogic.gdx.graphics.g3d.RenderInstance;
import com.badlogic.gdx.graphics.g3d.loader.JsonModelLoader;
-import com.badlogic.gdx.graphics.g3d.materials.ColorAttribute;
-import com.badlogic.gdx.graphics.g3d.materials.NewMaterial;
import com.badlogic.gdx.graphics.g3d.old.loaders.ModelLoaderRegistry;
import com.badlogic.gdx.graphics.g3d.old.materials.Material;
import com.badlogic.gdx.graphics.g3d.old.materials.TextureAttribute;
-import com.badlogic.gdx.graphics.g3d.old.model.Model;
-import com.badlogic.gdx.graphics.g3d.old.model.SubMesh;
import com.badlogic.gdx.graphics.g3d.old.model.still.StillModel;
import com.badlogic.gdx.graphics.g3d.old.model.still.StillSubMesh;
import com.badlogic.gdx.graphics.g3d.test.InterimModel;
import com.badlogic.gdx.graphics.g3d.test.Light;
import com.badlogic.gdx.graphics.g3d.test.NewModel;
-import com.badlogic.gdx.graphics.g3d.test.OldBatchRendererGLES11;
-import com.badlogic.gdx.graphics.g3d.test.OldBatchRendererGLES20;
-import com.badlogic.gdx.graphics.g3d.test.TestShader;
-import com.badlogic.gdx.graphics.g3d.utils.ExclusiveTextures;
-import com.badlogic.gdx.graphics.glutils.FrameBuffer;
+import com.badlogic.gdx.graphics.g3d.utils.DefaultTextureBinder;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.tests.utils.GdxTest;
import com.badlogic.gdx.utils.Array;
-import com.badlogic.gdx.utils.Pool;
public class BatchRenderTest extends GdxTest {
int TEXTURE_COUNT = 30;
int BOX_COUNT = 500;
int UNIT_OFFSET = 2;
- int MAX_TEXTURES = Math.min(16 /*GL10.GL_MAX_TEXTURE_UNITS*/ - UNIT_OFFSET, ExclusiveTextures.MAX_GLES_UNITS - UNIT_OFFSET);
- int BIND_METHOD = ExclusiveTextures.WEIGHTED;
+ int MAX_TEXTURES = Math.min(16 /*GL10.GL_MAX_TEXTURE_UNITS*/ - UNIT_OFFSET, DefaultTextureBinder.MAX_GLES_UNITS - UNIT_OFFSET);
+ int BIND_METHOD = DefaultTextureBinder.WEIGHTED;
float MIN_X = -10f, MIN_Y = -10f, MIN_Z = -10f;
float SIZE_X = 20f, SIZE_Y = 20f, SIZE_Z = 20f;
Array<NewModel> cubes = new Array<NewModel>();
Array<Texture> textures = new Array<Texture>();
RenderBatch renderBatch;
- ExclusiveTextures exclusiveTextures;
+ DefaultTextureBinder exclusiveTextures;
Light[] lights;
float[] lightColor = {1, 1, 1, 0};
cam.lookAt(0, 0, 0);
cam.update();
- renderBatch = new RenderBatch(exclusiveTextures = new ExclusiveTextures(BIND_METHOD, UNIT_OFFSET, MAX_TEXTURES));
+ renderBatch = new RenderBatch(exclusiveTextures = new DefaultTextureBinder(BIND_METHOD, UNIT_OFFSET, MAX_TEXTURES));
lights = new Light[] {
new Light(Color.WHITE, Vector3.tmp.set(-10f, 10f, -10f), 15f),
instances.add(new ModelInstance(testModel, (new Matrix4()).setToTranslation(0, 5, 4)));
instances.add(new ModelInstance(carModel, (new Matrix4()).setToTranslation(6, 0, -4)));
- for (int i = 0; i < 1000; i++)
+ for (int i = 0; i < 10; i++)
instances.add(new ModelInstance(sphereModel, (new Matrix4()).setToTranslation(MIN_X + (float)Math.random() * SIZE_X, MIN_Y + (float)Math.random() * SIZE_Y, MIN_Z + (float)Math.random() * SIZE_Z).scl(0.25f + (float)Math.random())));
}
if ((dbgTimer += Gdx.graphics.getDeltaTime()) >= 1f) {
dbgTimer -= 1f;
Gdx.app.log("Test", "FPS: "+Gdx.graphics.getFramesPerSecond()+", binds: "+exclusiveTextures.getBindCount()+", reused: "+exclusiveTextures.getReuseCount());
- exclusiveTextures.resetCounter();
+ exclusiveTextures.resetCounts();
}
GL20 gl = Gdx.gl20;
gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
@Override
public boolean touchDragged (int x, int y, int pointer) {
+ cam.rotateAround(new Vector3(), Vector3.X, y - touchStartY);
cam.rotateAround(new Vector3(), Vector3.Y, x - touchStartX);
-// cam.rotateAround(new Vector3(), Vector3.X, y - touchStartY);
touchStartX = x;
touchStartY = y;
return false;