[solved] Cursor questions

Started by
23 comments, last by tre 15 years ago
Hi, I'm wondering if anyone has the answer to why my cursor positions are acting strange, strange, strange. Some background. I'm trying to create a custom mouse pointer by assigning a textured quad to the pointer position. I've figured it all out, though. I'm "unprojecting" the cursor with gluOrtho2D, flipping and translating the screen and all that jazz. The problems then. When I assign the quad to the cursor position it's all great in resolutions from 800x600 up to and including 1600x900. But when I'm trying to kick the program into gear for my native resolution 1920x1600 the quad jumps up above the cursor position with quite a few units, images below for easier understanding. Why is it just for higher resolutions? I want to be able to run this program at my computers highest capacity without strangeness happening :) The second problem is that the quad is sort of lagging behind the cursor when I move it. If I move it faster the quad is falling more behind. Of course, it allways catches up with the mouse and will probably not be noticable when I hide the default cursor. Still, it's annoying me. Is there a way to get the quad to move faster, allmost exactly as the mouse or is this a common thing? Code: Orthographic projection

// gets called whenever I want orthographic projection
void orthoStart(void){
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0, g_window->init.width, 0, g_window->init.height);
	glScalef(1, -1, 1);
	glTranslatef(0, -g_window->init.height, 0);
	glMatrixMode(GL_MODELVIEW);
}

// gets called whenever I want to get back into 3D projection
void orthoEnd(void){
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
}




Cursor position and drawing

// for finding out the cursor position
void posCursor(void){
	POINT lastMouse = {0, 0};
	GetCursorPos(&lastMouse);
	
	float moveX = float(320 + lastMouse.x)/100.0f;
	float moveY = float(240 - lastMouse.y)/100.0f;
	
	// mousePosition[] is a global, storing the values from GetCursorPos
	mousePosition[0] = g_mouse->mouseNoOldX;
	mousePosition[1] = g_mouse->mouseNoOldY;
}

// for drawing and moving the cursor
void drawCursor(void){
	glPushMatrix();
	glTranslatef(mousePosition[0], mousePosition[1], 0.0f);
	glTranslatef(0.0f, 50.0f, 0.0f);
	glBegin(GL_QUADS);
		glVertex2f(0, 0);
		glVertex2f(50, 0);
		glVertex2f(50, -50);
		glVertex2f(0, -50);
	glEnd();
	glPopMatrix();
}

// the following is located in my main Draw() function
// calling 2D projection, mouse and position
orthoStart();
	posCursor();
	drawCursor();
orthoEnd();




Images: 1600x900 1600x900 1920x1200 1920x1200 Edit After simplifying how I position the quad, I've now got this problem ONLY when in Windowed mode, still not acceptable to me. Why is it only occurring in resolutions larger than 1600x900 and never in fullscreen? Do you need any more code than what's allready been posted? I really want to understand why this is happening. Thanks in advance and take care, Marcus [Edited by - tre on May 6, 2009 5:30:49 AM]
Advertisement
While waiting for a reply on the above question I have been fooling around with textures. Trying to apply a texture to the quad I'm going to be using for the cursor.
Strange thing is, whenever I try to call
glGenTextures(3, &texture[0].texID);
the program crashes.
I set the texture array to texture[3], I made sure I bind the correct texture ID, the glTexParameteri's and glTexImage2D settings are correct, and I free the image data correctly for this new texture. I have set the glTexCoord2f's and bound the correct texture to the correct quad.
If I change the 2 to a 3 in glGenTextures the program crashes, if I leave it at 2 I get undesirable results.

Anyone have an answer to this question as well?
// for finding out the cursor positionvoid posCursor(void){	POINT lastMouse = {0, 0};	GetCursorPos(&lastMouse);		float moveX = float(320 + lastMouse.x)/100.0f;	float moveY = float(240 - lastMouse.y)/100.0f;	//The code above is not used at all		// mousePosition[] is a global, storing the values from GetCursorPos	mousePosition[0] = g_mouse->mouseNoOldX;	mousePosition[1] = g_mouse->mouseNoOldY;	//What is exactly g_mouse->mouseNoOldX and g_mouse->mouseNoOldY;	//Do you rellay need mousePosition? you can just use g_mouse in drawCursor() instead.}


glGenTextures(3, &texture[0].texID);
Can't be used that way. glGenTextures will write at the address &texture[0].texID and its successors not at &texture[0].texID, &texture[1].texID and &texture[2].texID. Suppose that in your struct there is a pointer defined after texID. When you call glGenTextures(3, &texture[0].texID), the value of that pointer will be changed...
Hello again Knighty :)
First off, thanks for the help on my previous question, I'm sort of progressing, learning new things every day.

Now, glGenTextures. I'm loading my "starmap.tga" and my "globe.tga" with glGenTextures(2, &texture[0].texID), that is why I thought I could generate three textures with glGenTextures(3, &texture[0].texID). When reading the specification for glGenTextures I read: "glGenTextures returns n texture names in textures. There is no guarantee that the names form a contigous set of integers; however, it is guaranteed that none of the returned names was in use immediately before the call to glGenTextures."
This led me to believe that I could generate the amount of textures needed by simply adding more to this call.
How should I go about adding more than one texture? Call several separate glGenTextures?

And now for the OT question. The code I supplied earlier has now been revised some. I've removed the posCursor function completely and am now sending g_mouse straight to the drawMouse function.
The g_mouse->mouseNoOldX and g_mouse->mouseNoOldY are the mouse positions without removal of the old position. I do this for rotating the scene.

In my CALLBACK function
case WM_MOUSEMOVE:	window->mouse->mouseMoving = true;	window->mouse->mousePosX = (LOWORD(lParam)-oldPosX);	window->mouse->mousePosY = (HIWORD(lParam)-oldPosY);	window->mouse->mouseNoOldX = LOWORD(lParam);	window->mouse->mouseNoOldY = HIWORD(lParam);	oldPosX = (LOWORD(lParam));	oldPosY = (HIWORD(lParam));	return 0;


I'm thinking of removing windowed mode, since the only benefit of that is that I can run the program easily without having to into fullscreen every time. It's not something I have planned for the finished game anyway.
It's still bugging me though and I'd like to know why the quad is behaving the way it is. Is it because of the start bar in Windows Vista? Is it pushing the quad upwards?


Thanks for taking the time to answer (again),
Marcus


Edit
Okay, following Knighty's recommendations I wrote my glGenTextures this way instead of
glGenTextures(2, &texture[0].texID)

glGenTextures(1, &texture[0].texID);glGenTextures(1, &texture[1].texID);glGenTextures(1, &texture[2].texID);

It's working but I don't know if it's the best way to do it. Right now I'm using only 3 textures, but as the scene grows I guess I have to do some kind of loop instead.

I've also removed the windowed/fullscreen option and now the game will only run in fullscreen in the requested resolutions, this fixed the problem with the moving quad.

I've also started texturing the mouse pointer with a TGA with an Alpha value. Lack of knowledge rears it's ugly head again as I can clearly see the Alpha working correctly (removing the background from the image), but the black quad that I'm binding the texture to is now showing. Giving me less than great results.
The pointer is looking good though. :)

Anyone have any tips? Either on what to read or details on how to go about it? It'd be appreciated.

I changed the title of the thread to better reflect the content.

Thanks for all the help I've been getting here. I'm new to this kind of programming. But I am learning and I've recently bought the "Beginning OpenGL Game Programming" book and the follow up, "More OpenGL Game Programming". Really great books.

[Edited by - tre on April 27, 2009 10:53:31 AM]
Hi, :)

Quote:
Hello again Knighty :)
First off, thanks for the help on my previous question, I'm sort of progressing, learning new things every day.

Now, glGenTextures. I'm loading my "starmap.tga" and my "globe.tga" with glGenTextures(2, &texture[0].texID), that is why I thought I could generate three textures with glGenTextures(3, &texture[0].texID). When reading the specification for glGenTextures I read: "glGenTextures returns n texture names in textures. There is no guarantee that the names form a contigous set of integers; however, it is guaranteed that none of the returned names was in use immediately before the call to glGenTextures."
This led me to believe that I could generate the amount of textures needed by simply adding more to this call.
How should I go about adding more than one texture? Call several separate glGenTextures?

Why not! Generaly, allocating texture (and other) names is done once at startup.

The functions like glGenTextures() may be very dangerous if not used carefully. It's supposed to be used this way:
#define AN_ARBITRARY_TEX_NAME_NUMBER 3
GLuint texName[AN_ARBITRARY_TEX_NAME_NUMBER];
...
glGenTextures(AN_ARBITRARY_TEX_NAME_NUMBER, texName);

Or if one needs only one texture name:
GLuint texName;
...
glGenTextures(1, &texName);

Suppose you do:
GLuint texName;
foo *anArrayOfFoo=new foo[100];
...
glGenTextures(2, &texName);

Here, depending on the way the compiler puts data in memory the pointer "anArrayOfFoo" may (or may not) be modified by "glGenTextures". the result may be anything from runnig perfectly (if you don't use the second texture name) to a spectacular crash :))

In your case you did something like this (I suppose):
typedef struct{
...
GLuint texID;
char *imgData;
} MyTextureType;
MyTextureType texture[3];

or:
typedef struct{
...
GLuint texID;
} MyTextureType;
MyTextureType texture[3];
foo *aDataPointer;

In both cases, the second texture name generated by "glGenTextures(3, &texture[0].texID);" will be written immediatly after texID. In the first case it may overwrite imgData and in the second aDataPointer.

For your original post, I can't say what's going wrong. It may be anything in your code. It also seems to me that it's not related to openGL.

One thing that helps me while debugging my (little) programs is to remember that the computer does what it's asked to do, never what we want it to do. ;)

Edit: by the way, GetCursorPos() gives mouse coordinates in screen coordinates not in client area coordinates.

[Edited by - knighty on April 27, 2009 3:27:46 PM]
Okay, I'm back and I've had some time to work on this. From what you wrote above I gather that I've done something correctly now :)
This is how I run through and generate textures now:
// first I set a number that will represent how many textures I want.#define TEX_NUMBER	3// create an array of texturesTexture texture[TEX_NUMBER];// and in my LoadTextures() function I run:for(int i = 0; i < TEX_NUMBER; i++){	glGenTextures(1, &texture.texID);}

The above works, I can assign any amount of textures to my objects and it's all dandy. I hope that I got it right, please correct me if I'm wrong.

The result with some blending on the mouse cursor is very nice. A picture further down. I'm trying to get the texture to look even better, there are some pixels that are bugging me.

On the GetCursorPos() call... since it's in screen coordinates it's getting pushed by the Windows Start bar if the client area is larger than the screen? 1920x1600 + the top "title bar" is pushing the window somewhat below the start bar.
What would I use to correct it? Is there any mouse position call that is calculated on the client area?

The progress of the entire graphics module for the game is about 75% done now, I think. I'm going to add some animated specularity (if possible) to the water, and maybe a very small height map to the land mass.
I'm thinking of adding a blended gluSphere with an animated perlin noise to simulate clouds and I'm trying to get the Multisample and FSAA to work (NeHe's code).
I'm having fun and I'm learing :)

I hope to some day be able to repay you, Knighty. I'll buy you a beer if you end up in Sweden sometime :)

Progress Shot
Quote:Original post by tre
Okay, I'm back and I've had some time to work on this. From what you wrote above I gather that I've done something correctly now :)
This is how I run through and generate textures now:
*** Source Snippet Removed ***
The above works, I can assign any amount of textures to my objects and it's all dandy. I hope that I got it right, please correct me if I'm wrong.

That's OK! You can also get the texture names in an array then copy them in the for() loop to your texture[].texID. But let's keep it as it is. Simpler is better.
Quote:Original post by tre
The result with some blending on the mouse cursor is very nice. A picture further down. I'm trying to get the texture to look even better, there are some pixels that are bugging me.

On the GetCursorPos() call... since it's in screen coordinates it's getting pushed by the Windows Start bar if the client area is larger than the screen? 1920x1600 + the top "title bar" is pushing the window somewhat below the start bar.
What would I use to correct it? Is there any mouse position call that is calculated on the client area?

GetCursorPos() gives mouse position in screen coordinates including the task bar. If you want to use that function, you need to convert the coordinates returned by GetCursorPos() to client rectangle by using ScreenToClient() function.
GetCursorPos() is not necessary. In fact you already have the mouse coordinates (in lparam of WM_MOUSE messages). You only have to convert them to normalized screen coordinates. the upper left corner of the cursor quad would be (2.0*x_mouse/window_width-1.0,1.0-2.0*y_mouse/window_height). You will not need to translate or scale that quad.
Quote:Original post by tre
The progress of the entire graphics module for the game is about 75% done now, I think. I'm going to add some animated specularity (if possible) to the water, and maybe a very small height map to the land mass.
I'm thinking of adding a blended gluSphere with an animated perlin noise to simulate clouds and I'm trying to get the Multisample and FSAA to work (NeHe's code).
I'm having fun and I'm learing :)

I hope to some day be able to repay you, Knighty. I'll buy you a beer if you end up in Sweden sometime :)

Progress Shot

Already payed! [grin] That picture is nice. I like the star field in the background.
Seems like you will have to write some shader effects... good luck!
Okay, that's good to know if I decide to add in the windowed mode later on, I've kept the code for now. It's one of those things that I don't know if I'll cut or not. It's pretty pointless.
Yeah, the shaders... *drum roll* :) I'm reading up on GLSL right now, the "More OpenGL Game Programming" book covers it really well and have great code examples to check out. They're running their grahpics engine differently though, so sometimes it's a bit of a search to find the parts I want to take a closer look at. But nothing extreme (yet!).

I'll be back with more questions, count on it ;)

Thanks for the compliment! I'm pretty happy with the results so far.
The star field looks great in smaller resolutions, but not as hot in 1920x1200. I'm trying to figure out better ways to do it, but haven't gotten any ideas yet. I'd like to get the stars to twinkle and be "resolution independent", so that they're equally high quality regardless of the resolution. Right now I'm thinking of maybe doing the stars with billboards and do some animated blending. The tradeoff is that there would be quite a few billboards... I'm rambling.

Thank you Knighty, take care!
Marcus
I dont know if u solevd the cursor problem

the trick is to always keep the OS curosr in the center of the screen
just read the delta movement from that + apply it to your opengl drawn cursor
Quote:Original post by zedz
I dont know if u solevd the cursor problem

the trick is to always keep the OS curosr in the center of the screen
just read the delta movement from that + apply it to your opengl drawn cursor


I never solved it per se, I just disabled the Windowed Mode, quick and dirty :)
What do you mean by "delta movement"? I tried keeping the mouse cursor in the middle of the screen at first, and did a few different calculations but nothing worked out. I do carry both the current mouseposition minus the last mouse position as well as just the current mouse position in my Mouse struct.

This topic is closed to new replies.

Advertisement