🔒 Locked
Scrolling
Advertisement
Original Post
Howzit
What is the best way to do scrolling in OpenGL?
At the moment I use glTranslatef and it works fine, but when I put another object on the screen it doesn''t scroll. So what I did then was add/substract the same amount that the ground moves from the model. That works but it looks like the model is moving on the ground.
I''m using
gluPerspective(45.0f, (float) Display.getWidth() / (float) Display.getHeight(), 1.0f, 10000.0f)
for the default view
Why not simply use the camera?
Simply translate the camera in the opposite direction to the direction you want to scroll.
Simply translate the camera in the opposite direction to the direction you want to scroll.
quote:
Original post by noisecrime
Why not simply use the camera?
Simply translate the camera in the opposite direction to the direction you want to scroll.
that''s an interesting idea, considering that the "camera" doesnt exist and would only change the modelview in a way to move everything the other way. so moving the camera the other way would have exactly the same result as translating the rest in the right direction in the first place ,-)
btw. if glulookat doesnt work and gltranslate is giving you trouble its the perfect time to learn about the modelview matrix, what it does and why it matters WHEN you call these functions. if you want to scroll (assuming that means move EVERYTHING) then translate should be the very first thing you call after setting up your view (if you do that at all and dont just use the identity)
That''s cool but why does the object look like it''s moving on the ground.
I''ve got 2 translatef''s in two methods. One a background and one a 3D imported model of a building. If I press for example ''A'' then I add 5 onto the background and I subtract 5 from the model. This gives the effect that you are moving away from the building but it also looks like the building moving on the ground and I think it is because I have a texture on the ground and the building does not stay in the same position.
The ground does move away as well.
Why would it do this if I add and subtract the same amount?Surely they should both move together.
I''ve got 2 translatef''s in two methods. One a background and one a 3D imported model of a building. If I press for example ''A'' then I add 5 onto the background and I subtract 5 from the model. This gives the effect that you are moving away from the building but it also looks like the building moving on the ground and I think it is because I have a texture on the ground and the building does not stay in the same position.
The ground does move away as well.
Why would it do this if I add and subtract the same amount?Surely they should both move together.
Mr.Ridd wrote
''That''s cool but why does the object look like it''s moving on the ground.''
Err, becuase you''re making it move along the ground.
You say you move the ground in one direction (+5 units) and a model in the opposite direction (-5units), so I don''t understand why you think the model should stay relative to the ground at all. I mean try it, grab a piece of paper and draw some lines across it, then stick an object on top like a cup. Now move the paper one direction, and the cup in the other.
Like I said, unless I''ve misunderstood what you''re trying to achive, you should really be using the camera for this. You should not move the ground or models at all (unless the model is itself moving (i.e. a vehicle) and instead move the camera.
To do this in openGL i''d imagine you''d need a camera matrix (from your own matrix lib) that is just the position and rotation of the camera. Then apply this when setting up your modelview matrix. Now when you want to scroll, simply translate the camera matrix and you''ll get the effect you are after.
''That''s cool but why does the object look like it''s moving on the ground.''
Err, becuase you''re making it move along the ground.
You say you move the ground in one direction (+5 units) and a model in the opposite direction (-5units), so I don''t understand why you think the model should stay relative to the ground at all. I mean try it, grab a piece of paper and draw some lines across it, then stick an object on top like a cup. Now move the paper one direction, and the cup in the other.
Like I said, unless I''ve misunderstood what you''re trying to achive, you should really be using the camera for this. You should not move the ground or models at all (unless the model is itself moving (i.e. a vehicle) and instead move the camera.
To do this in openGL i''d imagine you''d need a camera matrix (from your own matrix lib) that is just the position and rotation of the camera. Then apply this when setting up your modelview matrix. Now when you want to scroll, simply translate the camera matrix and you''ll get the effect you are after.
Ok don''t worry about what I plus and minus. The ground and the building are moving in the same direction. It''s not like they moving oposite from one another. I''m not actually moving the ground and building, I''m adding or subtracting from a variable that I pass into glTranslatef.
I think I might have found out what the problem is though. I think it looks like it''s moving on the ground because the distance between the ground and the building is different.
I adjusted some stuff and I got it to look a bit better but it''s still not perfect.
I think I might have found out what the problem is though. I think it looks like it''s moving on the ground because the distance between the ground and the building is different.
I adjusted some stuff and I got it to look a bit better but it''s still not perfect.
if you want to move ground and building i dont see why you would call gltranslate twice. call it ONCE and before you draw either of them. your matrix isnt reset after drawing and the first translation still applies. translating it BACK would only make the object stay in position but move the ground without it and as long as your building isnt hanging from a helicopter i''d guess its supposed to move with the ground. it would really help if you post some code (SOME, ie the relevant code from cleaning the color buffer to switching buffers).
still, i dont see the reason to do:
camera.move(left);
camera.invert();
camera.loadAsModelView(); //do the opposite to the scene
instead of
scene.move(right);
still, i dont see the reason to do:
camera.move(left);
camera.invert();
camera.loadAsModelView(); //do the opposite to the scene
instead of
scene.move(right);
Here''s the code to draw the background...
static final int XCO = 500;
static final int YCO = 400;
static int startX = 0, endX = 0;
static int startY = 0, endY = 0;
public static void drawBackground(int w, int h, float tx, float ty, float tz)
{
int west = w*(XCO*2)*-1;
int east = w*(XCO*2);
int south = h*(YCO*2)*-1;
int north = h*(YCO*2);
startX = west-XCO;
endX = east;
startY = south-YCO;
endY = north;
int tileAmountX = (((startX*-1)+endX)/(XCO*2))+1;
int tileAmountY = (((startY*-1)+endY)/(YCO*2))+1;
float tempStartX = (float)startX;
float tempEndX = (float)(startX+(XCO*2));
float tempStartY = (float)startY;
float tempEndY = (float)(startY+(YCO*2));
int textureCount = 0;
for(int y = 0; y < tileAmountY; y++)
{
for(int x = 0; x < tileAmountX; x++)
{
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
GL.glBindTexture(GL.GL_TEXTURE_2D, background);
GL.glBegin(GL.GL_QUADS);
GL.glTexCoord2f(0.0f, 0.0f);
GL.glVertex3f(tempStartX, tempStartY, -10.0f);
GL.glTexCoord2f(1.0f, 0.0f);
GL.glVertex3f(tempEndX, tempStartY, -10.0f);
GL.glTexCoord2f(1.0f, 1.0f);
GL.glVertex3f(tempEndX, tempEndY, -10.0f);
GL.glTexCoord2f(0.0f, 1.0f);
GL.glVertex3f(tempStartX, tempEndY, -10.0f);
GL.glEnd();
textureCount++;
tempStartX = tempStartX+(XCO*2);
tempEndX = tempEndX+(XCO*2);
}
tempStartY = tempStartY+(YCO*2);
tempEndY = tempEndY+(YCO*2);
tempStartX = (float)startX;
tempEndX = (float)(startX+(XCO*2));
}
}
The tx, ty, tz values I increase/decrease when a certain key is pressed.
*background is a texture
Now for the building I''ve got a class of which I have another glTranslatef witch accepts the same tx, ty, tz.
Hope you know this is in Java.
static final int XCO = 500;
static final int YCO = 400;
static int startX = 0, endX = 0;
static int startY = 0, endY = 0;
public static void drawBackground(int w, int h, float tx, float ty, float tz)
{
int west = w*(XCO*2)*-1;
int east = w*(XCO*2);
int south = h*(YCO*2)*-1;
int north = h*(YCO*2);
startX = west-XCO;
endX = east;
startY = south-YCO;
endY = north;
int tileAmountX = (((startX*-1)+endX)/(XCO*2))+1;
int tileAmountY = (((startY*-1)+endY)/(YCO*2))+1;
float tempStartX = (float)startX;
float tempEndX = (float)(startX+(XCO*2));
float tempStartY = (float)startY;
float tempEndY = (float)(startY+(YCO*2));
int textureCount = 0;
for(int y = 0; y < tileAmountY; y++)
{
for(int x = 0; x < tileAmountX; x++)
{
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
GL.glBindTexture(GL.GL_TEXTURE_2D, background);
GL.glBegin(GL.GL_QUADS);
GL.glTexCoord2f(0.0f, 0.0f);
GL.glVertex3f(tempStartX, tempStartY, -10.0f);
GL.glTexCoord2f(1.0f, 0.0f);
GL.glVertex3f(tempEndX, tempStartY, -10.0f);
GL.glTexCoord2f(1.0f, 1.0f);
GL.glVertex3f(tempEndX, tempEndY, -10.0f);
GL.glTexCoord2f(0.0f, 1.0f);
GL.glVertex3f(tempStartX, tempEndY, -10.0f);
GL.glEnd();
textureCount++;
tempStartX = tempStartX+(XCO*2);
tempEndX = tempEndX+(XCO*2);
}
tempStartY = tempStartY+(YCO*2);
tempEndY = tempEndY+(YCO*2);
tempStartX = (float)startX;
tempEndX = (float)(startX+(XCO*2));
}
}
The tx, ty, tz values I increase/decrease when a certain key is pressed.
*background is a texture
Now for the building I''ve got a class of which I have another glTranslatef witch accepts the same tx, ty, tz.
Hope you know this is in Java.
quote:
Original post by Mr_Ridd
Hope you know this is in Java.
i was hoping that. i cant tell about c# but i wouldnt know any other language being sadistic enough to force you to write public/private in front of everything all the time.
ok, first of, promise to never ever place
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
GL.glBindTexture(GL.GL_TEXTURE_2D, background);
GL.glBegin(GL.GL_QUADS);
inside a loop, let alone two nested loops if you dont absolutely have to.
static final int XCO = 1000;
static final int YCO = 800;
int endX = w*XCO;
int startX = -endX -XCO/2;
int endY = h*YCO;
int startY = -endY - YCO/2;
GL.glPushMatrix(); /*dont mess with the modelview without saving it first, except you absolutely know that this part will always be the first you call... also: if you set up your view (glulookat for example) you just screwed that and threw it out the window without pushing it onto the stack first)*/
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
GL.glBindTexture(GL.GL_TEXTURE_2D, background);
GL.glBegin(GL.GL_QUADS);
for(float y = startY; y < endY; y+=YCO) {
for(int x = startX; x < endX; x+=XCO) {
/*why were you even using a for loop if you didnt use the counter variables anyway?*/
GL.glTexCoord2f(0.0f, 0.0f);
GL.glVertex3f(tempStartX, tempStartY, -10.0f);
GL.glTexCoord2f(1.0f, 0.0f);
GL.glVertex3f(tempStartX+XCO, tempStartY, -10.0f);
GL.glTexCoord2f(1.0f, 1.0f);
GL.glVertex3f(tempStartX+XCO, tempStartY+YCO, -10.0f);
GL.glTexCoord2f(0.0f, 1.0f);
GL.glVertex3f(tempStartX, tempStartY+YCO, -10.0f);
}
}
GL.glPopMatrix();
now that its slightly shorter and giving me less of an headache trying to track those values being passed over a dozen variables (can you tell i just love messing with other peoples code? *fg*).. this part seems fine, except calling loadidentity without backing up the modelview first. no surprise glulookat didnt work for you if you just throw away the changes it made.
if you want to scroll, call translate ONCE and before you start drawing the ground or anything else. DONT change the position of every single object yourself. chances are, that your ground will never be moving at all (except you care about earthquakes and plate tectonics), so passing tx,ty,tz should be pointless and you can drop that whole
GL.glPushMatrix();
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
...
GL.glPopMatrix();
later you might want to NOT draw the whole ground, but only whats visible. for the simple case of scrolling in tile-sized steps you loop over the ground tiles beginning at the right position and always draw at the same position (left edge of viewport to right etc.). probably overcomplicated for smooth scrolling:
offsetX, offsetY, transX, transY;
you add the movement to the trans variables and check against tileSize.
if (transX<0) {transX+=tileSize; --offsetX;}
if (transX>tileSize) {transX-=tileSize; ++offsetX;}
when drawing you draw the tiles from offsetX to offsetX+numTiles at topLeft-transX. if you want to also rotate your view its getting a little more complicated and you can either cull single tiles or make sure you draw a big enough part of the ground (simpler but wasteful, though once you do that advanced graphics stuff to cause trouble you wont have problems to find a good solution).
a general note: try not to use a dozen variables all over the place just to pass something through them and not use them again after that. its making your code a pain to follow (readability) its doing pointless allocations on the stack (performance) and its making it hard to spot bugs (stability).
also: is there some kind of weird aversion against using -variable thats causing all that variable*-1 ?
int tileAmountX = (((startX*-1)+endX)/(XCO*2))+1;
is (endX-startX)/(XCO*2) + 1;
which probably results in (talk about loosing track)
(east+west)/(XCO*2);
and in (2*east)/(2*XCO)
hence east/XCO
hence 2*w
[edited by - Trienco on January 21, 2004 8:27:24 AM]
Shot a lot. I didn't know you could do that.
There is one thing though...
You said I could drop the
GL.glPushMatrix();
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
...
GL.glPopMatrix();
thingy, but then how am I going to scroll if I don't use
glTranslatef()?
Oh and you don't have to put private or public in front of the methods/variables, you can just leave it blank.
[edited by - Mr_Ridd on January 21, 2004 8:51:54 AM]
There is one thing though...
You said I could drop the
GL.glPushMatrix();
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
...
GL.glPopMatrix();
thingy, but then how am I going to scroll if I don't use
glTranslatef()?
Oh and you don't have to put private or public in front of the methods/variables, you can just leave it blank.
[edited by - Mr_Ridd on January 21, 2004 8:51:54 AM]
quote:
Original post by Mr_Ridd
You said I could drop the
GL.glPushMatrix();
GL.glLoadIdentity();
GL.glTranslatef(ty, tx, tz);
...
GL.glPopMatrix();
thingy, but then how am I going to scroll if I don''t use
glTranslatef()?
you do, but not inside this function. and once your function doesnt mess with the modelview theres no reason to push/pop. translating should apply to everything (except any hud displays or parts of some menu), so theres no point in calling it all the time for everything if you can do it only once in the beginning.
in the end you would have a main loop like:
glClear(...);
glLoadIdentity();
glTranslate(ScrollX, ScrollY);
drawBackground();
drawBuildings();
drawWhatever();
later though you should also avoid drawing stuff that isnt visible, but until its working i wouldnt worry about that.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement