5

I'm happily using the SpriteBatch class of the LibGDX Framework. My aim is to modify the representation of the sprite through a shader.

batch = new SpriteBatch(2, shaderProgram);

I copied the default shader from the SpriteBatch Class and added another uniform Sampler 2d

+ "uniform sampler2D u_Texture2;\n"//

Is there a working way to give the texture to the shader. Doing it like this, allways ends up in a ClearColor Screen.

batch.begin();
  texture2.bind(1);
  shaderProgram.setUniformi("u_Texture2", 1);
  batch.draw(spriteTexture,positions[0].x,positions[0].y);
  batch.draw(spriteTexture,positions[1].x,positions[1].y);
batch.end();

Each texture alone is working. Drawing manually with the help of the Mesh Class works as expected. So what can i do to use the convenience of SpriteBatch?

THX for Help

fky
  • 222
  • 2
  • 11

1 Answers1

7

I guess the problem there is related to texture bindings. SpriteBatch asumes that the active texture unit will be 0, so it makes a call to

lastTexture.bind(); instead of lastTexture.bind(0);

The problem is that the active unit you are giving it is 1 (as you call texture2.bind(1); in your code). so, texture unit 0 is never bound, and may be thats causing the blank screen.

For instance, i would add a Gdx.GL20.glActiveTexture(0); before the draw calls. I'm not quite sure it will solve the problem, but it's a start!

EDIT: I try my suggested solution and it works! :D. To be clearer, you should be doing this:

      batch.begin();
      texture2.bind(1); 
      shaderProgram.setUniformi("u_Texture2", 1);
      Gdx.gl.glActiveTexture(GL10.GL_TEXTURE0);//This is required by the SpriteBatch!!
             //have the unit0 activated, so when it calls bind(), it has the desired effect.
      batch.draw(spriteTexture,positions[0].x,positions[0].y);
      batch.draw(spriteTexture,positions[1].x,positions[1].y);
    batch.end();
aacotroneo
  • 2,170
  • 16
  • 22
  • hey finally i got an answere, thanks! You are right. It's cause of the way that class binds the texture. I need to say that i already made my own custom SpriteBatch Class out of it. SpriteBatch has shown also some issues in rendering bigger sized Framebuffer textures. And i always bind TEXTURE0 before. Thats why i decided to do it my way. Less convinient but way more flexible. Now i have a Sprite Batch which handles only the generation of the vertices. Everything arround can be customized with own shaders. – fky Sep 07 '12 at 16:20
  • 1
    Be aware that SpriteBatch does a little more than generating the vertices, if you are not carefull you'll run into performance issues. SpriteBatch itself has some 'usability' problems, but it's a design decision. It's intended to simplify the most common drawing operations, and somehow that hurts flexibility. Anyway, i've been able to solve most of the problems i ran into so far (most of the times it's enabling/disabling appropriate opengl flags before using it). Maybe tonight I'll try to implement multitexture like you did and let you know ;) – aacotroneo Sep 07 '12 at 17:33
  • 1
    sry for being late again and Thanks for your support. It's working like you edited. BUT, i don't like it. This looks kind a dangerous for me. I prefer my specialized version which is also faster and better debuggable cause of its smaller size. SpriteBatch is trying to make everybody happy. It's not really a performance optimised Class in my opinion. But anyway, thanks for making clear that SpriteBatch is using LAST BOUND texture and not just TEXTURE0 – fky Sep 17 '12 at 15:26