Sign in to follow this  

Texture atlas source rectangles and drawing models?

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wish to draw a model using a texture found in a texture atlas. The atlas gives me the source rectangle which denotes the texture location in the atlas.

How can I set the correct uv coordinates for the model based on the source rectangle so that it draws only the texture encompassed by the source rectangle?

Share this post


Link to post
Share on other sites
You mean drawing a model like a box that fetches its texture from an atlas where multiple models are drawed? In that case, that should be pretty easy. You could:
- Just alter the UV coordinates in the original model
- Shift/scale texcoords. Let's say you draw a quad where the coordinates are normally 0(bottom left) to 1(top right). But now that texture only takes 25% of a bigger atlas, and is placed in the top-right corner. In that case:
texcoords.xy *= 0.25; // scale
texcoords.xy += 0.50; // shift

You can do this by passing the scale/shift factors to a shader. Or do it in the texture matrix. In OpenGL it would be something like

glMatrixMode(GL_TEXTURE);
glTranslatef( offsetU, offsetV, 0.0);
glScalef( scaleU, scaleV, 1.0);
glMatrixMode(GL_MODELVIEW);


Rick

Share this post


Link to post
Share on other sites
Quote:
Original post by spek
You mean drawing a model like a box that fetches its texture from an atlas where multiple models are drawed?


That's correct. The atlas has many textures, each denoted by a source rectangle. Is wish to draw many models with different textures.

I have the uv coordinates of the texture from the source rectangle.

If I pass the corners of the rectangle into a HLSL shader then I wish to manipulate the shift/scale the original texture coordinates so they display the correct texture based on the rectangle passed in.

I thought about:


input.TextureCoordinates.x *= (rectWidth / textureWidth); // Scale
input.TextureCoordinates.x += (rectTopX / textureWidth); // Shift

input.TextureCoordinates.y *= (rectHeight / textureHeight);
input.TextureCoordinates.y += (rectTopY / textureHeight);



but that isn't correct.

Share this post


Link to post
Share on other sites
I've got it working now. I was using integers instead of floating points.

Is this an efficient way to set the source rectangle data for HLSL each time a meshpart is drawn?


Rectangle srcRect = game.TextureAtlas.Rectangles[boxModel.Texture];

Vector4 srcRectProperties = new Vector4();
srcRectProperties.X = srcRect.X;
srcRectProperties.Y = srcRect.Y;
srcRectProperties.Z = srcRect.Width;
srcRectProperties.W = srcRect.Height;

effect.Parameters["SourceRectangle"].SetValue(srcRectProperties);



The only other way I could think of was as four separate floats but I'm open to ideas for improvements.

Share this post


Link to post
Share on other sites
Don't know GLSL, but I assume that is how you pass the rect to the shader? In that case, that is just fine. And probably a tiny little bit better than passing 4 separate floats. This is how I do it as well for packing multiple shadowMaps into 1 texture.

Cheers
Rick

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this