C++ OpenGL中三维坐标到屏幕坐标的转换

C++ OpenGL中三维坐标到屏幕坐标的转换,c++,opengl,C++,Opengl,我在将3D坐标转换为屏幕坐标时遇到问题。我必须把圆心转换成屏幕坐标。我的代码在这里: // OpenGL problem #ifdef __APPLE__ # include <GLUT/glut.h> #else # include <GL/glut.h> #endif void passive(int,int); void reshape(int,int); void init(void); void display(void); void camera(v

我在将3D坐标转换为屏幕坐标时遇到问题。我必须把圆心转换成屏幕坐标。我的代码在这里:

//  OpenGL problem

#ifdef __APPLE__
#  include <GLUT/glut.h>
#else
#  include <GL/glut.h>
#endif

void passive(int,int);
void reshape(int,int);
void init(void);
void display(void);
void camera(void);

int cursorX,cursorY,width,height;
double centerX,centerY,centerZ;
//GLfloat modelviewMatrix[16],projectionMatrix[16];
GLdouble modelviewMatrix[16],projectionMatrix[16];
GLint viewport[4];

int main (int argc,char **argv) {
    glutInit (&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
    glutInitWindowSize(1364,689);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Sample");
    init();
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutPassiveMotionFunc(passive);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

void display() {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //  Render 3D content
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60,(GLfloat)width/(GLfloat)height,1.0,100.0);    // create 3D perspective projection matrix
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    camera();
    glTranslatef(-6,-2,0);
    glColor3f(1,0,0);
    glutSolidSphere(5,50,50);
    glPopMatrix();

    glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix);
    glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
    glGetIntegerv(GL_VIEWPORT, viewport);
    // get 3D coordinates based on window coordinates  
    gluProject(-6, -2, 0, modelviewMatrix, projectionMatrix, viewport, &centerX, &centerY, &centerZ);

    // Render 2D content
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width,height, 0);                 // create 2D orthographic projection matrix
    glMatrixMode(GL_MODELVIEW);
    glColor3f(1,1,1);
    glBegin(GL_LINES);
        glVertex2f( centerX,centerY );          // coordinate of center of the sphere in orthographic projection
        glVertex2f( cursorX,cursorY );
    glEnd();

    glutSwapBuffers();
}

void camera(void) {
    glRotatef(0.0,1.0,0.0,0.0);
    glRotatef(0.0,0.0,1.0,0.0);
    glTranslated(0,0,-20);
}

void init(void) {
    glEnable (GL_DEPTH_TEST);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_COLOR_MATERIAL);
}

void reshape(int w, int h) {
    width=w; height=h;
}

void passive(int x1,int y1) {
    cursorX=x1; cursorY=y1;
}
//OpenGL问题
#苹果__
#包括
#否则
#包括
#恩迪夫
无效被动(int,int);
空洞重塑(int,int);
void init(void);
作废显示(作废);
void摄像机(void);
int cursorX,cursorY,宽度,高度;
双centerX、centerY、centerZ;
//GLfloat modelviewMatrix[16],projectionMatrix[16];
GLdouble modelviewMatrix[16],projectionMatrix[16];
闪烁视口[4];
int main(int argc,字符**argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_双精度| GLUT_深度| GLUT_RGBA);
GLUTINITWindowsSize(1364689);
位置(0,0);
创建窗口(“样本”);
init();
glutDisplayFunc(显示器);
glutIdleFunc(显示);
glutpassiveemotionfunc(被动);
GLUTREFORUNC(重塑);
glutMainLoop();
返回0;
}
无效显示(){
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
//渲染三维内容
glMatrixMode(GL_投影);
glLoadIdentity();
gluPerspective(60,(GLfloat)宽度/(GLfloat)高度,1.0100.0);//创建三维透视投影矩阵
glMatrixMode(GLU模型视图);
glPushMatrix();
摄像机();
glTranslatef(-6,-2,0);
gl3f(1,0,0);
固体球(5,50,50);
glPopMatrix();
glGetDoublev(GLU模型视图矩阵、模型视图矩阵);
glGetDoublev(GL_投影矩阵,projectionMatrix);
glGetIntegerv(GL_视口,视口);
//基于窗口坐标获取三维坐标
gluProject(-6,-2,0,modelviewMatrix,projectionMatrix,viewport,¢erX,¢erY,¢erZ);
//渲染二维内容
glMatrixMode(GL_投影);
glLoadIdentity();
gluOrtho2D(0,宽度,高度,0);//创建二维正交投影矩阵
glMatrixMode(GLU模型视图);
gl3f(1,1,1);
glBegin(GL_行);
glVertex2f(centerX,centerY);//正交投影中球体中心的坐标
glVertex2f(cursorX,cursorY);
格伦德();
glutSwapBuffers();
}
无效摄影机(无效){
glRotatef(0.0,1.0,0.0,0.0);
glRotatef(0.0,0.0,1.0,0.0);
gl(0,0,-20);
}
void init(void){
glEnable(GLU深度试验);
glEnable(GL_混合物);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去GL_SRC_ALPHA);
glEnable(GL_颜色_材料);
}
空洞重塑(整数w,整数h){
宽度=w;高度=h;
}
无效被动(int x1,int y1){
cursorX=x1;cursorY=y1;
}

在我的代码中,centerX和centerY坐标将离开屏幕。我必须在球体的中心和鼠标指针之间画一条线。对代码进行任何修改以使其正常工作?

通常是我用来在3D/2D坐标之间切换的函数。看看它是否适合你

void toggle2DMode(bool flag, GLint Width, GLint Height) const
{
        if(flag)
        {
                glMatrixMode(GL_PROJECTION);
                glPushMatrix();
                glLoadIdentity();

                glOrtho(0.0, Width, Height, 0.0, -1.0f, 1.0f);
                glMatrixMode(GL_MODELVIEW);
                glPushMatrix();
                glLoadIdentity();
                glDisable(GL_DEPTH_TEST);
                glEnable(GL_BLEND);
        }
        else
        {
                glMatrixMode(GL_PROJECTION);
                glPopMatrix();
                glMatrixMode(GL_MODELVIEW);
                glPopMatrix();
                glEnable(GL_DEPTH_TEST);
                glDisable(GL_BLEND);
        }
}

我的函数用于检查四边形的分辨率

void WINDOW_TEXT::calcResolution( GLshort & x , GLshort & y )
{
    GLdouble tx, ty, ttx, tty, z; // target 2d coords (z is 'unused')

    GLdouble model_view[16];
    glGetDoublev(GL_MODELVIEW_MATRIX, model_view);

    GLdouble projection[16];
    glGetDoublev(GL_PROJECTION_MATRIX, projection);

    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);

    // get window coords based on 3D coordinates
    gluProject( up_right.x, up_right.y, up_right.z,
                model_view, projection, viewport,
                &tx, &ty, &z);

    gluProject( down_left.x, down_left.y, down_left.z,
                model_view, projection, viewport,
                &ttx, &tty, &z);

    x = (GLshort)(tx-ttx);
    y = (GLshort)(tty-ty);
};

“z”被忽略,得到的是存储在x中的纯分辨率,而y

这与只有一个答案的线程有什么不同。我试过了,但没能成功。代码已经修改,以包含该线程中建议的内容。仍然得到奇怪的结果。你不会因为没有得到好的答案而一直问同一个问题。让我重新定义我的问题。如果三维坐标系中有一个点x,y,z,那么它在屏幕坐标系中对应的x,y是什么?哦。您是否尝试过简单地使用函数?函数定义:将对象坐标映射到窗口坐标我在上面编写的代码中使用了gluProject。它给出了奇怪的结果。项目返回的x、y、z值不在屏幕上。我希望鼠标位置(2D)和球体中心(3D)位于同一坐标系中。我无法将3D转换为2D。但现在我成功地将二维鼠标坐标转换为三维坐标系。这解决了我的问题。从NeHe教程中选择代码。我的更新代码:(使用gluUnProject将2D转换为3D):