   Smoother Rendering
  Hey all, I've posted many topics related and non related in different places on this forum. So if you've seen my post something like this before. Just remember it most likely had other stuff with it. Im sorry for the multiple posts though. Anyways the graphics relevancy I need is this. Currently my game is rendering, and it does it semi good. The only problem is it only moves the map an entire tile at a time. Where I actually wish for it to render more smoothly. Ive been trying to figure out how to do this for some time with many different ways.Ill be showing you the code in a bit, but currently what I have is two points. I have a logical point, this represents an index value for the point of the array that I should be drawing. The other point represents a device point where the bitmap will be drawn. I need to shift where I start drawing according to how I wish to draw the screen or set an offset. Anyways here is my code perhaps you can optimize it for me. If so that would be agreat help and I appreciate it very very much.//Get the rect area of the entire screenCRect rect;GetClientRect (&rect);//Create a DC for the primary surfaceCClientDC dc (this);// off-screen pixelsCBitmap bmOff;bmOff.CreateCompatibleBitmap (&dc, rect.Width(), rect.Height());//create a memory DC compatible with the primary surfaceCDC memDC;memDC.CreateCompatibleDC (&dc);//make sure to save the old 1x1 BitmapCBitmap * pOldOffBM = memDC.SelectObject (&bmOff);// draw to offscreen DC//memDC.FillSolidRect (&rect, RGB (215, 215, 0)); //desert to buggie on/*No more desert to buggie on, its time to buggie on somethingmore realisitic. Implementing map rendering here.*/// Load bitmap//create an instance of CBitmapCBitmap bmMap;// DCCDC memBitmapDC;memBitmapDC.CreateCompatibleDC(&dc);// load the bitmap resource into the bitmap instancebmMap.LoadBitmap(IDB_DEFAULTMAP);// select the bitmap into the DC (remember to save the old one!)CBitmap * pOldddddddy = memBitmapDC.SelectObject(&bmMap);// This will do the drawingfor(int iWinYPos(-32), iLogicalY((m_cNewBuggie.GetYPos()-(550/2)+64)/32); iWinYPos<576; iWinYPos += 32, iLogicalY++)for(int iWinXPos(-32), iLogicalX((m_cNewBuggie.GetXPos()-(1000/2)+64)/32); iWinXPos<1028; iWinXPos += 32, iLogicalX++){// Our window variables for drawing// We have twenty tilesswitch(m_gmCurrent.iMapTiles[iLogicalY][iLogicalX]){case 0:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 0, SRCCOPY);break;case 1:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 0, SRCCOPY);break;case 2:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 0, SRCCOPY);break;case 3:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 0, SRCCOPY);case 4:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 32, SRCCOPY);break;case 5:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 32, SRCCOPY);break;case 6:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 32, SRCCOPY);break;case 7:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 32, SRCCOPY);break;case 8:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 64, SRCCOPY);break;case 9:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 64, SRCCOPY);break;case 10:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 64, SRCCOPY);break;case 11:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 64, SRCCOPY);break;case 12:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 96, SRCCOPY);break;case 13:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 96, SRCCOPY);break;case 14:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 96, SRCCOPY);break;case 15:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 96, SRCCOPY);break;case 16:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 129, SRCCOPY);break;case 17:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 129, SRCCOPY);break;case 18:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 129, SRCCOPY);break;case 19:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 129, SRCCOPY);break;default:memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 129, SRCCOPY);break;}}memBitmapDC.SelectObject(pOldddddddy);m_cNewBuggie.Render (&memDC);for(int i(0); i < 4; i++)if(m_cbBuggies)m_cbBuggies->RenderOpponent(&memDC, m_cNewBuggie.GetXPos(), m_cNewBuggie.GetYPos());// flip to primarydc.BitBlt (0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);// restore all surfaces/objectsmemDC.SelectObject (pOldOffBM);
  If I follow you could render to a bitmap one tile wider and higher than the screen. You then blit a section of that to the screen. So basically in the last blit rather than always using (0,0) you use a value between (0,0) and (tile.width-1,tile.height-1).   ;  It seems like you have the map stoped in IDB_DEFAULTBMAP and you want to do a smoother scrolling... rather than 'jumping' in steps of 32 (which I guess is happening).The way you have coded it up, you will see jumps in steps of 32.Also, could you please answer some questions:What is the size of the actual map (the bitmap IDB_DEFAULTBMP)? (My guess is 640x640 based on your code)How you expect the scrolling to be done: Do you want the scrolling to stop and when you reach a boundary? Or is it supposed to wrap around? What should you do when the window is bigger than the map size?From a coding perspective, I would suggest you get rid of that switch case and try to calculate the offsets given the value of m_gmCurrent.iMapTiles[logicalX][logicalY]. Probably something like yoff = (m_gmCurrent.iMapTiles[logicalX][logicalY]/4)*8;xoff = (m_gmCurrent.iMapTiles[logicalX][logicalY]% 4) * 32I think we can even get rid of that nested for loop!  But, we can answer your questions better after you answer the above questions. ;  Looking at the code again and LilBudyWizer's response, it looks like you have a 32x32 bitmap which you want to tile the background with.If the game window size is 'nice' (tiles perfectly) and does not change, then you can follow LilBudWizer's solution. Render to a bitmap a tile wider and higher than the window size. _Save it_ (This lets you do the nested for loop just once during the whole life of your program, instead of each frame). Then blit from on offset within (0,0) - (tilewidth, tileheight) which in your case is probably (0,0) - (31,31) (i.e x offset and y offset values of the bitmap are between 0 and 31). For instance, say you have a character 'hero' who is always at the center of the screen. He just moves to the left by x. You then change the x offset the bitmap by x, but doing the operations modulo 32. (i.e modulo the tilewidth). If he moves up by y, you change the y offset of the bitmap by 32 (i.e modulo the tileheight).If you allow the user to change the size of the game window, it gets a little more complicated.;  Okay, the user isn't allowed to change the size of the game window. And I have actually done that, the modulas 32 of their location for the offset. It created even buggier movement, but then again I have alot of problems. Ill keep trying because I agree that should work with the modulas and yea, the bitmap has several tiles in it 32x32 and the switch statement grabs the tiles out properly. If I get it working I'll let you guys know.Wait, I re-read what you wrote and your saying take the tile itself and do the modulas on the tile. That could have been my problem. I've been doing modulas 32 on the actual position. I dont know all I know is when i do that it does not do it properly :p Anyways ill continue trying cause this is a main thing I need to get done. To determine if my hit detection is working.Thanks everyone for the help, and great thanks to a friend who was able to determine what I was doing wrong in my code. My drawing is now smooth and all I have to do is work on getting hit detection working properly once again.[Edited by - Surg AKA Kunark on December 9, 2005 3:40:14 AM]