Sign in to follow this  
PnP Bios

Unity Texture tiling algorithm

Recommended Posts

PnP Bios    494
Topic started in Graphics Programming and Theory I guess this is sort of a cross post, but I think it is warranted. Guys, I need help. For the library I am writing, I need to be able to break up images into multiple chunks, so it can play nice with OpenGL's power of 2 rules. There is that, and I also want it to be able to handle images greater than a video card usualy allows. This will be a feature rich library that you can adapt to SDL, Win32, or any other library once the interface has been ported. But for now, it is just a hunk of source code just sitting on my hard drive. My problem is this... I think that I have the algorithm for finding the UV coordinates down just right, but the problem comes to generating the screen coordinates. The UV was simple, if the block was in full view, then the coordinates would be (0,0)-(1,1), otherwise, it would take the modulus of the chunk size, and divide by the chunk size to get a value between 0 and 1. The screen coordinates are another matter entirely. I can't just make it a multipling function, that would work if it alligned perfectly with the grid, and the destination rect matched the source rect perfectly. But it doesn't in all cases. I know it's the screen coordinates that aren't working properly, because i forced the textures and the poly winding off, and fixed the color, and nothing shows up at all still. Does anybody know where I can find an algorithm for this? or a white paper on it? or anything? I have been googling, but don't have a clue on what to google for... I know it's long, but thanks for reading. And mods, if you feel the need to close a thread, close the original one.

Share this post


Link to post
Share on other sites
Syranide    375
I really don't see why you would need a paper on this, unless I misunderstand you, I think most of this sounds pretty trivial, as splitting an image into chunks and drawing the chunks as one image isn't exactly magic.

I might be the one not understanding, but could you be more specific to _what_ that is the problem? Finding the UV-coordinates for what? (and why)...

Share this post


Link to post
Share on other sites
dimebolt    440
Check out this recent thread. . It discusses some of the issues you may have (as the previous poster I'm not exactly sure what your issues are though).

Tom

Share this post


Link to post
Share on other sites
PnP Bios    494
dimebolt, thanks for the link, but I am looking at a more flexible solution than the one provided there.

Syranide, my problem is that I can't figure out how to handle the screen coordinates for the broken up image.

Share this post


Link to post
Share on other sites
Syranide    375
Quote:
Original post by PnP Bios
Syranide, my problem is that I can't figure out how to handle the screen coordinates for the broken up image.


First thing first, are you working with 2D or 3D?
If working with 2D it should be a piece of cake as you SHOULD be working with an orthogonal projection thus one pixel is one pixel.

Working with 3D could prove more brain teasing, but, really, I don't see the problem here either, if you have a wall, which would come to use 3 textures, then you can split it up in 3 parts, and create 3 new walls, and their coordinates (X,Y,SX,SY) would be interpolated coordinates (from the "real wall"), and the texture coordinates would be clipped according to your needs.

Wrong again?

Share this post


Link to post
Share on other sites
PnP Bios    494
Quote:
Original post by Syranide
Quote:
Original post by PnP Bios
Syranide, my problem is that I can't figure out how to handle the screen coordinates for the broken up image.


First thing first, are you working with 2D or 3D?
If working with 2D it should be a piece of cake as you SHOULD be working with an orthogonal projection thus one pixel is one pixel.

Working with 3D could prove more brain teasing, but, really, I don't see the problem here either, if you have a wall, which would come to use 3 textures, then you can split it up in 3 parts, and create 3 new walls, and their coordinates (X,Y,SX,SY) would be interpolated coordinates (from the "real wall"), and the texture coordinates would be clipped according to your needs.

Wrong again?


Fortunatly, I am working in 2d. I know this should be so incredibly simple, but for some reason, I just can't figure out how to do the screen coordinates. I figure I won't have to worry about scaling and stuff, for when the source rectangle doesn't match the destination rectangle, I can use glScale.

But since it isn't alligned to a grid, the increments are going to be different when things are on the edge slices.

Share this post


Link to post
Share on other sites
dimebolt    440
Quote:
Original post by PnP Bios
Fortunatly, I am working in 2d. I know this should be so incredibly simple, but for some reason, I just can't figure out how to do the screen coordinates. I figure I won't have to worry about scaling and stuff, for when the source rectangle doesn't match the destination rectangle, I can use glScale.

But since it isn't alligned to a grid, the increments are going to be different when things are on the edge slices.


I still feel your question is still lacking some context. What exactly do you mean with screen coordinates (screen coordinates of what?). Are trying to make an API that allows the user to draw a quad with an arbitrary size texture on it? In that case the user will have specified the coordinates of the corners of the quad which can be use in calculating the corners of the subquads. If that's not what you want, please give some more context.

Tom

Share this post


Link to post
Share on other sites
PnP Bios    494
Well, I solved it, I think. I will have to try it with larger images, but it seems to work so far.

void hxSurface::Blit(hxRect sRect, hxRect dRect)
{
float u1, u2, v1, v2; //texture coordinates
float sx, sy, sw, sh; //screen coordinates
float w_inc, h_inc; //width and height of the increment marker

int l, r, t, b; //four edges of the image

l = sRect.x / this->chunk_width;
r = (sRect.x + sRect.w) / this->chunk_width;

t = sRect.y / this->chunk_height;
b = (sRect.y + sRect.h) / this->chunk_height;

glPushMatrix();

glTranslatef(FL(dRect.x), FL(dRect.y), 0.0f);
glScalef(FL(dRect.w)/FL(sRect.w), FL(dRect.h)/(sRect.h), 0.0f);

sx = 0;
sy = 0;

for (int i = t; i <= b; i += 1)
{
h_inc = this->chunk_height;

for(int j = l; j <= r; j += 1)
{
u1 = 0.0f;
v1 = 0.0f;

u2 = 1.0f;
v2 = 1.0f;

w_inc = this->chunk_width;

//do adjustments for UV coordinates
if(j == l)
{
u1 = FL(l % this->chunk_width) / FL(this->chunk_width);
w_inc = (sRect.x % this->chunk_width);
}

if(j == r)
{
u2 = FL(r % this->chunk_width) / FL(this->chunk_width);
w_inc = (sRect.h % this->chunk_width);
}

if(i == t)
{
v1 = FL(t % this->chunk_height) / FL(this->chunk_height);
h_inc = (sRect.y % this->chunk_height);
}

if(i == b)
{
v2 = FL(b % this->chunk_height) / FL(this->chunk_height);
h_inc = (sRect.h % this->chunk_height);
}

sw = w_inc;
sh = h_inc;

//blit object to the screen;
glBindTexture(GL_TEXTURE_2D, this->texList[(this->y_chunk * i)+j]);

glBegin(GL_QUADS);

glTexCoord2f(u1, v1); glVertex2f(sx, sy);
glTexCoord2f(u2, v1); glVertex2f(sx + sw, sy);
glTexCoord2f(u2, v2); glVertex2f(sx + sw, sy + sh);
glTexCoord2f(u1, v2); glVertex2f(sx, sy + sh);

glEnd();

sx = sx + w_inc;

}

sx = 0;
sy = sy + h_inc;
}

glPopMatrix();

return;
}


This seems to work prety well. Now I just have a few more things to figure out and I am good to go.

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