0

I'm developing a 2D side-scrolling game.I have a tiled bitmap for background with size 2400x480.How can i scroll this bitmap?

I know that i can do it with following code:

for(int i=0;i<100;i++)
draw(bitmap,2400*i,480);

So it will scroll bitmap for 240000 pixels.

But i don't want to draw images which stays out of screen(with size 800x480).

How can i render scrolling tile?How can i give velocity to it?(For parallax scrolling after normal scrolling)

droidmachine
  • 577
  • 2
  • 8
  • 24
  • _scrambling through my brain_ You shouldn't [accept answers](http://stackoverflow.com/a/10179587/1262542) that don't help you. It's OK. – Stefan Hanke May 01 '12 at 18:36
  • @StefanHanke Sorry but i accepted because i supposed to understand what you said.Then i tried to code this algorithm but i can't success.That's why i asked again. – droidmachine May 01 '12 at 20:40

2 Answers2

0

The following code does not use two quads, but one quad, and adapts the texture coordinates accordingly. Please note that I stripped all texture handling code. The projection matrix solely contains glOrthof(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);. Quad2D defines a quad whose tex coords can be animated using updateTexCoords:

static class Quad2D {
    public Quad2D() {
        /* SNIP create buffers */
        float[] coords = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, };
        mFVertexBuffer.put(coords);
        float[] texs = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, };
        mTexBuffer.put(texs);
        /* SNIP reposition buffer indices */
    }

    public void updateTexCoords(float t) {
        t = t % 1.0f;
        mTexBuffer.put(0, 0.33f+t);
        mTexBuffer.put(2, 0.0f+t);
        mTexBuffer.put(4, 0.33f+t);
        mTexBuffer.put(6, 0.0f+t);
    }

    public void draw(GL10 gl) {
        glVertexPointer(2, GL_FLOAT, 0, mFVertexBuffer);
        glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
    /* SNIP members */
}

Now how to call updateTexCoords? Inside onDrawFrame, put the following code:

    long time = SystemClock.uptimeMillis() % 3000L;
    float velocity = 1.0f / 3000.0f;
    float offset = time * velocity;
    mQuad.updateTexCoords(offset);

Since the texture coordinates go beyond 1.0f, the texture wrap for the S coordinate must be set to GL_REPEAT.

Stefan Hanke
  • 3,458
  • 2
  • 30
  • 34
0

If you are ok working with shaders, we can have a cleaner and may be more efficient way of doing this.

Create a VBO with a quad covering the whole screen. The witdth and height should be 800 and 480 respectively.

then create your vertex shader as:

attribute vec4 vPos;
uniform int shift;
varying mediump vec2 fTexCoord;
void main(void){
   gl_Position = vPos;
   fTexCoord = vec2((vPos.x-shift)/800.0, vPos.y/480.0);//this logic might change slightly based on which quadarnt you choose.
}

The fragment shader would be something like:

precision mediump float;
uniform sampler2D texture;    
varying mediump vec2 fTexCoord;
void main(void){
   gl_FragColor = texture2D(texture, fTexCoord);
}

and you are done. To scroll just set the uniform value using "glUniformX()" apis.

CuriousChettai
  • 1,862
  • 1
  • 12
  • 10
  • @droidmachine: If your hw is OpenGL ES2.0 compliant, then most probably your fixed function anyway is getting implemented by shaders only. Making the shaders simple might gain you some performance figures. – CuriousChettai May 04 '12 at 06:36