|
|
This thread is locked; no one can reply to it.
|
1
2
|
| Mapping a texture on a sphere. |
|
Johan Peitz
Member #9
April 2000
|
I planning a game where the player rolls balls around. Very exciting. Anyway, I need to map a texture on a 2d circle so that it looks like a ball in 3d. The texture is 64x64 in this case and the ball is a circle with a radius of 16 pixels. What I would like is a lookup table for the circle so I know what pixel to draw from the texture. Has anyone got some cool mathematic formulas or something for this? I'm pretty sure someone has posted a question like this before and that someone else wrote something with a picture of the earth mapped on a circle... Any ideas? -- |
|
Shade
Member #1,152
April 2001
|
Maybe the easiest way is to use a rotating sprite... formulas with sin/cosine are nice but you can't really use then to fill an entire circle. If you do something like this: for (r=0;r<50;r++){ you'll see that there are points missing. Shade8-) |
|
Johan Peitz
Member #9
April 2000
|
Hmm... Maybe I didn't express myself very clear. I don't want to simply rotate a sprite. I want to wrap a texture around a ball. The thought was to create a lookup table for a circle and the map the texture to the circle. The effect of getting the ball to roll would be achieved by shifting the texture. But! How to I calculate the lookup? -- |
|
Paul Pridham
Member #250
April 2000
|
Johan, I think I have some old Allegro demo code of this very thing. I will find it on my HD later tonight and let you know. ---- |
|
Gabhonga
Member #1,247
February 2001
|
also there's this library once made for allegro, maybe it was plush or p3d...whatever, it had several routines for rendering "3d" spheres, i.e. the all-famous, vectorballs having their textures projected and even shaded in different ways. it doesn't include perspective warp, but you don't actually notice that for spheres unless they're very close, or your fov is very twisted. -------------------------------------------------------- |
|
Oscar Giner
Member #2,207
April 2002
|
You could use ray-tracing. With this technique you can get perfect spheres, because it uses the sphere formula. I don't know how to do it, maybe someone can help you. -- |
|
Bob
Free Market Evangelist
September 2000
|
I posted code to do this on [AGP] a little while ago. I'm not at my computer (for a few months), so I can't send it to you. Perhaps you can ask there if someone still has a copy of it. -- |
|
Fladimir da Gorf
Member #1,565
October 2001
|
How come I was just asking the same question? If I remember corrent the concept I'm using is: For every upleft pixel: Count the current radius. Divide it with the maxium radius to get the number 'm'. Now, use a special function (I've got a wrong one) which gets the number 'm' and produces the number 'n'. Now we divide 'n' with 'm' and get the number 'k'. Then, the current upright position where we'll read the color is (centreX -k * (centreX -currentX), centreY -k * ( centreY -currentY )). OK I somehow think I didn't get it correct. But what is this function that takes 'm' and returns 'n'? OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
|
Gabhonga
Member #1,247
February 2001
|
hmm...if anyone finds a good sollution/explanation to this problem, please post info here! -------------------------------------------------------- |
|
Fladimir da Gorf
Member #1,565
October 2001
|
"maybe it was plush or p3d" I searched for both of them and it heavily seems they used 3D code and an older allegro version (and even DJGPP makefiles I think...) So....? OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
|
Thomas Fjellstrom
Member #476
June 2000
|
wasn't p3d slurped up by allegro? Or did it get removed? -- |
|
Bob
Free Market Evangelist
September 2000
|
Yes, p3d was merged into Allegro. However, p3d did NOT do sphere mapping of any kind. -- |
|
Gabhonga
Member #1,247
February 2001
|
hmm, it could be that it was called "more3d". yes, it's quite old, but it had this textured sphere rendering code that wasn't actually fast, but worked fine :-) -------------------------------------------------------- |
|
Johan Peitz
Member #9
April 2000
|
Ok ppl, here's some results then. 1) Paul Pridham mailed me some code by a guy named David Lenhart. I haven't really looked at it that much and I haven't managed to compile it, it uses some old version of allegro I think and I didn't bother. Get it here: [url http://www.dtek.chalmers.se/~d98peitz/junk/earth.zip] 2) My own version. Using lookup tables and is not very mathematically correct, but it's fast enough and looks ok. Instead of sphere-mapping I apply some kind of lens filter to the texture and shows. Get it here: [url http://www.dtek.chalmers.se/~d98peitz/junk/balls.zip] Feel free ta ask questions and/or come with imporvements. -- |
|
Gabhonga
Member #1,247
February 2001
|
hehe well, and I finally remembered (& then searched my hd, and even found!!!) the library that was able of doing "3d" spheres!! actually the code is quite messy to read, but it works and it's also quite good commented...the name was AllegPak!! (har, the only one allegro 3d lib I hadn't mentioned yet -------------------------------------------------------- |
|
Steve Terry
Member #1,989
March 2002
|
hmm, well anyone got a MingW32 edition of the code. I erased my DJGPP compiler because windowsXP forced me to.... or do you at least have an executable I can look at so maybe I can rewrite it if the effect looks good. ___________________________________ |
|
Plucky
Member #1,346
May 2001
|
Some years back I played with a spherical texture mapping algorithm using lookup tables that was developed by a Hans Kopp. I apparently don't have his original source, but I found my variation of his algorithm written for Allegro. His algorithm in a nutshell: It is relatively easy to wrap a texture on a sphere for rotations about the sphere's N-S pole axis. For this you need a lookup table from pixel coordinate to spherical coordinate. Add the rotation (longitude), and finally convert spherical to texture coordinates. The problem is when you want the sphere to rotate on all 3 axis. Hans' solution was to recognize the ease of rotating on a N-S pole axis and so created a lookup table that transformed a spherical coordinate such that one of the E-W axis is rotated to the N-S axis. After the coordinate system transformation, just add the now-longitudinal rotation. Perform this transformation once more, and you have rotation for all 3 axes.
|
|
Eric Love
Member #846
December 2000
|
Just this week I made a small program which draws a globe if you give it a rectangular world map. |
|
Kloks
Member #943
February 2001
|
|
Steve Terry
Member #1,989
March 2002
|
Pucky's code works great too, and you can use spheres of any size, it also runs a bit slow, but if you cange teh putpixel to a direct memory access and maybe the sqrt() function in draw sprite to a fixed point notation some speed might be improved.. though it ran fast enough for me. I got about 140fps with a radius of 128, and 70fps at radius of 256, that fills the entire screen at 640x480. The effect is good, and you can rotate on all three axis. Problems with code called like: InitLookupTables(); texture = (unsigned short *)malloc(sizeof(short) * TEX_SIZE * TEX_SIZE); CreateTextureTable("Earth2.bmp", texture); do{ clear(buffer); DrawSphere(phi, theta, psi, radius, texture, buffer, SCREEN_W >> 1, SCREEN_H >> 1); blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); }while(!key[KEY_ESC]);
___________________________________ |
|
Johan Peitz
Member #9
April 2000
|
Kloks, glad you like it. It is not by any means a very stringent way to solve the problem. Also, it does not map a texture on a sphere. It's more like a lens funciton on a texture, giving the impression of a ball. This is mostly noticeable on the red/white squared ball. All squares are really squares, and this is not possible on a sphere. Feel free to use what ever you want of the code. -- |
|
Plucky
Member #1,346
May 2001
|
Sorry about the sloppy code. I just lifted it out my test code, and obviously spent little time cleaning it up. Thanks Steve for picking through it and cleaning it up. I had TEX_SIZE and SIZEOFTEX, which are the same. I commented out *texture because the code could handle more than one. Quote: texture size must be 256x256x16, but it looks great anyway. Actually not quite true. The texture table is size TEX_SIZE x TEX_SIZE x 16. But when loading a texture, the texture could be of any size... it would just get crudely stretched to TEX_SIZE x TEX_SIZE. Also you can change the color depth of the texture table as well. A better stretching algorithm would improve the look of the texture. Also the element size of the texture table need not be 16 bits; it could be 8 bit or 32 bits depending on color depth. TEX_SIZE is limited to 256 because it is stuffing two numbers into a short. TEX_SIZE can be expanded to 65536 if the lookup table was a 32 bit array. However you run the risk of the table not fitting in memory cache. Also the code makes no distinction between texture size TEX_SIZE and the number of bits occupied by the low and high order data when stuffing the two values into one. A few tweaks and you can make this distinction such that TEX_SIZE need not be a power of 2. Quote: psi, theta, and phi range between 0 and 255, going over will trash the look-up tables and the program. Should have pointed this out earlier. Somewhere in the code, one should have psi %= TEX_SIZE; or the equivalent. Quote: if you cange teh putpixel to a direct memory access and maybe the sqrt() function in draw sprite to a fixed point notation some speed might be improved You can unroll the loop a bit along with direct memory access to increase speed. For example with 16 bit color:
Obviously you can do the same with 8 bit color by unrolling the loop 4 times. |
|
Steve Terry
Member #1,989
March 2002
|
hehe, cool, well it doesn't give much of a speed-up using the 32 bit packed way, and oddly it gives some weird fuzzy stuff around teh pixel blocks the other one doesn't have. That's okay anyway. But now i'm wondering if anyone has any tutorials on how to do the packed routines. I've tried incorperating them in other functions I've made and it doesn't quite work. My way was just doing this: ___________________________________ |
|
Bob
Free Market Evangelist
September 2000
|
Steve: I did write an article about this. -- |
|
Steve Terry
Member #1,989
March 2002
|
hehe yeah i've seen that code before, yes it takes one pixel and fades it by a factor from 0 to 32. I think it was used in fade16.c which worked ok. I think i'll just have to play with the code a bit more. I also had an example of blending two colors using the same technique, but I misplaced it or something. ___________________________________ |
|
|
1
2
|