Sign in to follow this  
Fantastic Jason

Rendering parts of a larger texture

Recommended Posts

Thanks for helping in advance... I am writing a tile engine in 2D....Each tile (Quad) is 32 x 32....My Tile Textures are held in a bigger texture that is 512 x 1024....giving me 512 32 x 32 textures....makes sense.... How would I go about calculating the sub image that I want....For example I need the texture rectangle at 38,42 with a size of 15,21........ When I do: glTexCoord2f(38*(1/512), 1.0-(42*(1/1024)))...etc...it seems to not calculate correctly....If I hard code....ie.. glTexCoord(0.0742, 1.0-0.0410) it works okay.....any ideas why?? Does every texture I use need to be to a power of 2??? ie 32 x 32 or 32 x 64..... If so How would I render part of a Tile at the edge of the screen with part of a texture on it....?? Thanks

Share this post


Link to post
Share on other sites
Cubed3    156
Yes they must be powers of 2...
And why are you doing

38*(1/512)? Why not just 38.0f / 512.0f

1.0-(42*(1/1024))? Why not just 1.0f - 42.0f / 1024.0f

Share this post


Link to post
Share on other sites
taby    1265
When you do integer arithmetic like that, the answers by default will be integer, which will eventually cause precision problems due to truncation.

Casting them to float will stop that.

Try this:


glTexCoord2f(static_cast<float>(tile_width)/static_cast<float>(texture_width), 1.0f - static_cast<float>(tile_height)/static_cast<float>(texture_height))








Also, you could multiply by the reciprocal of the divisor to eliminate repetitive division operators. Divisions tend to be more time consuming for the FPU to perform than multiplications.


// calculate this once...
float texture_width_coeff = 1.0f/static_cast<float>(texture_width);
float texture_height_coeff = 1.0f/static_cast<float>(texture_height);

// then, for all tile operations, use the coefficients...
glTexCoord2f(static_cast<float>(tile_width)*texture_width_coeff, 1.0f - static_cast<float>(tile_height)*texture_height_coeff)






For what it's worth, here is the code I use for my tiler. Any reference to "GetIP" is to the image plane, which is essentially the texture_width and texture_height in the code examples above. It also takes into account that the texture size is not evenly divisible by the tile size.

void gl_volume_renderer::rebuild_tiles(void)
{
rebuild_tile_set = false;
recalc_tile_set = true;
render_tiles.clear();

render_tile_2d temp_tile;

size_t current_x_pixel = 0;
size_t current_y_pixel = 0;

size_t num_whole_tiles_across = main_camera.GetIPWidth() / tile_width_pixels;
size_t slack_pixels_across = main_camera.GetIPWidth() % tile_width_pixels;

size_t num_whole_tiles_down = main_camera.GetIPHeight() / tile_height_pixels;
size_t slack_pixels_down = main_camera.GetIPHeight() % tile_height_pixels;

for(size_t i = 0; i < num_whole_tiles_down; i++)
{
current_x_pixel = 0;

for(size_t j = 0; j < num_whole_tiles_across; j++)
{
temp_tile.vp_x_start = static_cast<GLuint>(current_x_pixel);
temp_tile.vp_y_start = static_cast<GLuint>(current_y_pixel);
temp_tile.vp_x_end = static_cast<GLuint>(current_x_pixel + tile_width_pixels - 1);
temp_tile.vp_y_end = static_cast<GLuint>(current_y_pixel + tile_height_pixels - 1);

render_tiles.push_back(temp_tile);

current_x_pixel += tile_width_pixels;
}

if(0 != slack_pixels_across)
{
temp_tile.vp_x_start = static_cast<GLuint>(current_x_pixel);
temp_tile.vp_y_start = static_cast<GLuint>(current_y_pixel);
temp_tile.vp_x_end = static_cast<GLuint>(main_camera.GetIPWidth() - 1);
temp_tile.vp_y_end = static_cast<GLuint>(current_y_pixel + tile_height_pixels - 1);

render_tiles.push_back(temp_tile);
}

current_y_pixel += tile_height_pixels;
}

if(0 != slack_pixels_down)
{
current_x_pixel = 0;

for(size_t j = 0; j < num_whole_tiles_across; j++)
{
temp_tile.vp_x_start = static_cast<GLuint>(current_x_pixel);
temp_tile.vp_y_start = static_cast<GLuint>(current_y_pixel);
temp_tile.vp_x_end = static_cast<GLuint>(current_x_pixel + tile_width_pixels - 1);
temp_tile.vp_y_end = static_cast<GLuint>(main_camera.GetIPHeight() - 1);

render_tiles.push_back(temp_tile);

current_x_pixel += tile_width_pixels;
}

if(0 != slack_pixels_across)
{
temp_tile.vp_x_start = static_cast<GLuint>(current_x_pixel);
temp_tile.vp_y_start = static_cast<GLuint>(current_y_pixel);
temp_tile.vp_x_end = static_cast<GLuint>(main_camera.GetIPWidth() - 1);
temp_tile.vp_y_end = static_cast<GLuint>(main_camera.GetIPHeight() - 1);

render_tiles.push_back(temp_tile);
}
}
}





Edit: Switched to Cubed3's formulae. They work.

[Edited by - taby on April 24, 2006 8:46:15 AM]

Share this post


Link to post
Share on other sites
MARS_999    1627
Quote:
Original post by Foobar of Integers
Textures don't have to be powers of 2 on most modern hardware.


OpenGL2.0 compliant hardware to be exact

Share this post


Link to post
Share on other sites

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