Jump to content
  • Advertisement
Sign in to follow this  
Fantastic Jason

Rendering parts of a larger texture

This topic is 4437 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

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
Advertisement
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
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
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!