如何在OpenGL中映射球体表面上的单击点?

如何在OpenGL中映射球体表面上的单击点?,opengl,linear-algebra,glut,quaternions,glm-math,Opengl,Linear Algebra,Glut,Quaternions,Glm Math,我希望能够在OpenGL中单击球体表面上的点。以下是我目前掌握的情况: #include <iostream> #include <stdlib.h> #include "GL/freeglut.h" #include "glm/glm.hpp" #include "quaternion.h" const GLsizei WINDOW_WIDTH = 640; const GLsizei WINDOW_HEIGHT = 640; int mouse_x = 0; i

我希望能够在OpenGL中单击球体表面上的点。以下是我目前掌握的情况:

#include <iostream>
#include <stdlib.h>

#include "GL/freeglut.h"
#include "glm/glm.hpp"
#include "quaternion.h"

const GLsizei WINDOW_WIDTH = 640;
const GLsizei WINDOW_HEIGHT = 640;

int mouse_x = 0;
int mouse_y = 0;

float zoom = 1.0f;
float zoom_sensitivity = 0.1f;
const float zoom_max = 1.5f;
const float zoom_min = 0.1f;

bool clicked = false;
glm::vec3 pointClick;

glm::vec3 GetOGLPos(int x, int y);

void display(void) {

    // Clear display port
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    // Reset camera
    gluLookAt(
        0.0, 0.0, 2.0,
        0.0, 0.0, 0.0,
        0.0, 1.0, 0.0
    );

    // Zoom
    glScalef(zoom, zoom, zoom);


    // Render sphere
    glPushMatrix();
    glTranslatef(0, 0, 0);
    glColor3f(1, 0, 0);
    glutSolidSphere(1, 64, 64);
    glPopMatrix();

    // Render point
    if (clicked == true) {
        glPushMatrix();
        glColor3f(0, 1, 0);
        glPointSize(0.5f);
        glBegin(GL_POINTS);
        glVertex3f(pointClick.x, pointClick.y, pointClick.z);
        printf("%f, %f, %f\n", pointClick.x, pointClick.y, pointClick.z);
        glEnd();
        glPopMatrix();
    }

    // Swap buffers
    glutSwapBuffers();
}

void reshape(GLsizei width, GLsizei height) {
    if (height == 0) {
        height = 1;
    }
    float ratio = 1.0 * width / height;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, width, height);
    gluPerspective(45, ratio, 1, 100);
    glMatrixMode(GL_MODELVIEW);
}

// Handles mouse input for camera rotation.
void motion(int x, int y) {
    pointClick = GetOGLPos(x, y);
    clicked = true;
    glutPostRedisplay();
}

// Handles scroll input for zoom.
void mouseWheel(int button, int state, int x, int y) {
    if (state == 1) {
        zoom = zoom + zoom_sensitivity >= zoom_max ? zoom_max : zoom + zoom_sensitivity;
    }
    else if (state == -1) {
        zoom = zoom - zoom_sensitivity <= zoom_min ? zoom_min : zoom - zoom_sensitivity;
    }
    glutPostRedisplay();
}


int main(int argc, char** argv) {

    // Initialize glut.
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DOUBLE);
    glutInitWindowPosition(
        (glutGet(GLUT_SCREEN_WIDTH) - WINDOW_WIDTH) / 2,
        (glutGet(GLUT_SCREEN_HEIGHT) - WINDOW_HEIGHT) / 2
    );
    glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    glutCreateWindow("Window");

    // Register callbacks.
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMotionFunc(motion);
    glutMouseWheelFunc(mouseWheel);

    // Start glut.
    glutMainLoop();

    return 0;
}

// Get position of click in 3-d space
glm::vec3 GetOGLPos(int x, int y)
{
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

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

    winX = (float)x;
    winY = (float)viewport[3] - (float)y;
    glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

    gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
    return glm::vec3(posX, posY, posZ);
}
#包括
#包括
#包括“GL/freeglut.h”
#包括“glm/glm.hpp”
#包括“四元数.h”
常数GLsizei窗口宽度=640;
const GLsizei窗户高度=640;
int mouse_x=0;
int mouse_y=0;
浮动缩放=1.0f;
浮动变焦灵敏度=0.1f;
常量浮动缩放最大值=1.5f;
常量浮动缩放最小值=0.1f;
bool=false;
glm::vec3点击点;
glm::vec3 GetOGLPos(intx,inty);
作废显示(作废){
//清除显示端口
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glLoadIdentity();
//复位摄像机
注视(
0.0, 0.0, 2.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0
);
//变焦
glScalef(缩放,缩放,缩放);
//渲染球体
glPushMatrix();
glTranslatef(0,0,0);
gl3f(1,0,0);
实心球体(1,64,64);
glPopMatrix();
//渲染点
如果(单击==true){
glPushMatrix();
gl3f(0,1,0);
glPointSize(0.5f);
glBegin(总分);
glVertex3f(pointClick.x、pointClick.y、pointClick.z);
printf(“%f,%f,%f\n”,pointClick.x,pointClick.y,pointClick.z);
格伦德();
glPopMatrix();
}
//交换缓冲区
glutSwapBuffers();
}
空洞重塑(GLsizei宽度、GLsizei高度){
如果(高度==0){
高度=1;
}
浮动比率=1.0*宽度/高度;
glMatrixMode(GL_投影);
glLoadIdentity();
glViewport(0,0,宽度,高度);
(45,比率,1100);
glMatrixMode(GLU模型视图);
}
//处理相机旋转的鼠标输入。
无效运动(整数x,整数y){
pointClick=GetOGLPos(x,y);
单击=真;
再发现();
}
//处理缩放的滚动输入。
无效鼠标滚轮(int按钮、int状态、int x、int y){
如果(状态==1){
缩放=缩放+缩放灵敏度>=缩放最大值?缩放最大值:缩放+缩放灵敏度;
}
else if(状态==-1){

zoom=zoom-zoom\u灵敏度首先要将光标转换为世界中的光线,然后执行光线-球体相交测试以确定光线与球体相交的位置。您可以阅读这篇关于如何将光标转换为世界中的光线的文章:。

首先要将光标转换为世界中的光线,然后然后执行光线与球体相交测试,以确定光线与球体相交的位置。您可以阅读本文,了解如何将光标转换为世界中的光线: