我希望能够在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);
}
这是视觉输出:
这会在屏幕上渲染一个点,但它不在球体上。我想知道如何将点放置在球体的表面上,因此,如果我旋转并缩放相机,则该点将停留在同一位置。如何将点“投影”到球体表面上?