我的环境是VS2005中用MFC来搭建OPENGL环境然后网上找的漫游代码,自己修修改改之后,是可以简单漫游(我是参考点坐标始终不变,然后根据键盘或鼠标改变眼睛的坐标,参考点的坐标如何变,我实在不懂),然后我给一棵树加了个billboard算法(某个英文介绍中的,待会贴),之后那棵树确实是可以始终面向我。不过它的位置明显错误了,因为我在树的旁边还有一个箱子,在漫游中,发现树始终面向我,但它和箱子的相对位置却始终在改变,这肯定是错的吧因为我使用的是glulookat()函数,就是说坐标系里的物体的位置不可能改变,树扎根的地方不变,只是他会随着我的眼睛饶Y轴旋转而已,而现在是扎根的位置用了billboard会变
是不是跟我之前参考点的坐标没改变有关,还是说用了glulookat就不能搭配billboard算法了以下是一些代码
void COpenGLAppView::billboardCheatCylindricalBegin()
{
float modelview[16];
int i,j; // save the current modelview matrix
glPushMatrix(); // get the current modelview matrix
glGetFloatv(GL_MODELVIEW_MATRIX , modelview); for( i=0; i<3; i+=2 ) 
    for( j=0; j<3; j++ ) {
if ( i==j )
    modelview[i*4+j] = 1.0;
else
    modelview[i*4+j] = 0.0;
    } // set the modelview matrix
glLoadMatrixf(modelview);
}
void COpenGLAppView::billboardEnd()
{
// restore the previously 
// stored modelview matrix
glPopMatrix();}
BOOL COpenGLAppView::RenderScene() 
{
。。渲染函数里,这里绘制了一个长方体,就不贴代码了,以下是树的绘制代码
billboardCheatCylindricalBegin();
glBegin(GL_QUADS);                 // 绘制平行于XY面四边形面
//glColor3f(0.0f, 0.0f, 0.0f);
glTexCoord2d( 0, 0 );glVertex3f( 1.0f, -0.5f, -1.0f); // 
glTexCoord2d( 1, 0 );glVertex3f( 1.5f, -0.5f, -1.0f); // 
glTexCoord2d( 1, 1 );glVertex3f( 1.5f, 0.0f, -1.0f); // 
glTexCoord2d( 0, 1 );glVertex3f( 1.0f, 0.0f, -1.0f); // 
glEnd();
billboardEnd();下楼贴我的漫游实现,顺便看看那个参考点的坐标到底该怎么随眼睛(相机)改变

解决方案 »

  1.   

    这是主要绘制的实现代码BOOL COpenGLAppView::RenderScene() 
    {
    init();
    //glClearColor(1.0f, 1.0f, 1.0f, 1.0f);  // 设置刷新背景色
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// 刷新背景 glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST); // 启用深度测试
    glDepthFunc(GL_LESS); glLoadIdentity(); glPushMatrix(); //gluLookAt(2.0,2.0,1.0,1.0,0.0,0.0,0.0,1.0,0.0);
    Camera();
    ////绑定纹理
    TextureManager::Inst()->BindTexture( 0 ); glBegin(GL_POLYGON);                 // 绘制地面四边形
    //glColor3f(0.0f, 0.0f, 0.0f);
    glTexCoord2f(0.0f, 0.0f);glVertex3f( 0.0f, -0.5f, 0.0f); // 
    glTexCoord2f(1.0f, 0.0f);glVertex3f( 1.5f, -0.5f, 0.0f); // 
    glTexCoord2f(1.0f, 1.0f);glVertex3f( 1.5f, -0.5f, -2.0f); // 
    glTexCoord2f(0.0f, 1.0f);glVertex3f( 0.0f, -0.5f, -2.0f); // 
    glEnd();
    //还有箱子的绘制代码,都是差不多的,不贴了,太长了
    然后这里是camera函数
    GLvoid COpenGLAppView::Camera()
    {
    if(theta>360) //角度不能大于360度
    theta=0.0f;   //if (viewUp> 0.5f) viewUp = 0.5f; //不要抬得太高  
    //if (viewUp<-0.6f) viewUp =-0.6f;    //// 新的参考点的位置,这里始终不懂这个参考点改变是怎么回事,把它注销了,才能成功漫游
    /*viewAtPosition.x = float(eyePosition.x + cos(theta));   
    viewAtPosition.z = float(eyePosition.z + sin(theta));
    viewAtPosition.y = eyePosition.y;*/ gluLookAt( eyePosition.x,eyePosition.y ,eyePosition.z, // 视点位置
    viewAtPosition.x, viewAtPosition.y , viewAtPosition.z , //参考点位置
    0.0,1.0,0.0); //向上
    return ;
    }然后是键盘事件void COpenGLAppView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值 switch (nChar)
    {
    case VK_UP:
    eyePosition.x+= (viewAtPosition.x-eyePosition.x)*speed;
    eyePosition.z+= (viewAtPosition.z-eyePosition.z)*speed; break;
    case VK_DOWN:
    eyePosition.x-=(viewAtPosition.x-eyePosition.x)*speed;
    eyePosition.z-=(viewAtPosition.z-eyePosition.z)*speed;
    break;
    case VK_LEFT: eyePosition.x+=(viewAtPosition.z-eyePosition.z)*speed;
    eyePosition.z+= -(viewAtPosition.x-eyePosition.x)*speed;   
    break;
    case VK_RIGHT: eyePosition.x-=(viewAtPosition.z-eyePosition.z)*speed;
    eyePosition.z-= -(viewAtPosition.x-eyePosition.x)*speed;    
    break;
    case 'A':
    eyePosition.x+=(viewAtPosition.z-eyePosition.z)*speed;
    eyePosition.z+= -(viewAtPosition.x-eyePosition.x)*speed;   
    break;
    case 'D':
    eyePosition.x-=(viewAtPosition.z-eyePosition.z)*speed;
    eyePosition.z-= -(viewAtPosition.x-eyePosition.x)*speed;    
    break;
    case 'W':
    eyePosition.x+= (viewAtPosition.x-eyePosition.x)*speed;
    eyePosition.z+= (viewAtPosition.z-eyePosition.z)*speed;
    break;
    case 'S':
    eyePosition.x-=(viewAtPosition.x-eyePosition.x)*speed;
    eyePosition.z-=(viewAtPosition.z-eyePosition.z)*speed;
    break;
    case 27:                    /*按ESCAPE时退出窗口*/
    exit(0);
    break;
    default:
    break;
    } InvalidateRect(NULL,FALSE); CView::OnKeyDown(nChar, nRepCnt, nFlags);
    }
      

  2.   

    事先全局变量GLfloat speed = 0.1f;
    Vector3 eyePosition(2.0f,2.0f,1.0f); //视点坐标
    Vector3 viewAtPosition(1.0,-0.5,-1.0); // 参考点的坐标还有上面那个相机眼睛代码中的gluat(...)中,我把参考点本来要加的某个东西都去掉了,一直都是保持我的参考点不变的,实在不懂这个参考点怎么随着我们改变而改变
      

  3.   

    有没有人帮忙看一下,我不能回复了我的树就是不能定点啊我想实现billboard树,但它必须得定点跟着镜头旋转才行啊不能改变位置啊
    高手快来帮助我吧,谢谢
      

  4.   

    建议楼主把认为有问题的时刻截图下来 放到自己的blog上去,然后给链接出来
      

  5.   

    袄,我现在的问题就是我用的 billboard算法 可以实现 树始终面向我,但是树的位置改变了,树没有在原地旋转好象是说需要在我这个billboard算法画好之后,要来个什么移动还什么的,总之我不太懂这个算法,哎,郁闷死了
      

  6.   

    那个数组 是不是要事先把 要画的四个顶点存进去啊?始终不太懂那个算法的意思啊刚刚有人跟我解释说 opengl都是先把那个片面移动到原点去billboard算法中的modelview[16]数组中去啊
    这个数组究竟先存什么啊
      

  7.   

    glulookat 的第二个参数要设为你的树的世界坐标。对于漫游来说,你只需要改变glulookat的第一个参数和up向量即可。
    另外,void COpenGLAppView::billboardCheatCylindricalBegin()
    是实现loadidentity吗?
    为什么i += 2?
      

  8.   

    我做了如下修改后,看似树好象定点了,但是树的大小却改变了,变得异常大这又是为什么呢?我就是把绘制树的那段代码中原来准确的坐标改为数组来计算,如下为修改代码:
    //绑定纹理
    TextureManager::Inst()->BindTexture( 2 );
    glTranslatef ( 2.0, 0.0, -1.0);
    billboardCheatCylindricalBegin();

    glBegin(GL_QUADS);                 // 绘制远处平行于XY面四边形面
    //glColor3f(0.0f, 0.0f, 0.0f);
    glTexCoord2d( 0, 0 );//glVertex3f( 2.0f, -0.5f, -1.0f); // 
    glVertex3f(-(modelview[0]+modelview[1]),-(modelview[4]+modelview[5]),-(modelview[8]+modelview[9]));
    glTexCoord2d( 1, 0 );//glVertex3f( 2.5f, -0.5f, -1.0f); // 
    glVertex3f(modelview[0]-modelview[1],modelview[4]-modelview[5],modelview[8]-modelview[9]);
    glTexCoord2d( 1, 1 );//glVertex3f( 2.5f, 0.0f, -1.0f); // 
    glVertex3f(modelview[0]+modelview[1],modelview[4]+modelview[5],modelview[8]+modelview[9]);
    glTexCoord2d( 0, 1 );//glVertex3f( 2.0f, 0.0f, -1.0f); // 
    glVertex3f(modelview[1]-modelview[0],modelview[5]-modelview[4],modelview[9]-modelview[8]);
    glEnd();
    billboardEnd();