3
\$\begingroup\$

I'm new in openGL world and I try to figure out followed problem:

How can I change size/zoom dynamically for my spritesheet.

This class represents some creature fetched from spritesheet and animate it.

enter image description here

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

public class DevQuestSpriteBase {

private static final String LOG_TAG = "Fess";//DevQuestSpriteBase.class.getSimpleName();

protected int mFrame = 0;
protected int mSwitcher = 0;
private int textureCount = 1; // frame animation
protected int[] textures = new int[textureCount]; // frame animation

// texture and verts
protected FloatBuffer vertexBuffer,
textureBuffer1,
textureBuffer2,
textureBuffer3,
textureBuffer4;

ByteBuffer bb1;



protected float verticesZoom[] = {
        0f,0f,0.0f,
        0f,0.5f,0.0f,
        0.6f,0f,0.0f,           
        0.6f,0.5f,0.0f
};


/** 1 frame */
protected float texture1[] = {          
        0.0f, 1.0f,     
        0.0f, 0.0f,     
        0.25f, 1.0f,    
        0.25f, 0.0f     
};
/** 2 frame */
protected float texture2[] = {          

        0.25f, 1.0f,        
        0.25f, 0.0f,        
        0.5f, 1.0f,     
        0.5f, 0.0f      
};
/** 3 frame */
protected float texture3[] = {          
        0.5f, 1.0f,     
        0.5f, 0.0f,     
        0.75f, 1.0f,    
        0.75f, 0.0f     
};
/** 4 frame */
protected float texture4[] = { 
        0.75f, 1.0f,        
        0.75f, 0.0f,        
        1.0f, 1.0f,     
        1.0f, 0.0f      
};


public DevQuestSpriteBase(){
    // vertices buffer
    bb1 = ByteBuffer.allocateDirect(verticesZoom.length * 4);
    bb1.order(ByteOrder.nativeOrder());
    vertexBuffer = bb1.asFloatBuffer();
    vertexBuffer.put(verticesZoom);
    vertexBuffer.position(0);

    // texture buffer
    bb1 = ByteBuffer.allocateDirect(texture1.length * 4);
    bb1.order(ByteOrder.nativeOrder());
    textureBuffer1 = bb1.asFloatBuffer();
    textureBuffer1.put(texture1);
    textureBuffer1.position(0);

    //#########################################################

    // texture buffer
    bb1 = ByteBuffer.allocateDirect(texture2.length * 4);
    bb1.order(ByteOrder.nativeOrder());
    textureBuffer2 = bb1.asFloatBuffer();
    textureBuffer2.put(texture2);
    textureBuffer2.position(0);

    //#########################################################

    // texture buffer
    bb1 = ByteBuffer.allocateDirect(texture3.length * 4);
    bb1.order(ByteOrder.nativeOrder());
    textureBuffer3 = bb1.asFloatBuffer();
    textureBuffer3.put(texture3);
    textureBuffer3.position(0);

    //#########################################################

    // texture buffer
    bb1 = ByteBuffer.allocateDirect(texture4.length * 4);
    bb1.order(ByteOrder.nativeOrder());
    textureBuffer4 = bb1.asFloatBuffer();
    textureBuffer4.put(texture4);
    textureBuffer4.position(0);
}


private void update() {

    if(mSwitcher == 5){
        mFrame = ++mFrame % 4;
        mSwitcher = 0;
        // Log.e(LOG_TAG, "DevQuestSpriteBase :: " + mFrame);
    }
    else{
        mSwitcher++; 
    }   


}

public void draw(GL10 gl){

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);


    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    if(mFrame == 0){
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer1);
    }
    else  if(mFrame == 1){
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer2);
    }
    else  if(mFrame == 2){
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer3);
    }
    else  if(mFrame == 3){
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer4);
    }



    //gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

    //Log.e(LOG_TAG, "DevQuestSpriteBase :: draw"); 

    update();

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, verticesZoom.length / 3);

    gl.glDrawElements(GL10.GL_TRIANGLES, 1, GL10.GL_UNSIGNED_SHORT, vertexBuffer);

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}   
}

You can see from code that i change texture every 5 calls:

if(mSwitcher == 5){
 mFrame = ++mFrame % 4;
...
}

I want to change dynamically vertix to change zoom to my creature.

So every 5 calls on draw to increase zoom to texture by 1%.

I saw many examples how to do it for static image but not during the draw.

comment

I have 10-20 these objects and create them in different times. Therefore I need change size per object differently.

Can someone help me,

Thank you

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

The common practice to do this (in modern OpenGL) is using shaders. Specifically vertex shaders. Usually by using some kind of transformation matrix.

Here is a tutorial about doing what you did, and also how to do it using shaders. The tutorial is in c++ and using OpenGL and not OpenGL ES, but should be quite straightforward to understand as the difference between modern OpenGL and OpenGL ES is small.

Edit:

Shaders are basically some code run on the GPU in parallel. It is executed for each Vertex and then each Fragment(pixel).

The Vertex shader's usual inputs are:

  • Vertex's Parameters:
    • Position
    • Texture Coordinates
    • Normals
    • etc.(Tangent, Bitangent, Vertex Color....)
  • Textures
  • Uniforms

The Vertex shader's usual outputs are:

  • Vertex Position(always)
  • Any parameters passed to the fragment shader

The Fragment shader's usual inputs are:

  • Any parameters passed down from the vertex shaders (usually interpolated across the triangle)
  • Textures
  • Uniforms

The Fragment shader's usual outputs are:

  • Pixel color data

As seen, both vertex and fragment shaders accept uniforms as inputs. These are variables set by your program to the shader and stay constant for each draw call. For the method I propose, you could use an uniform mat4 type uniform, to pass a transformation matrix to the Vertex shader, and multiply the input vertex position with the matrix.

Here is a Vertex shader in GLSL version 420 to do this:

#version 420

layout(location=0) in vec3 in_Position;

uniform mat4 u_TransformMatrix;

void main()
{
    gl_Position = vec4(in_Position, 1.0) * u_TransformMatrix;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You should explain it inline a bit more, rather than just linking to an external site. \$\endgroup\$ Jul 18, 2013 at 17:58
  • 1
    \$\begingroup\$ @SeanMiddleditch Edited to explain basic usage and workings of shaders. \$\endgroup\$
    – akaltar
    Jul 18, 2013 at 19:17
2
\$\begingroup\$

Well, didn't think that will find proper answer by myself,

I added to update method:

verticesZoom[4] = verticesZoom[4]*1.05f;
verticesZoom[6] = verticesZoom[6]*1.05f;
verticesZoom[9] = verticesZoom[9]*1.05f;
verticesZoom[10] = verticesZoom[10]*1.05f;

vertexBuffer.clear();
vertexBuffer.put(verticesZoom);
vertexBuffer.position(0);

Thank you anyways,

\$\endgroup\$
5
  • \$\begingroup\$ I was planning on writing a similar answer when I first read your question, but didn't get to it until now. Glad you found a solution. \$\endgroup\$
    – House
    Jul 17, 2013 at 15:20
  • 1
    \$\begingroup\$ If you are using modern OpenGL I guess you could just use transformation matrices or just simply do this multiplication in the vertex shader. \$\endgroup\$
    – akaltar
    Jul 18, 2013 at 9:48
  • \$\begingroup\$ @akaltar can you please, give me example or link how your technique help in my case, Thank you \$\endgroup\$ Jul 18, 2013 at 9:50
  • \$\begingroup\$ Here's a link to a tutorial. It's in c++, but I think you should be able to understand. link. Also, don't forget to read the second page, the first page only describes how to do it the way you do it now. The second explains why is that bad, and offers a new solution. \$\endgroup\$
    – akaltar
    Jul 18, 2013 at 10:07
  • \$\begingroup\$ @akaltar Please add this approach as response, because its interesting, ill +1 to response \$\endgroup\$ Jul 18, 2013 at 10:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .