It seems to me that its almost impossible to do pixel-perfect 2D drawings in 3D engines. Obviously the UV-mapping causes errors.
While its ok for scaling, there are situation where one just want to draw a bitmap with the exact size on the screen. Is there a way to do a "pixel-pefect" drawing ?
In my case i have all my gui-imagesin 1 or 2 "big" bitmaps and i want to draw them exactly as they are in the bitmap.
pixel-perfect drawing
Started by AticAtac, Mar 09 2006 09:12 PM
10 replies to this topic
#1
Posted 09 March 2006 - 09:12 PM
#2
Posted 10 March 2006 - 12:17 AM
OpenGL offers a rasterizing interface, look up the glDrawPixels function. Presumably D3D has something similiar. And it's not that hard to achieve a one-one texel-to-pixel mapping - you just have to set identity matrices for the projection, view, etc, turn off bilinear filtering, and be a bit careful with how you set your texture coordinates.
reedbeta.com - developer blog, OpenGL demos, and other projects
#3
Posted 10 March 2006 - 02:48 AM
DrawPrimitiveUp in Directx ... with transformed and lit vertices ... there is absoluetely no problem in drawing pixel-perfect 2d Textures to the screen ...
there is certainly a somewhat similar function in opengl ...
there is certainly a somewhat similar function in opengl ...
#4
Posted 10 March 2006 - 10:59 AM
subtract 0.5 pixel from each uv-coordinate (so for a 256x256 texture you subtract 0.5/256)
It is to do with sampling being done on the centre of the pixel (http://msdn.microsof...s_to_Pixels.asp)
If you do this, you don't have to turn off bilinear filtering.
It is to do with sampling being done on the centre of the pixel (http://msdn.microsof...s_to_Pixels.asp)
If you do this, you don't have to turn off bilinear filtering.
#5
Posted 10 March 2006 - 06:54 PM
Substracting 0.5 is a common mistake many people do !
It fixes some errors and produce new ones !
Update: I just read the article and i am not sure if i understood correctly:
lets say my bitmap has size of w x h
the sub-image in the bitmap i want to draw from is at (x1,y1)->(x2,y2),
so right now i do this:
u1 = x1 / w
v1 = y1 / h
u2 = x2 / w
v2 = y2 / h
according to the article i should do this:
u1 = (x1-0.5f) / w
v1 = (y1-0.5f) / h
u2 = (x2-0.5f) / w
v2 = (y2-0.5f) / h
is that correct ?
It fixes some errors and produce new ones !
Update: I just read the article and i am not sure if i understood correctly:
lets say my bitmap has size of w x h
the sub-image in the bitmap i want to draw from is at (x1,y1)->(x2,y2),
so right now i do this:
u1 = x1 / w
v1 = y1 / h
u2 = x2 / w
v2 = y2 / h
according to the article i should do this:
u1 = (x1-0.5f) / w
v1 = (y1-0.5f) / h
u2 = (x2-0.5f) / w
v2 = (y2-0.5f) / h
is that correct ?
#6
Posted 10 March 2006 - 08:59 PM
yes, that's correct. What sort of problems have you noticed with this? I'm using it myself, and I get a consistent 1 to 1 mapping of texels to pixels.
#7
Posted 10 March 2006 - 09:05 PM
While the drawn bitmap has the right size (of course) the drawn texture on it is missing the right and bottom row.
Could this be a driver issue ? (I got ATI 9600 Pro)
Could this be a driver issue ? (I got ATI 9600 Pro)
#8
Posted 10 March 2006 - 09:14 PM
That's most likely the correct behaviour, as the rasterization convention for directx is to not draw the last pixel. just increase your bitmap size by one on each axis
#9
Posted 10 March 2006 - 09:45 PM
It still doesn't work :(
I try to sum it up here again:
I want to draw a bitmap (x1,y1->x2,y2) stored in a bigger bitmap (w x h) to screen at (sx1,sy1 -> sx2,sy2) w/o scaling which means:
sx2-sx1 = x2-x1 and sy2-sy1=y2-y1
So i first calculate the U/V by
u1 = (x1-0.5f) / w
v1 = (y1-0.5f) / h
u2 = (x2-0.5f) / w
v2 = (y2-0.5f) / h
then i draw my bitmap to: (sx1,sy1 -> sx2+1, sy2+1)
is that correct ?
I try to sum it up here again:
I want to draw a bitmap (x1,y1->x2,y2) stored in a bigger bitmap (w x h) to screen at (sx1,sy1 -> sx2,sy2) w/o scaling which means:
sx2-sx1 = x2-x1 and sy2-sy1=y2-y1
So i first calculate the U/V by
u1 = (x1-0.5f) / w
v1 = (y1-0.5f) / h
u2 = (x2-0.5f) / w
v2 = (y2-0.5f) / h
then i draw my bitmap to: (sx1,sy1 -> sx2+1, sy2+1)
is that correct ?
#10
Posted 10 March 2006 - 10:13 PM
If you're adding one to sx2 and sy2, you should also add one to x2 and y2, i.e. u2 = (x2 + 0.5f) / w and (y2 + 0.5f) / h.
reedbeta.com - developer blog, OpenGL demos, and other projects
#11
Posted 10 March 2006 - 10:23 PM
Reedbeta:
"u2 = (x2 + 0.5f) / w and (y2 + 0.5f) / h" solved the problem !
Thanks to all the helpers here !
"u2 = (x2 + 0.5f) / w and (y2 + 0.5f) / h" solved the problem !
Thanks to all the helpers here !
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users












