How do you simulate a scrolling effect?

Started by
15 comments, last by thyrgle 13 years, 9 months ago
Hi,

I was wondering how you create a scrolling effect in OpenGL like the do in RTS games? Where you click down, move the mouse and it scrolls it the opposite way. Any suggestions on how to do something like this?
Advertisement
step 1: retrieve and store each frames, relative (i.e. position change) mouse coordinates
step 2(optional): adjust the speed of the scroll in some way.
step 3: apply that to your scrolling mechanism.

pseudo-ish code:
int main(int argc, char** argv){	// ...	Point<float> scrollSpeed = Mouse.GetRelativePosition( ); // retrieve coordinates	scrollSpeed *= -scrollFactor; // adjust speed where scroll factor is in the range [0, 1]	Scene.Scroll(scrollSpeed.x, scrollSpeed.y); // bleh...	// ...	return 0;}


Obviously, in actual code it wont be that simple since (I assume) your building from scratch but the core concept is still there.

Hope that helps.

PS: Dont play any RTS games, but I think the above is what your looking for thanks to your neat and tidy description :D

EDIT: Oh and umm, you should perform step 1, 2, 3 inside a mouse click event of some kind (presumably left click) so the background will only scroll when you hold down the left mouse button.
When the player clicks at an appropriate spot, save the screen coordinate that they clicked on, if they are still holding the mouse down and move away from this point. You can then use the saved point and the current mouse position to do some 2D vector math to get the amount your camera should move around.

/* vector2 is a simple struct that has a x and y value */vector2 startPoint;bool isScrolling = false;if (mouse->Clicked){    startPoint = mousePosition;    isScrolling = true;}else    isScrolling = false;if (isScrolling == true && savePoint != mousePosition){    /* calculate the angle and length between the save point and the mouse position */    /* Move the camera in the direction of the angle by the length */}


sorry I'm really horrible with calculus stuff but that is a simple way to do it, you just got to figure out how to get the angle using atan or atan2 and the length.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
CodeCriminal thanks for your response but, how do I get speed of mouse speed in openGL?
Quote:Original post by thyrgle
CodeCriminal thanks for your response but, how do I get speed of mouse speed in openGL?


Im not sure OpenGL provides that kind of functionality, since it is, after all, a graphics library. This is more to do with the windowing API's (or whatever API handles your event system).

In the Windows API, one can retrieve the relative mouse coordinates in various ways.

WM_INPUT comes to mind, it provides "raw" input data AFAIK, which also means it provides the "raw" device coordinates of the mouse.

However, using WM_INPUT seems a little over the top for something as simple as this. One would preferably build a system around WM_INPUT messages and then use that to retrieve desired data. See if no one else here cant answer that question better, or recommend an easier API.
*Sigh*
To bad I'm using a Mac lol.
Quote:Original post by thyrgle
*Sigh*
To bad I'm using a Mac lol.


you can look into SDL's input handling to get mouse and keyboard input.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Quote:Original post by thyrgle
*Sigh*
To bad I'm using a Mac lol.


If you know already how to "absolute" (position of mouse on screen) coordinates of the mouse, you can add a step '4' to the above algorithm (with some modifictions.

When you take the absolute coordinates of the cursor on screen, subtract the current coordinates from the centre screen ones (will make sense soon)

Inside the mouse click event:

pre step 1: hide the mouse cursor
step 1: Get positional mouse coords and perform arithmatic (see below)
step 4: programmaticly set the cursor position to the center of your screen this can be as simple as:

Point<int> center(screenWidth / 2, screenHeight / 2); // provided you sustain accessable variables to your screen width and screen// height (by screen I mean your windows client area, the thing that everything// gets draw into)


Now lets imagine how this might work; each frame the cursor is being moved some distance from the center, and then reset after that distance is calculated and applied to the scrolling mechanism.

let c be the center of your window,
let a be the absolute coordinates of your cursor relative to your windows client area
and let r be the relative (change of position)

then with this simple calculation we can solve for r (simple vector math whey!):

r = a - c;

Ok for example sake lets say that c = (halfwidth, halfheight) = (400, 300), a = (x, y) = (404, 277)

pluggin those values in we get:

r = a - c
= (404 - 400, 277 - 300)
= (4, -23)

So here we can see the mouse has moved a total of 4 on the x axis, and -23 on the y axis.

That might work, not really tested it soo..

Ofcourse having an API that can retrieve these coordinates for you is prefered but in the case that you may not have access to such things this is a viable option. reading on google, I think GLUT provides a function to retrieve absolute mouse coords

Good luck, repost if you need more help, because I love it! :D

PS: To any math boff out there, my math terminology is kinda sucky so if I have said / done anything wrong, apologies and speak up so I can change it.

[Edited by - CodeCriminal on July 11, 2010 11:20:37 PM]
Thanks, for everyones replies...

I have came up with the following:(this is the function passed into glutMouseFunc)
void mouseMovement(int button, int state, int x, int y){	static int g = 0;	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && g == 0)	{		mouseX = x;		mouseY = y;		g = 1;	}	else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && g == 1)	{		changeCameraMovement(x, y);	}	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)	{		g = 0;	}}


And the changeCameraMovement(int x, int y) is implemented here:

void changeCameraMovement(int x, int y){	cameraX = mouseX - x;	cameraY = mouseY - y;	cout << mouseX - x << "," << mouseY - y;	glutPostRedisplay();}


Now cameraX and cameraY is just the arguments passed to a glTranslatef function at the very beginning of a my display function. But, I am having a problem, mouseX - x and mouseY - y always has a value of 0. Meaning no movement. Any suggestions?
Well I cant tell what is going on outside the two functions there, but I assume it is because of this:


first of all you can change the entire contents of the first function (mouseMovement) to this:
 /* snippet removed */


Second of all, without taking a look at code outside these functions its difficult to tell which what is happening here.

What do 'x' and 'y' represent?
Are you trying to implement the method I suggested? And if so, why is mouseX and mouseY only being set with each "press" (i.e. not when the mouse button is held)
What is happening outside mouseMove(...)?

This topic is closed to new replies.

Advertisement