0

画面をクリックするたびに、マウスの位置に球を描画しようとしています。

マウスがクリックされるたびに、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
}
4

2 に答える 2

0

MouseFunc では、クリックの位置を、描画関数から見える配列/リスト/ベクトルに格納します。つまり、ローカル スコープの変数には格納しません。次に、 を使用して、初期化コードで一度glutPostRedisplay登録した表示関数を GLUT に呼び出すように呼び出します。glutDisplayFunc

表示関数自体では、配列/リスト/ベクトルを反復処理し、要素のデータに従って各要素の球を描画します。

コメントでのリクエストによるコードサンプル

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;
};
于 2013-10-18T17:27:59.373 に答える
0

最初に変換行列を作成してから描画する必要があります。言い換えると:

glTranslatef(X,Y,Z);       /* everything from here below would be translated */
glutWireSphere(3,100,100); /* draw with the current transformation matrix */
于 2013-10-18T17:12:19.353 に答える