我的环境是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();下楼贴我的漫游实现,顺便看看那个参考点的坐标到底该怎么随眼睛(相机)改变
是不是跟我之前参考点的坐标没改变有关,还是说用了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();下楼贴我的漫游实现,顺便看看那个参考点的坐标到底该怎么随眼睛(相机)改变
{
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);
}
Vector3 eyePosition(2.0f,2.0f,1.0f); //视点坐标
Vector3 viewAtPosition(1.0,-0.5,-1.0); // 参考点的坐标还有上面那个相机眼睛代码中的gluat(...)中,我把参考点本来要加的某个东西都去掉了,一直都是保持我的参考点不变的,实在不懂这个参考点怎么随着我们改变而改变
高手快来帮助我吧,谢谢
这个数组究竟先存什么啊
另外,void COpenGLAppView::billboardCheatCylindricalBegin()
是实现loadidentity吗?
为什么i += 2?
//绑定纹理
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();