在opengl中绘制带有鼠标位置的球体

时间:2013-10-18 17:08:29

标签: c++ opengl

我每次点击屏幕时都试图在鼠标位置绘制球体。

每次点击鼠标时,我都会编写一个函数来获取3D鼠标坐标。它就像一个魅力。

现在我如何在这些位置创建球体。

void display()
{
...
...
glColor3f(1,0,0)
glutWireSphere(3,100,100);
glTranslatef(X,Y,Z);
}

void MouseFunc()//where the 3D mouse coordinates are recieved
{
double X,Y,Z// where I store the coordinates.
.....
.....
glutDisplayFunc(display);//Because thats where I create the spheres
}

2 个答案:

答案 0 :(得分:0)

您需要先创建转换矩阵,然后绘制。换句话说:

glTranslatef(X,Y,Z);       /* everything from here below would be translated */
glutWireSphere(3,100,100); /* draw with the current transformation matrix */

答案 1 :(得分:0)

在MouseFunc中,将click的位置存储到绘图函数可见的数组/列表/向量中,即不在本地范围的变量中。然后拨打glutPostRedisplay,使用glutDisplayFunc使GLUT调用您在初始化代码中注册一次的显示功能。

在显示功能本身中,您遍历数组/列表/向量,并根据元素的数据为每个元素绘制一个球体。

由于评论请求而导致的代码示例

clicksphere.cc

#include <GL/glut.h>
#include <GL/gl.h>
#include <list>

typedef union v2f_t {
    struct {
        float x;
        float y;
    };
    float v[2];
} v2f_t;

typedef std::list<v2f_t> v2flist_t;

v2flist_t sphere_centers;

void display(void)
{
      int const window_width  = glutGet(GLUT_WINDOW_WIDTH);
      int const window_height = glutGet(GLUT_WINDOW_HEIGHT);
    float const window_aspect = (float)window_width / (float)window_height;

    glClearColor(0.5, 0.5, 1.0, 1.0);
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glViewport(0, 0, window_width, window_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if(window_aspect > 1.) {
        glOrtho(-window_aspect, window_aspect, -1, 1, -1, 1);
    }
    else {
        glOrtho(-1, 1, -1/window_aspect, 1/window_aspect, -1, 1);
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLfloat const light_pos[4]     = {-1.00,  1.00,  1.00, 0.};
    GLfloat const light_color[4]   = { 0.85,  0.90,  0.70, 1.};
    GLfloat const light_ambient[4] = { 0.10,  0.10,  0.30, 1.};
    glLightfv(GL_LIGHT0, GL_POSITION, light_pos),
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glEnable(GL_DEPTH_TEST);

    for( v2flist_t::iterator sc = sphere_centers.begin();
         sc != sphere_centers.end();
         sc++ ) {

        glPushMatrix();
        glTranslatef(sc->x, sc->y, 0);
        glutSolidSphere(0.1, 31, 10);
        glPopMatrix();
    }

    glutSwapBuffers();
}

void mouseclick(
    int button,
    int state,
    int mouse_x,
    int mouse_y )
{
      int const window_width  = glutGet(GLUT_WINDOW_WIDTH);
      int const window_height = glutGet(GLUT_WINDOW_HEIGHT);
    float const window_aspect = (float)window_width / (float)window_height;

    v2f_t const sc = {
        (window_aspect > 1.0 ? window_aspect : 1.) *
        (  ((float)mouse_x / (float)window_width )*2. - 1.),

        (window_aspect < 1.0 ? 1./window_aspect : 1.) *
        ( -((float)mouse_y / (float)window_height)*2. + 1.)
    };
    sphere_centers.push_back(sc);

    glutPostRedisplay();
}


int main(
    int argc,
    char *argv[] )
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);

    glutCreateWindow("Click to place spheres");
    glutDisplayFunc(display);
    glutMouseFunc(mouseclick);

    glutMainLoop();

    return 0;
};