Rendering parts of a larger texture

Started by
3 comments, last by MARS_999 17 years, 11 months ago
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
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
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]
Textures don't have to be powers of 2 on most modern hardware.
"ok, pac man is an old gameand, there are faces which is eatin up shits" - da madface
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

This topic is closed to new replies.

Advertisement