Sign in to follow this  
DominicHughes

OpenGL How can I track the mouse cursor position and then draw a line ?

Recommended Posts

DominicHughes    143
How can I track the mouse cursor position and then draw a line at that exact location?

I tried to do this myself by using glUnProject(); and store the 3 last values and use them as position for the glVertex3f(); vertex positioning obviously that didn't work it would draw the line but not at the exact location of the cursor or close enough that it wasn't noticeable after running the program.

So I was trying to deciper a way to do it and I'm 100% honestly stumped....


So in other words if someone knows how to do this feel free to tell me how you did it smile.png

OpenGL 3.0
WIN32 API
C++


Thanks in Advance

Share this post


Link to post
Share on other sites
slicer4ever    6760
Are you drawing a 2D line, or 3D line?

If it's 3D gluUnProject is defiantly what you need, mind posting your code?

If it's just 2D then you simply need to track your mouse(although it sounds like a 3D projection from your description.)

Also, could you possible provide a picture of a test scene so we can see exactly what your attempting to do?

Share this post


Link to post
Share on other sites
DominicHughes    143
Hello yes I'm trying to draw a 3D Line here is the code thats most important in this case

The Setup :

[CODE]

void init ()
{
glClearColor(1.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90,SCREEN_HEIGHT/SCREEN_WIDTH,0.0,1500.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING); //we enable lighting, to make the 3D object to 3D
glEnable(GL_LIGHT0);
float col[]={1.0,1.0,1.0,1.0}; //light color is white
glLightfv(GL_LIGHT0,GL_DIFFUSE,col);

}

[/CODE]

Drawing The Line :

[CODE]
case WM_LBUTTONDOWN:

glBegin( GL_LINES );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex3f(posX, posY, 0.0f);
glVertex3f(posX, posY, posZ );
glEnd();

cout << "Test" << endl;


break;
[/CODE]

Displaying the graphics:

[CODE]
void display()
{

glLoadIdentity();
float pos[]={-1.0,1.0,-2.0,1.0}; //set the position
glLightfv(GL_LIGHT0,GL_POSITION,pos);
//glRotatef(angle,angle,0.0,2.0);
cout << name << endl;
// glCallList(cube);
for(std::vector<GLuint>::iterator I = cube.begin(); I != cube.end(); ++I) {
glCallList(*I);
}

glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_PROJECTION_MATRIX, projection);

GetCursorPos(&mouse);
ScreenToClient(hwnd, &mouse);

winX = (float)mouse.x;
winY = (float)mouse.y;
winY = (float)viewport[3] - winY;
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ );
cout << mouse.x << endl;
cout << mouse.y << endl;

SwapBuffers(hDC);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


}
[/CODE]


And theres not much to see accept a black background with a red line that shows on the frustum only if I left click many times [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Hope that helps Edited by DarkHorseKnight

Share this post


Link to post
Share on other sites
szecs    2990
A screenshot would still be useful.
"red line that shows on the frustum only if I left click many times"
This is not clear. Is something drawn? Is it drawn in the proper place?

The depth buffer is not infinitely precise. *Especially not at the far end of the frustum. You mustn't even use zero value of the near plane, because that screws the calculations. Look into the parameters of gluPerspective and what they mean.

So my guess: the lines are calculated fine except for the wrong perspective definition. Even if you define it correctly (with a >0.0 near plane value), the calculated world coordinates will be imprecise due to floating point errors. That means lines you want to draw at the end of the frustum may be culled (or partially culled) by the frustum, I hope it's clear.

[url="http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html"]*Read this[/url]

Share this post


Link to post
Share on other sites
szecs    2990
BTW, your whole logic is wrong, sorry I just noticed it now.

Sorry, it's hard to explain, there are fundamental flaws in your program.

OpenGL is not like DOS and EGA/VGA etc, where you can paint over-and over the scene and it will remain there like a canvas and everything will instantly get drawn on it. In OpenGL, commands are buffered, so you have to insert glFlush/glFinnish to force openGL to actually draw the stuff on the screen. Or you have to swap the buffers if you have double-buffer. Which you have (at least you use swappbuffers).

BUT:

You shouldn't (or better: mustn't) mix rendering with logic. You have rendering in your mouse handler logic, and you have logic stuff (reading and converting mouse coordinates) in your rendering. This thing can entirely screw rendering and logic, maybe it only works by accident in your case (we should see the WindProc to decide).

Frankly, the rendering and the logic is scattered all over the place, it's very hard to follow the program flow.



So:
Store the transformed (world) coordinates in a vector where you clicked with the mouse, then in the renderer, render the scene with the lines (you read the coordinates from the vector).
The most important thing is to decouple the logic from the render.


Maybe it's not clear at all, but honestly there are so many flaws in your program that it would be easier just to write the program for you than to explain it.


A note for rendering the lines: you should disable writing to the depth buffer ([i]glDepthMask[/i](false) ) so that you don't read the depth values of an already drawn line (unless you want that of course, but I doubt it).


Other problems: with lines, it's pretty much useless to use lighting. Lighting doesn't make things 3D as the comment in your code suggests. Maybe you copied it from a sloppy tutorial. Lighting makes the scene [i]look[/i] 3D, if there are polygons. Lighting requires normals. You don't specify any normals, and how would you do for lines anyway? This may cause that the lines you draw are black, since 0,0,0 is the default value of a normal (since the normals' coordinates are state variables, unlike vertex coordinates).



Maybe you are doing too much things at once. The thing you want to do is not the most beginner openGL topic IMHO, but you do seem like a total beginner (I'm sorry if I sound harsh). Edited by szecs

Share this post


Link to post
Share on other sites
DominicHughes    143
Dude my code is messed up because I leave stuff that I can in my code so I can come back to it later and my program flow is fine I can render 3d models to the screen and rotate the camera around with np and see them. I even coloured the models with no tex cords for fun and got this really cool model texture effect. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

I was asking how to draw a line under the mouse cursor not a course of fixing my so called problems ??? that were needed enforcements for my ease of use. Some people prefer less stuff. I prefer more stuff [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] .

but good advice for someone who needs that :) Edited by DarkHorseKnight

Share this post


Link to post
Share on other sites
szecs    2990
[quote name='DarkHorseKnight' timestamp='1337757835' post='4942460']
Dude my code is messed up because I leave stuff that I can in my code so I can come back to it later and my program flow is fine I can render 3d models to the screen and rotate the camera around with np and see them. I even coloured the models with no tex cords for fun and got this really cool model texture effect. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

I was asking how to draw a line under the mouse cursor not a course of fixing my so called problems ??? that were needed enforcements for my ease of use. Some people prefer less stuff. I prefer more stuff [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] .

but good advice for someone who needs that [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
[/quote]

Well, I was trying to help since the [i]broken[/i] program flow may be the [i]cause[/i] of the problem.
But ignore me if you like, just like my first post that explicitly shows a bug that is related.

Share this post


Link to post
Share on other sites
dpadam450    2357
gluUnproject gets you a point in 3D space, you are calling glBegin(LINES) with posX, posY, 0. What are those? Are they in 3D space or are they the mouse coordinates?

When you draw that line, you also do not show anything about the current matrix, is it going to be the identity? Are you able to rotate your camera? If so, you have to calculate the mouses start and end both in 3D space by calling gluUnproject 2 times, one with a depth from the depth buffer, and the other with a depth equal to your near plane.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Similar Content

    • By Zaphyk
      I am developing my engine using the OpenGL 3.3 compatibility profile. It runs as expected on my NVIDIA card and on my Intel Card however when I tried it on an AMD setup it ran 3 times worse than on the other setups. Could this be a AMD driver thing or is this probably a problem with my OGL code? Could a different code standard create such bad performance?
    • By Kjell Andersson
      I'm trying to get some legacy OpenGL code to run with a shader pipeline,
      The legacy code uses glVertexPointer(), glColorPointer(), glNormalPointer() and glTexCoordPointer() to supply the vertex information.
      I know that it should be using setVertexAttribPointer() etc to clearly define the layout but that is not an option right now since the legacy code can't be modified to that extent.
      I've got a version 330 vertex shader to somewhat work:
      #version 330 uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ModelViewMatrix; layout(location = 0) in vec4 Vertex; layout(location = 2) in vec4 Normal; // Velocity layout(location = 3) in vec3 TexCoord; // TODO: is this the right layout location? out VertexData { vec4 color; vec3 velocity; float size; } VertexOut; void main(void) { vec4 p0 = Vertex; vec4 p1 = Vertex + vec4(Normal.x, Normal.y, Normal.z, 0.0f); vec3 velocity = (osg_ModelViewProjectionMatrix * p1 - osg_ModelViewProjectionMatrix * p0).xyz; VertexOut.velocity = velocity; VertexOut.size = TexCoord.y; gl_Position = osg_ModelViewMatrix * Vertex; } What works is the Vertex and Normal information that the legacy C++ OpenGL code seem to provide in layout location 0 and 2. This is fine.
      What I'm not getting to work is the TexCoord information that is supplied by a glTexCoordPointer() call in C++.
      Question:
      What layout location is the old standard pipeline using for glTexCoordPointer()? Or is this undefined?
       
      Side note: I'm trying to get an OpenSceneGraph 3.4.0 particle system to use custom vertex, geometry and fragment shaders for rendering the particles.
    • By markshaw001
      Hi i am new to this forum  i wanted to ask for help from all of you i want to generate real time terrain using a 32 bit heightmap i am good at c++ and have started learning Opengl as i am very interested in making landscapes in opengl i have looked around the internet for help about this topic but i am not getting the hang of the concepts and what they are doing can some here suggests me some good resources for making terrain engine please for example like tutorials,books etc so that i can understand the whole concept of terrain generation.
       
    • By KarimIO
      Hey guys. I'm trying to get my application to work on my Nvidia GTX 970 desktop. It currently works on my Intel HD 3000 laptop, but on the desktop, every bind textures specifically from framebuffers, I get half a second of lag. This is done 4 times as I have three RGBA textures and one depth 32F buffer. I tried to use debugging software for the first time - RenderDoc only shows SwapBuffers() and no OGL calls, while Nvidia Nsight crashes upon execution, so neither are helpful. Without binding it runs regularly. This does not happen with non-framebuffer binds.
      GLFramebuffer::GLFramebuffer(FramebufferCreateInfo createInfo) { glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); textures = new GLuint[createInfo.numColorTargets]; glGenTextures(createInfo.numColorTargets, textures); GLenum *DrawBuffers = new GLenum[createInfo.numColorTargets]; for (uint32_t i = 0; i < createInfo.numColorTargets; i++) { glBindTexture(GL_TEXTURE_2D, textures[i]); GLint internalFormat; GLenum format; TranslateFormats(createInfo.colorFormats[i], format, internalFormat); // returns GL_RGBA and GL_RGBA glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, createInfo.width, createInfo.height, 0, format, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); DrawBuffers[i] = GL_COLOR_ATTACHMENT0 + i; glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textures[i], 0); } if (createInfo.depthFormat != FORMAT_DEPTH_NONE) { GLenum depthFormat; switch (createInfo.depthFormat) { case FORMAT_DEPTH_16: depthFormat = GL_DEPTH_COMPONENT16; break; case FORMAT_DEPTH_24: depthFormat = GL_DEPTH_COMPONENT24; break; case FORMAT_DEPTH_32: depthFormat = GL_DEPTH_COMPONENT32; break; case FORMAT_DEPTH_24_STENCIL_8: depthFormat = GL_DEPTH24_STENCIL8; break; case FORMAT_DEPTH_32_STENCIL_8: depthFormat = GL_DEPTH32F_STENCIL8; break; } glGenTextures(1, &depthrenderbuffer); glBindTexture(GL_TEXTURE_2D, depthrenderbuffer); glTexImage2D(GL_TEXTURE_2D, 0, depthFormat, createInfo.width, createInfo.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthrenderbuffer, 0); } if (createInfo.numColorTargets > 0) glDrawBuffers(createInfo.numColorTargets, DrawBuffers); else glDrawBuffer(GL_NONE); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "Framebuffer Incomplete\n"; glBindFramebuffer(GL_FRAMEBUFFER, 0); width = createInfo.width; height = createInfo.height; } // ... // FBO Creation FramebufferCreateInfo gbufferCI; gbufferCI.colorFormats = gbufferCFs.data(); gbufferCI.depthFormat = FORMAT_DEPTH_32; gbufferCI.numColorTargets = gbufferCFs.size(); gbufferCI.width = engine.settings.resolutionX; gbufferCI.height = engine.settings.resolutionY; gbufferCI.renderPass = nullptr; gbuffer = graphicsWrapper->CreateFramebuffer(gbufferCI); // Bind glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); // Draw here... // Bind to textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textures[2]); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, depthrenderbuffer); Here is an extract of my code. I can't think of anything else to include. I've really been butting my head into a wall trying to think of a reason but I can think of none and all my research yields nothing. Thanks in advance!
    • By Adrianensis
      Hi everyone, I've shared my 2D Game Engine source code. It's the result of 4 years working on it (and I still continue improving features ) and I want to share with the community. You can see some videos on youtube and some demo gifs on my twitter account.
      This Engine has been developed as End-of-Degree Project and it is coded in Javascript, WebGL and GLSL. The engine is written from scratch.
      This is not a professional engine but it's for learning purposes, so anyone can review the code an learn basis about graphics, physics or game engine architecture. Source code on this GitHub repository.
      I'm available for a good conversation about Game Engine / Graphics Programming
  • Popular Now