I've been looking over my code and I'm just wondering, when I set a texture for say, 20 quads that need to use the same texture, it seems as though I'm creating a new texture each time...... surely this isn't efficient?
How can I make sure that 20 quads that use the same texture do just that, use only 1 rather than creating 20 copies of it?
I just can't work out how I can do this. I know I can change the texID after applying the texture so that all quads that use the same texture, will have the same Texture ID, but this isn't really the issue I'm facing.
Of course, I may be completely misunderstanding how OpenGL deals with textures and my code may be OK :-/
Code:
public void setTexture(GLSurfaceView view, Bitmap imgTexture){
this.imgTexture=imgTexture;
//Create program from Utils class
iProgId = Utils.LoadProgram(strVShader, strFShader);
//Return location of u_basemap
iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap");
//Return location of attribute variables
iPosition = GLES20.glGetAttribLocation(iProgId, "a_position");
iTexCoords = GLES20.glGetAttribLocation(iProgId, "a_texCoords");
//Return usable texture ID from Utils class
texID = Utils.LoadTexture(view, imgTexture);
}
And....
public static int LoadTexture(GLSurfaceView view, Bitmap imgTex){
//Array for texture
int textures[] = new int[1];
try {
//Return texture name in textures Array
GLES20.glGenTextures(1, textures, 0);
//Bind textures
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
//Set parameters
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
//Apply the texture to the image loaded
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgTex, 0);
//clamp the texture
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
} catch (Exception e){
}
//Increase texture count by one
textureCount++;
return textures[0];
}
Edit
I've attempted the suggestion below (just calling glBindTextures()
) however, I'm not having any luck. Clearly I'm not understanding this correctly.
Lets say I have 2 sprites, Object1 and Object2.
I call the following:
object1.setTexture(this, myAtlasTexture); //Calls setTexture (See above)
This works and sets the texture on this sprite, so I can now draw it.
Now I want object2 to use the same texture. So I don't want to call this again and create a new texture (I believe this is a bad idea) - I simply want to use the texture that was previously created when I called setTexure
on object1.
So, instead of calling setTexture on object 2, I do the following:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIDOfObject1);
(Note textureIDOfObject1
is just that, I just query object1 to obtain its texture ID).
setTexture
being called from? What does your draw function look like? \$\endgroup\$texID
) to a texture image unit and binding that TIU to a sampler uniform in a program somewhere, then the code you posted does not do that either. All that we can see happening here is that when setTexture is called, a new GL program object is created, some attribute/uniform locations are queried, and a new GL texture object is created/uploaded. Nothing else is done with the texture object. \$\endgroup\$setTexture
once per material, then you're probably fine. Creating a different program for each material is probably unnecessary, as you can probably use the same program for most if not all of them, but it may not be a huge issue if you don't have more than a handful of materials. On the other hand ifsetTexture
is being called every frame, for every single quad, you have a big problem. \$\endgroup\$