Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
696 views
in Technique[技术] by (71.8m points)

c++ - 使用GLFW和OpenGL在鼠标单击上画点?(Draw point on mouse-click using GLFW & OpenGL?)

This is the function I used to get the mouse click position:

(这是我用来获取鼠标单击位置的功能:)

void Window::mouseButtonCallback(GLFWwindow * WindowObject, int button, int action, int mods)
{
 double xpos, ypos;

    if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
    {
        glfwGetCursorPos(WindowObject, &xpos, &ypos);
        cout << " XPOS : " << xpos << endl;
        cout << " YPOS : " << ypos << endl;

    }
    if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_RELEASE)
    {
        cout << "Mouse Button Released" << endl;
    }
}
glfwSetMouseButtonCallback(this->WindowObject, mouseButtonCallback);

Full code:

(完整代码:)

#include <GL/glew.h>
#include <glfw/glfw3.h>
#include <iostream>

using namespace std;

class Window
{
private:
    int screenWidth, screenHeight;
    const char* WindowName;
    GLFWwindow* WindowObject;
public:
    Window();
    void CreateWindow();
    void SetViewPort( int, int, const char* );
    void SetBGColor( float, float, float, float );
    void SetWindowActive();
    bool IsWindowActive();
    static void mouseButtonCallback( GLFWwindow* WindowObject, int button, int action, int mods );
};

GLdouble vertex[] = { 0.0f,0.0f };
GLuint VBO;

void DrawPoints()
{
    //generate vbo
    glGenBuffers( 1, &VBO );

    //binding vbo
    glBindBuffer( GL_ARRAY_BUFFER, VBO );

    //generating data in vbo
    glBufferData( GL_ARRAY_BUFFER, sizeof( vertex ), vertex, GL_STATIC_DRAW );

    //retrieving data
    glVertexAttribPointer( 0, 3, GL_DOUBLE, GL_FALSE, 0, 0 );

    //enable data for drawing
    glEnableVertexAttribArray( 0 );

    //drawing a point
    glDrawArrays( GL_POINTS, 0, 1 );

    //to increase the size of point
    glPointSize( 5 );

    //to change the color of the point
    glColor3f( 1, 0, 0 );

    //disable data after using
    glDisableVertexAttribArray( 0 );
}

void Window::mouseButtonCallback( GLFWwindow * WindowObject, int button, int action, int mods )
{
    double xpos, ypos;

    if( button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS )
    {
        glfwGetCursorPos( WindowObject, &xpos, &ypos );
        cout << " XPOS : " << xpos << endl;
        cout << " YPOS : " << ypos << endl;
        //glBegin(GL_POINTS);
        //glPointSize(5);
        //glColor4f(1, 0, 0, 1);
        //glVertex2f(xpos,ypos);
        //glEnd();
    }
    if( button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_RELEASE )
    {
        cout << "Mouse Button Released" << endl;
    }
}

Window::Window()
{
    this->screenWidth = 640;
    this->screenHeight = 480;
    this->WindowName = "New Window";
    glfwInit();
}

void Window::SetViewPort( int screenWidth, int screenHeight, const char* WindowName )
{
    this->screenHeight = screenHeight;
    this->screenWidth = screenWidth;
    this->WindowName = WindowName;
}

void Window::CreateWindow()
{
    this->WindowObject = glfwCreateWindow( this->screenWidth, this->screenHeight, this->WindowName, NULL, NULL );
    // To get co-ordinates of cursor
    //glfwSetCursorPosCallback(this->WindowObject, cursorPosCallback);
    glfwSetMouseButtonCallback( this->WindowObject, mouseButtonCallback );
    if( this->WindowObject == NULL )
    {
        cout << stderr << "Failed to Load the Window";
        glfwTerminate();
    }
    glfwMakeContextCurrent( this->WindowObject );
    glewInit();
}

void Window::SetBGColor( float R, float G, float B, float A )
{
    glClear( GL_COLOR_BUFFER_BIT );
    glClearColor( R, G, B, A );
}

void Window::SetWindowActive()
{
    glfwSwapBuffers( this->WindowObject );
    glfwPollEvents();
}

bool Window::IsWindowActive()
{
    if( glfwGetKey( this->WindowObject, GLFW_KEY_ESCAPE ) == GLFW_PRESS )
    {
        return false;
    }
    if( GLFW_PRESS && glfwWindowShouldClose( this->WindowObject ) != 0 )
    {
        return false;
    }
    return true;
}

int main()
{
    Window MyGameWindow;
    MyGameWindow.SetViewPort( 1024, 768, "My Game Window" );
    MyGameWindow.CreateWindow();

    do
    {
        MyGameWindow.SetBGColor( 0.128f, 0.128f, 0.128f, 0.0f );
        DrawPoints();
        MyGameWindow.SetWindowActive();
    }
    while( MyGameWindow.IsWindowActive() );
    return 0;
}
  ask by saran gunasekaran translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Use glfwSetWindowUserPointer to associate a pointer to the Window object, to the GLFWindow :

(使用glfwSetWindowUserPointer将指向Window对象的指针关联到GLFWindow :)

void Window::CreateWindow()
{
    this->WindowObject = glfwCreateWindow(this->screenWidth, this->screenHeight,
                                          this->WindowName, NULL, NULL );

    glfwSetWindowUserPointer( this->WindowObject, this ); // <----

    // [...]
}

Use glfwGetWindowUserPointer to retrieve the associated pointer in the static mouse button callback and delegate the callback to a method of Window :

(使用glfwGetWindowUserPointer检索静态鼠标按钮回调中的关联指针,并将回调委托给Window方法:)
(Sadly you've to cast the return value of type void* to Window* , there is no way around.)

((遗憾的是,您必须将void*类型的返回值void*Window* ,但无法解决。))

class Window
{
    // [...]

    void mouseButtonCallback( int button, int action, int mods );
    static void mouseButtonCallback( GLFWwindow* WindowObject, int button, int action, int mods );
};
void Window::mouseButtonCallback( GLFWwindow * WindowObject, int button, int action, int mods )
{
    Window *window = (Window*)glfwGetWindowUserPointer( WindowObject );
    window->mouseButtonCallback( button, action, mods );
}

void Window::mouseButtonCallback( int button, int action, int mods )
{
    // [...]
}

In the method the attributes for the window width ( this->screenWidth ) and height ( this->screenHeight ) can be accessed and the normalized device coordinate corresponding to the mouse position an be calculated.

(在该方法中,可以访问窗口宽度( this->screenWidth )和高度( this->screenHeight )的属性,并计算与鼠标位置对应的标准化设备坐标。)

Now it is possible to change vertex coordinates ( vertex ):

(现在可以更改顶点坐标( vertex ):)

void Window::mouseButtonCallback( int button, int action, int mods )
{
    double xpos, ypos;

    if( button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS )
    {
        glfwGetCursorPos( WindowObject, &xpos, &ypos );
        cout << " XPOS : " << xpos << endl;
        cout << " YPOS : " << ypos << endl;

        vertex[0] = (double)xpos / this->screenWidth * 2.0 - 1.0;
        vertex[1] = 1.0 - (double)ypos / this->screenHeight * 2.0;
    }
    if( button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_RELEASE )
    {
        cout << "Mouse Button Released" << endl;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...