# OpenGL Point at which gl size = pixel size

This topic is 3013 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am attempting to find out how to draw sprites in OpenGL in a specific way:

Imagine you have a quad size 32 x 32 (in opengl sizes) directly facing the camera, and it's textured with a 32 x 32 pixel texture, and the quad is travelling away from the camera in the z axis. At some point that quad is going to appear to actually be 32 x 32 pixels in size. What I would like to do is define the point at which the the opengl size is the same as the pixel size. I.e. at -10 from the camera the 32 x 32 quad will be 32 x 32 pixels wide/high. I imagine I need to scale it somehow...

I want the sprites to get bigger or smaller if they are closer/further away from the screen, I just want to be able to define the point at which they render at the correct size.

Any help appreciated

##### Share on other sites
Perhaps you could use orthographic projection? This way objects won't be shrinking in the distance so they'll always keep your size?

##### Share on other sites
I specifically want the objects to scale based on z distance.

##### Share on other sites
Assuming that the quad is already facing the camera and also assuming a symetric frustum projection this means that after the projection the initial quad'x x and y must equal x'(projected) and y'(projected).

x' = x*near/z
y' = y*near/z

this is true only when near / z = 1 so near / z = 1 and so z = 1/near, where near is the distance from the center of projection to the nearplane.

##### Share on other sites
I am not really sure if that is what I am looking for. The reason I think this is because I really think this has some relation to the size of the viewport. Assume for example I found the point z such that a 32 x 32 quad appeared to be 32 by 32 pixels. Render the same quad at the same z distance in a larger/smaller viewport and the quad will appear larger/smaller than 32 x 32 pixels. So clearly we should be talking about ratios of the viewport size.

##### Share on other sites
I asked a similar question here except I wanted to know the size of a texel when Z=0. Ashaman73 gave me a basic algorithm to calculate a texel in world space when using gluPerspective(). Here is my translation to a function.

static inline SizeF getTexelSize(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar){	GLfloat height = tanf(fovy / 2.0f) * zNear;	GLfloat width = height * aspect;		SizeF texelSize = SizeFMake(width / SCREEN_WIDTH, height / SCREEN_HEIGHT);		return texelSize;}

I'm not entirely sure if it's correct, but supposedly it gives a texel size when Z=0. Not exactly what you were after but it may help?

##### Share on other sites
I think this could actually be useful

static inline SizeF getTexelSize(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar){	GLfloat height = tanf(fovy / 2.0f) * zNear;	GLfloat width = height * aspect;		SizeF texelSize = SizeFMake(width / SCREEN_WIDTH, height / SCREEN_HEIGHT);		return texelSize;}

Basically I think I need to work out how height and width change based on z distance so I would take this

GLfloat height = tanf(fovy / 2.0f) * zNear;
GLfloat width = height * aspect;

and formulate

GLfloat heightAtZ = f( z ) * height
GLfloat widthAtZ = aspect * heightAtZ

Where z is the z distance and f calculates the scale factor at z.

I then want to solve the equations

widthScale * SCREEN_WIDTH / widthAtZ = 1
heightScale * SCREEN_HEIGHT / heightAtZ = 1

i.e

widthScale = widthAtZ / SCREEN_WIDTH
heightScale = heightAtZ / SCREEN_HEIGHT

(this is the texels/pixel ratio)

I believe the height equation is wrong, that's only half the height. so it should be

height = 2 * tanf(fovy / 2.0f) * zNear;

I also think that by using similar triangles, f( z ) = 1 + z/nearPlane

Which would yield a function like:

static inline SizeF getSpriteSize(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar, int pixelWidth, int pixelHeight, GLfloat zRealSize ){	GLfloat height = 2 * tanf(fovy / 2.0f) * zNear;        GLfloat heightAtZ = ( 1 + zRealSize/zNear ) * height;        GLfloat widthAtZ = aspect * heightAtZ;                GLfloat heightScale = heightAtZ/SCREEN_HEIGHT;        GLfloat widthScale = heightAtZ/SCREEN_WIDTH;        GLfloat spriteHeight = heightScale * pixelHeight;        GLfloat spriteWidth = widthScale * pixelWidth;        	SizeF spriteSize = SizeFMake( spriteWidth, spriteHeight );		return spriteSize;}

I think this function should give me the width and height of the quad to draw so that when I draw a sprite at distance z it is pixelWidth by pixelHeight in size. It would also maintain the aspect ratio of the sprite itself if it works correctly.

[Edited by - MoonDemon on July 22, 2010 1:26:39 PM]

##### Share on other sites
Here are the two functions I ended up with

static inline SizeF getTexelSize(GLfloat fovy, GLfloat zoom){	GLint viewPort[4];	glGetIntegerv(GL_VIEWPORT, viewPort);	GLfloat screenWidth = viewPort[2], screenHeight = viewPort[3];	GLfloat height = tanf((fovy * M_PI / 180.0f) / 2.0f) * zoom * 2.0f;	GLfloat width = height * (screenWidth / screenHeight);		SizeF texelSize = SizeFMake(width / screenWidth, height / screenHeight);		return texelSize;}static inline SizeF getScreenSize(GLfloat fovy, GLfloat zoom){	GLint viewPort[4];	glGetIntegerv(GL_VIEWPORT, viewPort);	GLfloat screenWidth = viewPort[2], screenHeight = viewPort[3];	GLfloat height = tanf((fovy * M_PI / 180.0f) / 2.0f) * zoom * 2.0f;	GLfloat width = height * (screenWidth / screenHeight);		return SizeFMake(width, height);}

1. 1
Rutin
46
2. 2
3. 3
4. 4
5. 5
JoeJ
19

• 11
• 14
• 9
• 10
• 12
• ### Forum Statistics

• Total Topics
633004
• Total Posts
3009833
• ### Who's Online (See full list)

There are no registered users currently online

×