I can't get smooth scrolling, I can't figure out why. I have a resolution of 1024x768. One unit is HORZ or 1024 (I use HORZ and VERT sporadically, I'm in the middle of getting rid of my magic numbers.)
So my hero's speed is 0.5f or half a unit per second or 512 pixels. Whatever you want to call it.
When my update function is like this, scrolling is super smooth. I cut a lot of stuff out before I posted here, I just leave what matters.
void tickmaster(Uint8 *keys, MapBox **icemap, MapBox **lastmap, BasicBox &primo, Iceint &iceblock, WeatherBox &nature, AudioBox *boombox){ Uint32 history; //how much time has passed since last update history=SDL_GetTicks()-primo.elticko; if(history>=1) //monitor is only 60fps probably so why bother updating more { //primo.elticko=SDL_GetTicks(); primo.elticko+=history; switch(primo.istate) //another switch(istate) to execute every cycle { case 1: input(keys, icemap, lastmap, primo, iceblock, history); } }}
See, I say when history is >= 1. It updates every millisecond if it can. But if my monitor is only 60hrtz then updating every millisecond cannot explain the smooth scrolling. If my monitor is 60fps and my guy moves 512 pixels per second, then my map is scrolling about 16 pixels per FRAME. Period. I'm never seeing my map scroll a pixel per frame.
So I tried all the advice above. My update function is like this now:
void tickmaster(Uint8 *keys, MapBox **icemap, MapBox **lastmap, BasicBox &primo, Iceint &iceblock, WeatherBox &nature, AudioBox *boombox){ Uint32 history; //how much time has passed since last update history=SDL_GetTicks()-primo.elticko; if(history>=16) //monitor is only 60fps probably so why bother updating more { //primo.elticko=SDL_GetTicks(); primo.elticko+=history; switch(primo.istate) //another switch(istate) to execute every cycle { case 1: input(keys, icemap, lastmap, primo, iceblock, history); } }}
I figure updating every 16 milliseconds about matches a standard framerate.
My input() funtion called above is like this: (again I'm cutting most of it out)
//blah blah blahelse if(THIS IS THE ONE THAT'S GETTING EXECUTED FOR MOVING TO THE RIGHT){ primo.hero.Gizmove(1,history,(*icemap)->mapgrid); setfx(*icemap,primo);}//blah blah blah
Gizmove goes like this:
switch(idirection){case 1: //right fhor+=fspeed*(float(history)/1000.0f)*float(HORZ);}
fhor is inside the hero's struct. It's a float. fspeed is in his struct. It's 0.5f. history is passed from the update function, it's the milliseconds since the last update. HORZ is 1024
I'm not using tiles, my maps are hand drawn. I say a map has irow rows and icol columns. If icol==3 then the map is 3 screens wide. So I use a floats called fx and fy to scroll around on the map depending on where the hero is. If his X coordinate is under 512 then fx==0 because the map should be scrolled all the way to the left. If his x coordinate is icol*1024-512 or greater then fx==1024*(icol-1) (in other words, scrolled as far to the right as possible)
So that setfx function above, it's like this:
void setfx(MapBox *icemap,BasicBox &primo){ //primo.fxstore=primo.fx; if(primo.hero.fhor<=512.0f) primo.fx=0.0f; else if(primo.hero.fhor<icemap->mapgrid.icol*HORZ-(HORZ/2)) primo.fx=primo.hero.fhor-512.0f; else primo.fx=float(icemap->mapgrid.icol-1)*1024.0f;}
Then when I draw my map I go like this:
/*glPushMatrix(); glTranslatef(-primo.fx,-primo.fy,0.0f); glBegin(GL_POLYGON); glTexCoord2f(0,1); glVertex3f(0,768*icemap->mapgrid.irow,0.0); glTexCoord2f(1,1); glVertex3f(1024*icemap->mapgrid.icol,768*icemap->mapgrid.irow,0.0); glTexCoord2f(1,0); glVertex3f(1024*icemap->mapgrid.icol,0,0.0); glTexCoord2f(0,0); glVertex3f(0,0,0.0); glEnd(); glPopMatrix();*/glBegin(GL_POLYGON); glTexCoord2f(primo.fx/(float(icemap->mapgrid.icol)*1024.0f),(primo.fy+768.0f)/(float(icemap->mapgrid.irow)*768.0f)); glVertex3f(0.0f,768.0f,0.0f); //bottom leftglTexCoord2f((primo.fx+1024.0f)/(float(icemap->mapgrid.icol)*1024.0f),(primo.fy+768.0f)/(float(icemap->mapgrid.irow)*768.0f)); glVertex3f(1024.0f,768.0f,0.0f); //bottom rightglTexCoord2f((primo.fx+1024.0f)/(float(icemap->mapgrid.icol)*1024.0f),primo.fy/(float(icemap->mapgrid.irow)*768.0f)); glVertex3f(1024.0f,0.0f,0.0f); //top rightglTexCoord2f(primo.fx/(float(icemap->mapgrid.icol)*1024.0f),primo.fy/(float(icemap->mapgrid.irow)*768.0f)); glVertex3f(0.0f,0.0f,0.0f); //top left glEnd();
Generally I do it the bottom way, I just grab a rectangle out of my map and only draw on the screen. I tried it the top way just now for the hell of it to see if it made any difference but it didn't. The top way draws the entire map and srolls to the correct place. I don't know a lot about OpenGL, I assume the bottom way is faster and the top way draws stuff you'll never see. But whatever that's not the issue.
Whenever I make 16ms go by between updates the map scrolling is choppy. It's like it jerks across the srceen. But that doesn't make sense because if my monitor is 60 hrtz then when I had 1ms between updates I wasn't seeing every update. The map was scrolling the same amount per frame. So I'm doing something wrong but I don't know what.
Hey also when it's choppy it looks like the screen got sliced horizontally 4 or 5 times and the slices don't line up. I can't see exactly what's happening but it looks like one slice is pushed to the right and the next to the left or something like that. ...I don't know what's going on. I can guess maybe the screen isn't drawn all the way and then it starts drawing a new frame? I don't know.
[Edited by - icecubeflower on September 28, 2008 4:58:43 PM]