How do I draw a sprite the cool way? (Ouch, my textures!)

RujiK

Member
Do I have mushy brain syndrome? I'm trying to draw a sprite from inside a texture page but the UV's seem to be way off. It draws a distorted image from a different part of the texture page.

Code:
ww = sprite_get_width(_sprite);
hh = sprite_get_height(_sprite);

_texture = sprite_get_texture(_sprite,0);
uvs = sprite_get_uvs(_sprite,0);
_l = uvs[0]; //left
_t = uvs[1]; //top
_r = uvs[2]; //right
_b = uvs[3]; //bottom


draw_set_color(c_white);
draw_primitive_begin_texture(pr_trianglelist,_texture)

draw_vertex_texture(xx,yy,_l,_t);
draw_vertex_texture(xx+ww,yy,_r,_t);
draw_vertex_texture(xx+ww,yy+hh,_r,_b);

draw_vertex_texture(xx+ww,yy+hh,_r,_b);
draw_vertex_texture(xx,yy+hh,_l,_b);
draw_vertex_texture(xx,yy,_l,_t);

draw_primitive_end();
The code is very simple so I'm really lost at what I'm doing wrong. Any help would be greatly appreciated. (Generous upvotes if that is any incentive to help.)
 

Lonewolff

Member
I tested this out and see what you mean.

It seems strange, because if you do this it works fine, even with multiple different sprites on the texture page.

Code:
draw_vertex_texture(xx,yy, 0.0, 0.0);
draw_vertex_texture(xx+ww,yy, 1.0, 0.0);
draw_vertex_texture(xx+ww,yy+hh, 1.0, 1.0);

draw_vertex_texture(xx+ww,yy+hh, 1.0, 1.0);
draw_vertex_texture(xx,yy+hh, 0.0, 1.0);
draw_vertex_texture(xx,yy, 0.0, 0.0);
Maybe sprite_get_texture(_sprite,0) make a copy of the texture, or perhaps even sorts out the UV's behind the scenes somewhere to make them normalised again? Dunno. :confused:
 

CloseRange

Member
@RujiK
there isn't a good reason for this that I know of but it has to do with how game maker does the whole drawing uv's with textures.
normally when you do draw_vertex_texture the point (1, 1) represents the bottom right of the whole image. But nope for texture pages like this it seems that (1, 1) represents the bottom right of the first image in the page.
That's why what @Lonewolff worked, nothing was copied or normalized or sorted, just a dumb thing game maker does.
anyway this is avery easy fix. change where you set _l _t _r and _b to this:
Code:
_l = uvs[0]*(1/texture_get_texel_width(_texture))/ww; //left
_t = uvs[1]*(1/texture_get_texel_width(_texture))/hh; //top
_r = uvs[2]*(1/texture_get_texel_width(_texture))/ww; //right
_b = uvs[3]*(1/texture_get_texel_width(_texture))/hh; //bottom
texture_get_texel is a.... weird one at best. It's how texture pages are sized (instead of pixels for whatever reason) but if you want to convert from texel's to pixels then you do 1/texelSize
and then we just take that number, devided by width and height respectivly (this will get us how many images, or cells... i guess?, are in the texture)
take that and multiply it by the uv's to get the correct uv's
 

NightFrost

Member
Texel, I recall, is the size of a single pixel on a texture page. The page size in pixels varies depending on how graphics are stacked there, but the GPU will always want its size as running from 0 to 1 so it divides 1.0 by page's pixel dimensions to arrive at texel size. So when you go in reverse, taking 1.0 and divide by texel width and height, you get the texture page width and height, respectively, in pixels. (A quick test appears to confirm this.)
 

RujiK

Member
Thanks guys! I wasn't sure if I was going to have more issues so my thank you is a little late. Extra thanks to @Lonewolff , I didn't realize that sprite_get_texture function returned anything other than the texture page. Seems weird to me, but it works.

@CloseRange I'm probably messing something up, but I tried pasting your code and it did not work for primitives. Primitives seems to want 0 and 1 values like lonewolf said.

Thanks again though guys, everything is dandy now :D
 
Top