Sign in to follow this  
let_eat_bee

SDL and textured RayCasting

Recommended Posts

let_eat_bee    122
Hi! I'm making RayCasting engine on C plus plus with SDL, but there is such a problem. To project texture on the wall I have to know distance and the offset. Then I have to cut texture and resize it(where x=offset, y=0, w=1, h=wall's height). Unfortunately, SDL's function SDL_BlitSurface() doesn't resizes texture. To do it I try to use function zoomSurface(src, zoomx, zoomy, smooth), which is in SDL_rotozomm.h library. But I can't understand how to do it in a proper way, because I tried to do it differently, but nothing works properly. Here is my function:
void DrawScene(ray dist, int i){ 
  int wall; 

  wall=(int) (WALL_HEIGHT / dist.distance * 277); //find wall's height(WALL_HEIGHT=32)
  SDL_Rect scr; //the place, where we want to project texture on the screen
  scr.x=i;
  scr.y=(screen->h - wall) / 2;
  scr.w=1;
  scr.h=wall;

  SDL_Rect ofsrect;
  ofsrect.x=dist.offset;
  ofsrect.y=0;
  ofsrect.h=64; // height of the texture before resizing
  ofsrect.w=1;
  
  SDL_Rect tmprect;
  tmprect.x=0;
  tmprect.y=0;
  tmprect.h=64;
  tmprect.w=1;
    
  int k = (screen->h - wall) / 2;
  if (k < 0){k=0;}
  vlineColor(screen, i, 0, k, 0xff0000FF); //draw ceiling
  SDL_BlitSurface(image, &ofsrect, tmp, &tmprect);  //copy texture's fragment to "tmp Surface"
  tmp = zoomSurface(tmp, 1, wall/64, 1);  //zoom Surface
  tmprect.h=wall; //new height
  SDL_BlitSurface(tmp, &tmprect, screen, &scr); //project texture's fragment on the screen
  vlineColor(screen, i, (screen->h + wall) / 2, screen->h, 0x00FF00FF); //draw floor
}
In this function "image" is the texture, "screen" is the screen:)(video output) and "tmp" is temporary surface. Thank you very much. Hope your advices will be helpful.

Share this post


Link to post
Share on other sites
Jinroh    108
Hi let_eat_bee,

I think it's great that you are doing an SDL Raycaster.

I actually have one I work on every now and again, but true 3D even at the software level I find a ton easier.

Never-the-less, I don't really think that using rotzoom or any SDL Blitter is a great idea for a raycaster. Drawing everything per pixel from your texture map IMO is the better way to go. That way you can draw each pixel exactly the way that you want.

Andre' LaMothe in his one Texture Mapping Mania article wrote some good info on sampling and interpolation of pixels from your texture map.

Your horizontal line drawer would be something to the effect of:


int destinationHeight = bottom - top;

//How Much We Increase the v Pixel Coordinate each time
float samplingRatioV = textureSize / destinationHeight;
//textureSize Assumes your textures are square

float v = 0; //Start from the top pixel of the current column
int u = textureX; //The Column we want to lift pixels from this would be where
//the ray hit your wall from 0 -> wallWidth which is usually 64.

for(int y = top; y < bot; y++) //Loop Through the Column
{
int texV = (int)v & textureSize - 1;
//The X Column of the texture map which shouldn't ever be more
//than texWidth - 1 in a Raycaster, but AND it just to be safe.
int texU = textureX & textureSize - 1;
SDL_PixelOrWhateverItsCalled = getPixelFromTexture(bitmap, texU, texV);
drawPixel(Screen, screenX, y, SDL_PixelOrWhateverItsCalled);
v += samplingRatioV;
}




I've not tested it, but it should take pixels from the specified column, which is whatever x coordinate your ray hit on your wall between 0 and the wall's width. Then it should take pixels from that column dependant on the top and bottom of your wall on the screen and scale them accordingly.

You can find an SDL GetPixel and DrawPixel a lot of places, even on this site I think somewhere in the articles section.

I think that's your best bet though, it's similar to how Christopher Lampton had me do it in Gardens of Imagination anyway.

Hope that helps some.

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