Android: SDL_RenderCopy using dest rectangle not working

Hi chaps,

Sorry to both you again, I have a little problem here. The following works
fine, stretching a whole image across the whole screen:
SDL_RenderCopy(renderer, sprite, NULL, NULL);

If I try to specific where to draw the sprite though, that is its
destination rectangle, I get just a black square under Android:
SDL_RenderCopy(renderer, sprite, NULL, &rect);
Under Linux everything works fine. Any idea what might be causing this?

I’m thinking it has to do with how the window’s size is overridden by the
mobile’s screen-size…

William

I don’t know anything about the specifics of what is going on there, but keep in mind that copying image data is not a strongpoint of GLES, perhaps the SDL_RendererCopy implementation is using
functionality not present on GLES?On 07/29/2011 04:34 AM, William Dyce wrote:

Hi chaps,

Sorry to both you again, I have a little problem here. The following works fine, stretching a whole image across the whole screen:
SDL_RenderCopy(renderer, sprite, NULL, NULL);

If I try to specific where to draw the sprite though, that is its destination rectangle, I get just a black square under Android:
*SDL_RenderCopy(renderer, sprite, NULL, &rect);
*
Under Linux everything works fine. Any idea what might be causing this?

I’m thinking it has to do with how the window’s size is overridden by the mobile’s screen-size…

William


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

Dunno - it works fine if the image gets to monopolise the render-srface but
not if if can’t, but I can’t think why that would be. I’ll have a look at
the implementation tomorrow when I’ve had some sleep. Are there any other
ways of blitting images I can try, without using the compat mode (which
doesn’t seem to work on my hardware)?

WilliamOn 29 July 2011 21:36, Forest Hale wrote:

I don’t know anything about the specifics of what is going on there, but
keep in mind that copying image data is not a strongpoint of GLES, perhaps
the SDL_RendererCopy implementation is using functionality not present on
GLES?

On 07/29/2011 04:34 AM, William Dyce wrote:

Hi chaps,

Sorry to both you again, I have a little problem here. The following works
fine, stretching a whole image across the whole screen:
SDL_RenderCopy(renderer, sprite, NULL, NULL);

If I try to specific where to draw the sprite though, that is its
destination rectangle, I get just a black square under Android:
*SDL_RenderCopy(renderer, sprite, NULL, &rect);
*
Under Linux everything works fine. Any idea what might be causing this?

I’m thinking it has to do with how the window’s size is overridden by the
mobile’s screen-size…

William

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/**
darkplaces http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged
demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I think I’m closing down on the problem: using SDL_image I was able to test
with images with alpha, my theory being that the image must monopolise the
renderer to be draw. Sure enough compositing two images with transparency,
even using NULL, NULL (whole render-surface) for both doesn’t work properly:
I get a black screen.

I’ll keep digging.On 30 July 2011 02:09, William Dyce <@William_Dyce> wrote:

Dunno - it works fine if the image gets to monopolise the render-srface but
not if if can’t, but I can’t think why that would be. I’ll have a look at
the implementation tomorrow when I’ve had some sleep. Are there any other
ways of blitting images I can try, without using the compat mode (which
doesn’t seem to work on my hardware)?

William

On 29 July 2011 21:36, Forest Hale wrote:

I don’t know anything about the specifics of what is going on there, but
keep in mind that copying image data is not a strongpoint of GLES, perhaps
the SDL_RendererCopy implementation is using functionality not present on
GLES?

On 07/29/2011 04:34 AM, William Dyce wrote:

Hi chaps,

Sorry to both you again, I have a little problem here. The following
works fine, stretching a whole image across the whole screen:
SDL_RenderCopy(renderer, sprite, NULL, NULL);

If I try to specific where to draw the sprite though, that is its
destination rectangle, I get just a black square under Android:
*SDL_RenderCopy(renderer, sprite, NULL, &rect);
*
Under Linux everything works fine. Any idea what might be causing this?

I’m thinking it has to do with how the window’s size is overridden by the
mobile’s screen-size…

William

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/**
darkplaces http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged
demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I’ve been having a look at the actual SDL_RenderCopy function in
SDL_render.c:

  • real_dstrect.x = 0;
    real_dstrect.y = 0;
    real_dstrect.w = renderer->viewport.w;
    real_dstrect.h = renderer->viewport.h;
    if (dstrect) {
    if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) {
    return 0;
    }
    /* Clip srcrect by the same amount as dstrect was clipped /
    if (dstrect->w != real_dstrect.w) {
    int deltax = (real_dstrect.x - dstrect->x);
    int deltaw = (real_dstrect.w - dstrect->w);
    real_srcrect.x += (deltax * real_srcrect.w) / dstrect->w;
    real_srcrect.w += (deltaw * real_srcrect.w) / dstrect->w;
    }
    if (dstrect->h != real_dstrect.h) {
    int deltay = (real_dstrect.y - dstrect->y);
    int deltah = (real_dstrect.h - dstrect->h);
    real_srcrect.y += (deltay * real_srcrect.h) / dstrect->h;
    real_srcrect.h += (deltah * real_srcrect.h) / dstrect->h;
    }
    }

I can’t help but think that somehow the *renderer->viewport.w; *type
functions are behaving strangely with Android, causing the source rect to
chosen incorrectly whenever a destination rect is specified. That would
explain why there’s nothing in the logs: it’s not actually an error. But I
tried commenting out this whole block of code just to see what would happen
and it didn’t change a thing.

The function call RenderCopy (rather than SDL_RenderCopy) which is
implemented by GLES_RenderCopy in SDL_render_gles.c (that’s GLES version 1).
I suppose I can only assume that the problem lies here if there is one…

WilliamOn 30 July 2011 12:30, William Dyce <@William_Dyce> wrote:

I think I’m closing down on the problem: using SDL_image I was able to test
with images with alpha, my theory being that the image must monopolise the
renderer to be draw. Sure enough compositing two images with transparency,
even using NULL, NULL (whole render-surface) for both doesn’t work properly:
I get a black screen.

I’ll keep digging.

On 30 July 2011 02:09, William Dyce <@William_Dyce> wrote:

Dunno - it works fine if the image gets to monopolise the render-srface
but not if if can’t, but I can’t think why that would be. I’ll have a look
at the implementation tomorrow when I’ve had some sleep. Are there any other
ways of blitting images I can try, without using the compat mode (which
doesn’t seem to work on my hardware)?

William

On 29 July 2011 21:36, Forest Hale wrote:

I don’t know anything about the specifics of what is going on there, but
keep in mind that copying image data is not a strongpoint of GLES, perhaps
the SDL_RendererCopy implementation is using functionality not present on
GLES?

On 07/29/2011 04:34 AM, William Dyce wrote:

Hi chaps,

Sorry to both you again, I have a little problem here. The following
works fine, stretching a whole image across the whole screen:
SDL_RenderCopy(renderer, sprite, NULL, NULL);

If I try to specific where to draw the sprite though, that is its
destination rectangle, I get just a black square under Android:
*SDL_RenderCopy(renderer, sprite, NULL, &rect);
*
Under Linux everything works fine. Any idea what might be causing this?

I’m thinking it has to do with how the window’s size is overridden by
the mobile’s screen-size…

William

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/**
darkplaces http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged
demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Eureka! I think I’m really on to something now :slight_smile:

So, the problem occurs when multiple images are blitted one on top of the
other. I was drawing a background texture first, followed by a sprite, then
SDL_RenderPresent:*
// Clear the entire screen to the Renderer’s base colour
SDL_RenderClear(renderer);

// Render the background
SDL_RenderCopy(renderer, background, NULL, NULL);

// Draw the game objects
thing->draw(renderer);

// Flip the buffers to update the screen
SDL_RenderPresent(renderer);*

where Thing::draw(SDL_renderer* renderer) is:

  • static SDL_Rect draw_dest, draw_src;
    draw_dest.x = position.x - size.x/2;
    draw_dest.y = position.y - size.y/2;
    draw_dest.w = size.x;
    draw_dest.h = size.y;
draw_src.x = draw_src.y = 0;
draw_src.w = draw_src.h = 32;

SDL_RenderCopy(renderer, sprite, &draw_src, &draw_dest);*

It seems that I can draw one texture OR the other, but not both one on top
of eachother, unless the second completely covers up the first. Am I using
RenderCopy and RenderPresent the wrong way? And if so, why does it work on
Ubuntu?

William

Now using OpenGL directly:

  • // Clear the entire screen
    glClear(GL_COLOR_BUFFER_BIT);
// Set up position, rotation, colour
glTranslatef(window_size.x/2, window_size.y/2, 0.0);
glRotatef(45.0, 0.0, 0.0, 1.0);

// Bind the texture to which subsequent calls refer to
glBindTexture(GL_TEXTURE_2D, background);

// Start drawing texture
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
GLfloat size[9], coords[9];
glVertexPointer(3, GL_FLOAT, 0, size);
glTexCoordPointer(2, GL_FLOAT, 0, coords);

// Top-left triangle
size = {-16,-16,0, 16,-16,0, 16,16,0};
coords = {0,0, 1,0, 1,1};
glDrawArrays(GL_TRIANGLES, 0, 3);

// Bottom-right triangle
size = {-16,-16,0, -16,16,0, 16,16,0};
coords = {0,0, 0,1, 1,1};
glDrawArrays(GL_TRIANGLES, 0, 3);

// Stop drawing texture
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

// Reset back to the origin
glLoadIdentity();

// Flip the buffers to update the screen
SDL_GL_SwapWindow(window);*

Exactly the same problem is occuring.

WilliamOn 1 August 2011 15:43, William Dyce <@William_Dyce> wrote:

Eureka! I think I’m really on to something now :slight_smile:

So, the problem occurs when multiple images are blitted one on top of the
other. I was drawing a background texture first, followed by a sprite, then
SDL_RenderPresent:
*
// Clear the entire screen to the Renderer’s base colour
SDL_RenderClear(renderer);

// Render the background
SDL_RenderCopy(renderer, background, NULL, NULL);

// Draw the game objects
thing->draw(renderer);

// Flip the buffers to update the screen
SDL_RenderPresent(renderer);*

where Thing::draw(SDL_renderer* renderer) is:

  • static SDL_Rect draw_dest, draw_src;
    draw_dest.x = position.x - size.x/2;
    draw_dest.y = position.y - size.y/2;
    draw_dest.w = size.x;
    draw_dest.h = size.y;
draw_src.x = draw_src.y = 0;
draw_src.w = draw_src.h = 32;

SDL_RenderCopy(renderer, sprite, &draw_src, &draw_dest);*

It seems that I can draw one texture OR the other, but not both one on top
of eachother, unless the second completely covers up the first. Am I using
RenderCopy and RenderPresent the wrong way? And if so, why does it work on
Ubuntu?

William