请教OPENGL捕获坐标问题!

pan7861 2004-09-13 03:28:22
请看syy64(太平洋) 所发代码http://community.csdn.net/Expert/topic/3146/3146805.xml?temp=.4938471
TO太平洋:你的代码中的m_hGLContext,m_pDoc,m_dModelMinX,m_dModelMaxX,m_pRoamParameter,dMouseModelX都是如何定义的。能不能给个解释说明,另外我所画的点连线,所有点都是有序号的,如何返回捕获点的序号呢,所有点的数据是放是数组中的。
...全文
516 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
pan7861 2004-09-29
  • 打赏
  • 举报
回复
我点在有模型处,X,Y值是0,而Z值还是天文数字也不对啊
syy64 2004-09-29
  • 打赏
  • 举报
回复
不应该这样,也许是你的程序别的地方出错了,仔细查查。
pan7861 2004-09-28
  • 打赏
  • 举报
回复
我得到的是天文数字,明显不对啊
syy64 2004-09-28
  • 打赏
  • 举报
回复
鼠标只有点在有模型处,才能得到正确值。
zh_zh_y 2004-09-24
  • 打赏
  • 举报
回复
楼主你的问题解决了吗?我现在也需要解决类似的问题。

用户在场景内进行漫游,当看到管道时,可以使用鼠标在屏幕上对某段管道进行选择,能够获取该段管道的三维空间坐标(x,y,z),并对这段管道进行加亮显示。

从二维屏幕位置(屏幕坐标x,y,屏幕坐标的原点应该是屏幕左上角)——转换到———三维空间的位置,好像可以使用gluProject函数来进行转换。
http://community.csdn.net/Expert/topic/3401/3401390.xml?temp=9.693545E-02

一起来探讨探讨。我现在正在调试syy64(太平洋) 所给代码但是没有获取需要的结果。

syy64 2004-09-24
  • 打赏
  • 举报
回复
to: pan7861(风间火月) :我给你的例子中有一个是反馈模式;
to: zh_zh_y(决不放弃):
void CMouseSelView::OnLButtonUp(UINT nFlags, CPoint point)
{
GLfloat fdepth; //深度信息
GLdouble ObjectX, ObjectY, ObjectZ; //模型的坐标

GLint iViewPort[4]; //视口数组
GLdouble dProjMatrix[16]; //投影矩阵
GLdouble dModelMatrix[16]; //模视矩阵

wglMakeCurrent(hdc, hrlrc);
glGetIntegerv(GL_VIEWPORT, iViewPort); //获取视口矩阵
glGetDoublev(GL_MODELVIEW_MATRIX, dModelMatrix); //获取模视矩阵
glGetDoublev(GL_PROJECTION_MATRIX, dProjMatrix); //获取投影矩阵

glReadPixels(point.x, iViewPort[3]-point.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fdepth); //获取深度信息

gluUnProject((GLdouble)point.x, (GLdouble)(iViewPort[3]-point.y), (GLdouble)fdepth, dModelMatrix, dProjMatrix, iViewPort, &ObjectX, &ObjectY, &ObjectZ);
wglMakeCurrent(hdc, NULL);
}

只有在场景放得比较大的情况下才比较准确。

zh_zh_y 2004-09-24
  • 打赏
  • 举报
回复
难道没有人能告诉正确的处理方式?郁闷。
pan7861 2004-09-24
  • 打赏
  • 举报
回复
我和你出现的问题一样,我的场景内绘制图形的坐标范围是-10到10,但是取出来的坐标值非常大。完全和真实坐标不吻合。看看有什么方法大家互相参考参考,这个贴子我先不结,太平洋你先别急着拿分,呵呵。
zh_zh_y 2004-09-24
  • 打赏
  • 举报
回复
不知道我理解的对不对?
我目前获取的坐标点的三维数据差别挺大。
目前我的理解是:在OPENGL坐标系上,根据模型的位置绘制三维模型,比如说,A模型中心位置在(-10.0,-10.0,-10.0) ,B模型中心位置在在(-8.0,2.0,3.0)等,我在opengl中按照他们的具体三维位置进行绘制,显示在三维场景中。不管视点如何变化,模型在opengl中的绝对位置不会发生改变。场景漫游只是视点发生了变化。然后场景模型会根据投影矩阵投射到屏幕上。我希望在屏幕上,使用鼠标来获取三维场景在屏幕上的三维坐标。

void CMouseSelView::OnLButtonUp(UINT nFlags, CPoint point)
{
GLfloat fdepth; //深度信息
GLdouble ObjectX, ObjectY, ObjectZ; //模型的坐标

GLint iViewPort[4]; //视口数组
GLdouble dProjMatrix[16]; //投影矩阵
GLdouble dModelMatrix[16]; //模视矩阵

glGetIntegerv(GL_VIEWPORT, iViewPort); //获取视口矩阵
glGetDoublev(GL_MODELVIEW_MATRIX, dModelMatrix); //获取模视矩阵
glGetDoublev(GL_PROJECTION_MATRIX, dProjMatrix); //获取投影矩阵

glReadPixels(point.x, iViewPort[3]-point.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fdepth); //获取深度信息

gluUnProject((GLdouble)point.x, (GLdouble)(iViewPort[3]-point.y), (GLdouble)fdepth, dModelMatrix, dProjMatrix, iViewPort, &ObjectX, &ObjectY, &ObjectZ);

}

以上使我使用点击鼠标左键,来获取三维坐标的函数代码,我得理解是如果我在场景中选择了A模型,ObjectX/ObjectY/ObjectZ应该返回的是前面我所述的模型的绝对坐标,也就是(-10.0,-10.0,-10.0),当然坐标值不一定如此精确,但是应该差别不会很大。但是目前我所获取的值差别很大,不知什么缘故?
pan7861 2004-09-24
  • 打赏
  • 举报
回复
我的问题还没解决,不过syy64(太平洋)给的代码是选择模式,我们好象应该用反馈模式。在绘制的过程中需要装载该图元的ID(应该这样叫吧)以及该图元的信息。但是对我来说节点数不固定,如何动态DEFINE呢?
pan7861 2004-09-22
  • 打赏
  • 举报
回复
这都是书上的例子,我要画的节点很多,每个节点都需要#define一个ID 吗?是否做个循环,每画一条连线就把两个端点的ID传给glLoadName。glSelectBuffer这个函数的参数是放节点的数组吗?
syy64 2004-09-22
  • 打赏
  • 举报
回复
opengl反馈模式返回的是图元信息,点、线、面和多边形都是图元,看你如何设计就行。
syy64 2004-09-21
  • 打赏
  • 举报
回复
// Planets.c
// OpenGL SuperBible, Chapter 14
// Demonstrates OpenGL Selection/Picking
// Program by Richard S. Wright Jr.

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <math.h>


#define glRGB(x, y, z) glColor3ub((GLubyte)x, (GLubyte)y, (GLubyte)z)

#define SUN 1
#define MERCURY 2
#define VENUS 3
#define EARTH 4
#define MARS 5

GLfloat fAspect;

// Lighting values
GLfloat whiteLight[] = { 0.35f, 0.35f, 0.35f, 1.0f };
GLfloat sourceLight[] = { 0.65f, 0.65f, 0.65f, 1.0f };
GLfloat lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };


// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Save the matrix state and do the rotations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// Translate the whole scene out and into view
glTranslatef(0.0f, 0.0f, -300.0f);

// Initialize the names stack
glInitNames();
glPushName(0);


// Set material color, Yellow
// Sun
glRGB(255, 255, 0);
glLoadName(SUN);
glutSolidSphere(15.0f, 15, 15);

// Draw Mercury
glRGB(128,0,0);
glPushMatrix();
glTranslatef(24.0f, 0.0f, 0.0f);
glLoadName(MERCURY);
glutSolidSphere(2.0f,15,15);
glPopMatrix();

// Draw Venus
glPushMatrix();
glRGB(128,128,255);
glTranslatef(60.0f, 0.0f, 0.0f);
glLoadName(VENUS);
glutSolidSphere(4.0f,15,15);
glPopMatrix();

// Draw the Earth
glPushMatrix();
glRGB(0,0,255);
glTranslatef(100.0f,0.0f,0.0f);
glLoadName(EARTH);
glutSolidSphere(8.0f,15,15);
glPopMatrix();

// Draw Mars
glRGB(255,0,0);
glPushMatrix();
glTranslatef(150.0f, 0.0f, 0.0f);
glLoadName(MARS);
glutSolidSphere(4.0f,15,15);
glPopMatrix();


// Restore the matrix state
glPopMatrix(); // Modelview matrix

glutSwapBuffers();
}


// Present the information on which planet/sun was selected and displayed
void ProcessPlanet(GLuint id)
{
switch(id)
{
case SUN:
MessageBox(NULL,"You clicked on the Sun!","Info",MB_OK | MB_ICONEXCLAMATION);
break;

case MERCURY:
MessageBox(NULL,"You clicked on Mercury!","Info",MB_OK | MB_ICONEXCLAMATION);
break;

case VENUS:
MessageBox(NULL,"You clicked on Venus!","Info",MB_OK | MB_ICONEXCLAMATION);
break;

case EARTH:
MessageBox(NULL,"You clicked on Earth!","Info",MB_OK | MB_ICONEXCLAMATION);
break;

case MARS:
MessageBox(NULL,"You clicked on Mars!","Info",MB_OK | MB_ICONEXCLAMATION);
break;

default:
MessageBox(NULL,"Nothing was clicked on!","Error",MB_OK | MB_ICONEXCLAMATION);
break;
}
}



// Process the selection, which is triggered by a right mouse
// click at (xPos, yPos).
#define BUFFER_LENGTH 64
void ProcessSelection(int xPos, int yPos)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];

// Hit counter and viewport storeage
GLint hits, viewport[4];

// Setup selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);

// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);

// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();

// Change render mode
glRenderMode(GL_SELECT);

// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horzontal direction
glLoadIdentity();
gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);

// Apply perspective matrix
gluPerspective(45.0f, fAspect, 1.0, 425.0);

// Draw the scene
RenderScene();

// Collect the hits
hits = glRenderMode(GL_RENDER);

// If a single hit occured, display the info.
if(hits == 1)
ProcessPlanet(selectBuff[3]);

// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();

// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);
}



// Process the mouse click
void MouseCallback(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
ProcessSelection(x, y);
}


// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Light values and coordinates
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate insides

// Enable lighting
glEnable(GL_LIGHTING);

// Setup and enable light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);

// Enable color tracking
glEnable(GL_COLOR_MATERIAL);

// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// Black blue background
glClearColor(0.60f, 0.60f, 0.60f, 1.0f );
}



void ChangeSize(int w, int h)
{
// Prevent a divide by zero
if(h == 0)
h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);

// Calculate aspect ratio of the window
fAspect = (GLfloat)w/(GLfloat)h;

// Set the perspective coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Field of view of 45 degrees, near and far planes 1.0 and 425
gluPerspective(45.0f, fAspect, 1.0, 425.0);

// Modelview matrix reset
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600,300);
glutCreateWindow("Pick a Planet");
glutReshapeFunc(ChangeSize);
glutMouseFunc(MouseCallback);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();

return 0;
}
syy64 2004-09-21
  • 打赏
  • 举报
回复
// Select.c
// OpenGL SuperBible, Chapter 14
// Demonstrates OpenGL Picking and Selection with feedback
// Program by Richard S. Wright Jr.

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <math.h>



#define glRGB(x, y, z) glColor3ub((GLubyte)x, (GLubyte)y, (GLubyte)z)

#define CUBE 1
#define SPHERE 2

RECT bRect; // Bounding rectangle
GLuint nWho = 0; // Who is selected
float fAspect;

// Application name and instance storeage
static LPCTSTR lpszAppName = "Select an Object";
static HINSTANCE hInstance;

// Lighting values
GLfloat whiteLight[] = { 0.35f, 0.35f, 0.35f, 1.0f };
GLfloat sourceLight[] = { 0.65f, 0.65f, 0.65f, 1.0f };
GLfloat lightPos[] = { -500.0f, 500.0f, 600.0f, 1.0f };



// Render the cube and sphere
void DrawObjects(void)
{
// Save the matrix state and do the rotations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// Translate the whole scene out and into view
glTranslatef(-80.0f, 0.0f, -300.0f);

// Initialize the names stack
glInitNames();
glPushName(0);

// Set material color, Yellow
// Cube
glRGB(255, 255, 0);
glLoadName(CUBE);
glPassThrough((GLfloat)CUBE);
glutSolidCube(75.0f);


// Draw Sphere
glRGB(128,0,0);
glTranslatef(130.0f, 0.0f, 0.0f);
glLoadName(SPHERE);
glPassThrough((GLfloat)SPHERE);
glutSolidSphere(50.0f, 15, 15);

// Restore the matrix state
glPopMatrix(); // Modelview matrix
}


// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Draw the objects in the scene
DrawObjects();

// If something is selected, draw a bounding box around it
if(nWho != 0)
{
int viewport[4];

// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);

// Remap the viewing volume to match window coordinates (approximately)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

// Establish clipping volume (left, right, bottom, top, near, far)
glOrtho(viewport[0], viewport[2], viewport[3], viewport[1], -1, 1);
glMatrixMode(GL_MODELVIEW);

glDisable(GL_LIGHTING);
glColor3ub(255,0,0);
glBegin(GL_LINE_LOOP);
glVertex2i(bRect.left, bRect.top);
glVertex2i(bRect.left, bRect.bottom);
glVertex2i(bRect.right, bRect.bottom);
glVertex2i(bRect.right, bRect.top);
glEnd();
glEnable(GL_LIGHTING);
}

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);

glutSwapBuffers();
}




// Go into feedback mode and draw a rectangle around the object
#define FEED_BUFF_SIZE 4096
void MakeSelection(int nChoice)
{
// Space for the feedback buffer
GLfloat feedBackBuff[FEED_BUFF_SIZE];

// Storeage for counters, etc.
int size,i,j,count;

// Initial minimum and maximum values
bRect.right = bRect.bottom = -999999.0f;
bRect.left = bRect.top = 999999.0f;

// Set the feedback buffer
glFeedbackBuffer(FEED_BUFF_SIZE,GL_2D, feedBackBuff);

// Enter feedback mode
glRenderMode(GL_FEEDBACK);

// Redraw the scene
DrawObjects();

// Leave feedback mode
size = glRenderMode(GL_RENDER);

// Parse the feedback buffer and get the
// min and max X and Y window coordinates
i = 0;
while(i < size)
{
// Search for appropriate token
if(feedBackBuff[i] == GL_PASS_THROUGH_TOKEN)
if(feedBackBuff[i+1] == (GLfloat)nChoice)
{
i+= 2;
// Loop until next token is reached
while(i < size && feedBackBuff[i] != GL_PASS_THROUGH_TOKEN)
{
// Just get the polygons
if(feedBackBuff[i] == GL_POLYGON_TOKEN)
{
// Get all the values for this polygon
count = (int)feedBackBuff[++i]; // How many vertices
i++;

for(j = 0; j < count; j++) // Loop for each vertex
{
// Min and Max X
if(feedBackBuff[i] > bRect.right)
bRect.right = feedBackBuff[i];

if(feedBackBuff[i] < bRect.left)
bRect.left = feedBackBuff[i];
i++;

// Min and Max Y
if(feedBackBuff[i] > bRect.bottom)
bRect.bottom = feedBackBuff[i];

if(feedBackBuff[i] < bRect.top)
bRect.top = feedBackBuff[i];
i++;
}
}
else
i++; // Get next index and keep looking
}
break;
}
i++;
}
}



// Process the selection, which is triggered by a right mouse
// click at (xPos, yPos).
#define BUFFER_LENGTH 64
void ProcessSelection(int xPos, int yPos)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];

// Hit counter and viewport storeage
GLint hits, viewport[4];

// Setup selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);

// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);

// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();

// Change render mode
glRenderMode(GL_SELECT);

// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horzontal direction
glLoadIdentity();
gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);

// Apply perspective matrix
gluPerspective(60.0f, fAspect, 1.0, 425.0);

// Draw the scene
DrawObjects();

// Collect the hits
hits = glRenderMode(GL_RENDER);

// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();

// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);

// If a single hit occured, display the info.
if(hits == 1)
{
MakeSelection(selectBuff[3]);
if(nWho == selectBuff[3])
nWho = 0;
else
nWho = selectBuff[3];
}

glutPostRedisplay();
}




// This function does any needed initialization on the rendering
// context. Here it sets up and initializes the lighting for
// the scene.
void SetupRC()
{
// Light values and coordinates
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
//glEnable(GL_CULL_FACE); // Do not calculate insides

// Enable lighting
glEnable(GL_LIGHTING);

// Setup and enable light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);

// Enable color tracking
glEnable(GL_COLOR_MATERIAL);

// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// Black blue background
glClearColor(0.60f, 0.60f, 0.60f, 1.0f );
glLineWidth(2.0f);
}


void ChangeSize(int w, int h)
{
// Prevent a divide by zero
if(h == 0)
h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);

// Calculate aspect ratio of the window
fAspect = (GLfloat)w/(GLfloat)h;

// Set the perspective coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Field of view of 45 degrees, near and far planes 1.0 and 425
gluPerspective(60.0f, fAspect, 1.0, 425.0);

// Modelview matrix reset
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

// Process the mouse click
void MouseCallback(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
ProcessSelection(x, y);
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Select an Object");
glutReshapeFunc(ChangeSize);
glutMouseFunc(MouseCallback);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();

return 0;
}
pan7861 2004-09-21
  • 打赏
  • 举报
回复
我看我的问题还没解决,太平洋兄多谢能给我提供两个关于反馈模式的例子程序看看吗,连接地址也行,我的信箱:philips-pan@vip.sina.com,回完这个贴我就把分给你结了。
syy64 2004-09-19
  • 打赏
  • 举报
回复
dMouseModelX是在当前的前面用gluunProject得到的鼠标有效的(在场景范围内)空间坐标值;
根据你的情况,m_dModelMinX应该为-10,m_dModelMaxX应该为10。
pan7861 2004-09-19
  • 打赏
  • 举报
回复
dMouseModelX是什么含义.
我把所有读取的X,Y,Z轴坐标都通过算法把范围定在-10到10以内了(为了将不同坐标范围得图形画到屏幕以内,我屏幕内得场景坐标范围定得是-10到10),那么m_dModelMinX等变量也是这样吗?比如我图形里最小X轴坐标是100但是同意经过放大或缩小变成了10,那么m_dModelMinX就等于10是吗
syy64 2004-09-17
  • 打赏
  • 举报
回复
不是这样的,不用比较,返回节点号是用选择模式;
不是,m_dModelMinX,m_dModelMaxX是场景中所有模型的范围;
可以不需要定义m_pDoc文档类指针;
哥们,你的信誉值咋那么低?
pan7861 2004-09-17
  • 打赏
  • 举报
回复
TO SYY64:那你是否要将捕获的坐标和数据文件(数组中保存的节点信息)进行比较,数据相近的就将该点的节点号返回对吗?
m_dModelMinX,m_dModelMaxX是屏幕中绘制的最大坐标最小坐标吗,比如我数据文件中的某点坐标值是100,200,300,而画到屏幕中的OPENGL坐标值是限定在-10到10的范围里了那么m_dModelMinX,m_dModelMaxX就是-10和10对吗?
dMouseModelX是什么意思,我是在VIEW类里定义的,是否可以不需要定义m_pDoc文档类指针?
alphapaopao 2004-09-17
  • 打赏
  • 举报
回复
太平洋的信誉也太高了 呵呵
加载更多回复(7)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧