查看: 3490|回复: 6

gluLookAt与osg::matrix::makeLookAt

[复制链接]

该用户从未签到

发表于 2010-5-3 12:01:40 | 显示全部楼层 |阅读模式
我在程序中用gluLookAt()实现场景的旋转、缩放和平移,同时把其中的视点位置向量和观察点位置向量传递给osg中相机的视图矩阵对osg加载的模型进行相同的操作,用的是viewMatrix::makeLookAt()。结果发现两者的模型旋转,平移和缩放的比例不一致。求高手指点。。。

该用户从未签到

发表于 2010-5-3 21:11:08 | 显示全部楼层
这可能需要考虑其他代码的影响,也许您需要提供更多的信息

该用户从未签到

 楼主| 发表于 2010-5-3 22:19:08 | 显示全部楼层
2# array

以下是我源码的主要部分,望各位指点一下到底是什么地方出问题了。。。

OSG初始化,加载模型函数(用sceneView)

  1. void COSGFrame::InitSceneView(std::string filename)
  2. {
  3. m_root = new osg::Group;
  4. fileName = filename;
  5. sceneView->setDefaults();
  6. sceneView->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);
  7. m_Model = osgDB::readNodeFile(fileName);
  8. osgUtil::Optimizer optimizer;
  9. optimizer.optimize(m_Model.get());
  10. optimizer.reset();
  11. osg::PositionAttitudeTransform* newModelPAT = new osg::PositionAttitudeTransform;
  12. newModelPAT->addChild(m_Model.get());
  13. newModelPAT->setPosition(osg::Vec3(0,-100,-10));
  14. newModelPAT->setScale(osg::Vec3(1.0,1.0,1.0));
  15. m_root->addChild(newModelPAT);
  16. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("01.ive");
  17. osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform;
  18. pat->setPosition(osg::Vec3(-350.035,123.94,-10.000136811));
  19. pat->setScale(osg::Vec3(0.5,0.5,0.5));
  20. pat->addChild(node.get());
  21. m_root->addChild(pat);
  22. osg::PositionAttitudeTransform* pat1 = new osg::PositionAttitudeTransform;
  23. pat1->setPosition(osg::Vec3(127.492,-59.3833,-10));
  24. pat1->setScale(osg::Vec3(0.3,0.3,0.3));
  25. pat1->addChild(m_Model.get());
  26. m_root->addChild(pat1);
  27. precipitationEffect = new osgParticle::PrecipitationEffect;
  28. precipitationEffect->snow(0.5);
  29. precipitationEffect->setParticleColor(osg::Vec4(1,1,1,1));
  30. precipitationEffect->setWind(osg::Vec3(2,0,0));
  31. //m_root->addChild(precipitationEffect.get());
  32. sceneView->setSceneData(m_root.get());
  33. viewMatrix.makeLookAt(eyePoint,center,osg::Vec3(0.0f,0.0f,1.0f));
  34. }

  35. void COSGFrame::OSG_Render_Frame()
  36. {
  37. //PreOSGRenderFrame(x,y,z);
  38. sceneView->getCamera()->setClearMask(GL_DEPTH_BUFFER_BIT);
  39. sceneView->setViewport(0,0,getWindowWidth(),getWindowHeight());
  40. viewMatrix.makeLookAt(eyePoint,center,upDirection);
  41. sceneView->setViewMatrix(viewMatrix);

  42. sceneView->update();
  43. sceneView->cull();
  44. sceneView->draw();
  45. //PostOSGRenderFrame();
  46. //SwapBuffers(::GetDC(_hwnd));
  47. }
复制代码


自定义的相机操作,主要是计算场景漫游时的视点位置、观察点位置的变化
只贴了旋转部分的

  1. void CSelfCamera::rotateView(float angle, float X,float Y,float Z)
  2. {
  3. Vector3 newView;

  4. Vector3 view = m_View - m_Position;
  5. float cosTheta = (float)cos(angle);
  6. float sinTheta = (float)sin(angle);
  7. newView.x = (cosTheta + (1 - cosTheta) * X * X)   *   view.x;
  8. newView.x += ((1 - cosTheta) * X * Y - Z * sinTheta) * view.y;
  9. newView.x += ((1 - cosTheta) * X * Z + Y * sinTheta) * view.z;
  10. newView.y  = ((1 - cosTheta) * X * Y + Z * sinTheta) * view.x;
  11. newView.y += (cosTheta + (1 - cosTheta) * Y * Y)  * view.y;
  12. newView.y += ((1 - cosTheta) * Y * Z - X * sinTheta) * view.z;
  13. newView.z  = ((1 - cosTheta) * X * Z - Y * sinTheta) * view.x;
  14. newView.z += ((1 - cosTheta) * Y * Z + X * sinTheta) * view.y;
  15. newView.z += (cosTheta + (1 - cosTheta) * Z * Z)  * view.z;
  16. m_View = m_Position + newView;
  17. }
  18. void CSelfCamera::setViewByMouse(CPoint oldPot,CPoint currPot)
  19. {
  20. CRect rect;
  21. GetClientRect(m_windowHandle,rect);
  22. CPoint mousePos;
  23. int middleX = rect.Width()/2;
  24. int middleY = rect.Height()/2;
  25. float angleY = 0.0f;
  26. float angleZ = 0.0f;
  27. static float currentRotX = 0.0f;
  28. if(currPot == oldPot)
  29.   return;
  30. angleY = (float)(( currPot.x - oldPot.x)) / 1000.0f;
  31. angleZ = (float)(( currPot.y - oldPot.y)) / 1000.0f;
  32. static float lastRotX = 0.0f;
  33. lastRotX = currentRotX;
  34. currentRotX += angleZ;
  35. if (currentRotX > 1.0f)
  36. {
  37.   currentRotX = 1.0f;
  38.   if (lastRotX != 1.0f)
  39.   {
  40.    Vector3 vAxis = m_View - m_Position;
  41.    vAxis = vAxis.crossProduct(m_upVector);
  42.    vAxis = vAxis.normalize();
  43.    rotateView(1.0f - lastRotX,vAxis.x,vAxis.y,vAxis.z);
  44.   }
  45. }
  46. else if (currentRotX < -1.0f)
  47. {
  48.   currentRotX = -1.0f;
  49.   if (lastRotX != -1.0f)
  50.   {
  51.    Vector3 vAxis = m_View - m_Position;
  52.    vAxis = vAxis.crossProduct(m_upVector);
  53.    vAxis = vAxis.normalize();
  54.    rotateView(-1.0f - lastRotX,vAxis.x,vAxis.y,vAxis.z);
  55.   }
  56. }
  57. else
  58. {
  59.   Vector3 vAxis = m_View - m_Position;
  60.   vAxis = vAxis.crossProduct(m_upVector);
  61.   vAxis = vAxis.normalize();
  62.   rotateView(angleZ,vAxis.x,vAxis.y,vAxis.z);
  63. }
  64. rotateView(angleY,0,1,0);
  65. }
复制代码


以下是MFC程序的view类

  1. int CosgSceneViewTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. if (CView::OnCreate(lpCreateStruct) == -1)
  4.   return -1;
  5. // TODO:  在此添加您专用的创建代码
  6. Init();
  7. m_osgFrame = new COSGFrame(m_hWnd);
  8. m_selfCamera = new CSelfCamera(m_hWnd);
  9. m_selfCamera->setCamera(0.0f,0.5f, -100.0f, 0.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f);
  10. m_osgFrame->eyePoint = OpenglToOsg(-(m_selfCamera->m_Position));
  11. m_osgFrame->center = OpenglToOsg(m_selfCamera->m_View);
  12. return 0;
  13. }
  14. void CosgSceneViewTestView::OnDestroy()
  15. {
  16. if (wglGetCurrentContext() != NULL)
  17. {
  18.   wglMakeCurrent(NULL,NULL);
  19. }
  20. if (m_hGLContext != NULL)
  21. {
  22.   wglDeleteContext(m_hGLContext);
  23.   m_hGLContext = NULL;
  24. }
  25. CView::OnDestroy();
  26. // TODO: 在此处添加消息处理程序代码
  27. }
  28. void CosgSceneViewTestView::OnPaint()
  29. {
  30. CPaintDC dc(this); // device context for painting
  31. // TODO: 在此处添加消息处理程序代码
  32. // 不为绘图消息调用 CView::OnPaint()
  33. DrawGroundTexture();
  34. DrawScene();
  35. //SwapBuffers(dc.m_ps.hdc);
  36. }

  37. BOOL CosgSceneViewTestView::OnEraseBkgnd(CDC* pDC)
  38. {
  39. // TODO: 在此添加消息处理程序代码和/或调用默认值
  40. //return CView::OnEraseBkgnd(pDC);
  41. return TRUE;
  42. }
  43. void CosgSceneViewTestView::OnSize(UINT nType, int cx, int cy)
  44. {
  45. CView::OnSize(nType, cx, cy);
  46. CSize size(cx,cy);
  47. double aspect;
  48. aspect = (cy == 0) ? (double)size.cx : (double)size.cx/(double)size.cy;
  49. glViewport(0, 0, (GLsizei) cx, (GLsizei) cy);
  50. glMatrixMode(GL_PROJECTION);
  51. glLoadIdentity();
  52. gluPerspective(60.0, (GLfloat) cx/(GLfloat) cy, 1.0f, 500.0f);
  53. glMatrixMode(GL_MODELVIEW);
  54. glLoadIdentity();
  55. m_selfCamera->setLook();
  56. // TODO: 在此处添加消息处理程序代码
  57. }
  58. void CosgSceneViewTestView::OnInitialUpdate()
  59. {
  60. CView::OnInitialUpdate();
  61. }
  62. void CosgSceneViewTestView::InitViewPort()
  63. {
  64. CRect rect;
  65. GetClientRect(rect);
  66. if ((rect.Width() == 0) || (rect.Height() == 0))
  67. {
  68.   return;
  69. }
  70. glMatrixMode(GL_PROJECTION);
  71. glLoadIdentity();
  72. //gluPerspective(90.0,rect.Width()/rect.Height(),1.0,10000000000);
  73. gluPerspective(50.0f,1.4f,1.0f,10000.0f);
  74. glViewport(0,0,rect.Width(),rect.Height());
  75. glMatrixMode(GL_MODELVIEW);
  76. glLoadIdentity();

  77. //Lights,Meterial Properties
  78. GLfloat ambientProperties[]  = {0.5f, 0.5f, 0.5f, 1.0f};
  79. GLfloat diffuseProperties[]  = {1.0f, 1.0f, 1.0f, 1.0f};
  80. GLfloat positionProperties[] = {0.0f, 0.0f, 2.0f, 1.0f};
  81. GLfloat specularProperties[] = {1.0f, 0.0f, 0.0f, 1.0f};
  82. glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties);
  83. glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties);
  84. glLightfv(GL_LIGHT0,GL_SPECULAR,specularProperties);
  85. glLightfv( GL_LIGHT0, GL_POSITION, positionProperties);
  86. //Default: lighting
  87. glEnable(GL_LIGHT0);
  88. //  //Modelate: texture lighting
  89. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  90.   glEnable(GL_TEXTURE_2D);
  91.   glShadeModel(GL_SMOOTH);
  92.   glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuseProperties);
  93. glEnable(GL_DEPTH_TEST);

  94. glDrawBuffer(GL_BACK);
  95. }
  96. void CosgSceneViewTestView::ChangeScene()
  97. {
  98. m_selfCamera->setLook();
  99. }


  100. void CosgSceneViewTestView::OnLButtonDown(UINT nFlags, CPoint point)
  101. {
  102. // TODO: 在此添加消息处理程序代码和/或调用默认值
  103. IsLeftButtonDown = true;
  104. SetCapture();
  105. m_lptorigin = m_lptold = point;
  106. CView::OnLButtonDown(nFlags, point);
  107. }
  108. void CosgSceneViewTestView::OnRButtonDown(UINT nFlags, CPoint point)
  109. {
  110. // TODO: 在此添加消息处理程序代码和/或调用默认值
  111. IsRightButtonDown = true;
  112. SetCapture();
  113. m_rptorigin = m_rptold = point;
  114. CView::OnRButtonDown(nFlags, point);
  115. }

  116. void CosgSceneViewTestView::ClearUserScreen()
  117. {
  118. glLoadIdentity();
  119. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  120. glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  121. }
  122. void CosgSceneViewTestView::OnReadconfigfile()
  123. {
  124. // TODO: 在此添加命令处理程序代码
  125. CFileDialog fileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("配置文件(*.txt)|*.txt||"),NULL);
  126. if (fileDlg.DoModal() == IDOK)
  127. {
  128.   char file[100];
  129.   /*strcpy(file,(char*)fileDlg.GetFileName().GetBuffer());*/
  130.   strcpy(file,(char*)(LPCTSTR(fileDlg.GetFileName())));
  131.   m_showlist.InitFromFile(file);
  132.   AfxMessageBox(_T("ok"));
  133. }
  134. }

  135. void CosgSceneViewTestView::OnLoadscene()
  136. {

  137. }
  138. void CosgSceneViewTestView::OnMouseMove(UINT nFlags, CPoint point)
  139. {
  140. // TODO: 在此添加消息处理程序代码和/或调用默认值
  141. CRect rect;
  142. GetClientRect(rect);
  143. if (IsLeftButtonDown)
  144. {
  145.   if (m_lptold == point)
  146.   {
  147.    return;
  148.   }
  149.   m_selfCamera->setViewByMouse(m_lptold,point);
  150.   m_osgFrame->eyePoint = OpenglToOsg(-m_selfCamera->m_Position);
  151.   m_osgFrame->center = OpenglToOsg(m_selfCamera->m_View);
  152.   DrawScene();
  153. }
  154. if (IsRightButtonDown)
  155. {
  156.   if (m_rptold == point)
  157.   {
  158.    return;
  159.   }
  160.   float DifLength=sqrt(pow((float)(point.x-m_rptold.x),(float)2)+pow((float)(point.y-m_rptold.y),(float)2));
  161.   if(point.y<m_rptold.y) DifLength=-DifLength;
  162.   float DifRatio=DifLength/(sqrt(pow((float)rect.Width(),(float)2)+pow((float)rect.Height(),(float)2)))*5;
  163.    m_selfCamera->zoomCamera(1-DifRatio);
  164.   m_osgFrame->eyePoint = OpenglToOsg(-m_selfCamera->m_Position);
  165.   m_osgFrame->center = OpenglToOsg(m_selfCamera->m_View);
  166.   //TRACE("%f,%f,%f,%f %f %f",m_selfCamera->m_Position.x,m_selfCamera->m_Position.y,m_selfCamera->m_Position.z,m_osgFrame->eyePoint.x(),m_osgFrame->eyePoint.y(),m_osgFrame->eyePoint.z());
  167.    DrawScene();
  168. }

  169. if (IsMiddleButtonDown)
  170. {
  171.   if (m_mptold == point)
  172.   {
  173.    return;
  174.   }
  175.   m_selfCamera->yawCamera(20*m_selfCamera->getSpeed()*(m_mptold.x - point.x));
  176.   m_osgFrame->eyePoint = OpenglToOsg(-m_selfCamera->m_Position);
  177.   m_osgFrame->center = OpenglToOsg(m_selfCamera->m_View);
  178.   DrawScene();
  179. }

  180. if(IsLeftButtonDown) m_lptold=point;
  181. if(IsRightButtonDown) m_rptold=point;
  182. if (IsMiddleButtonDown) m_mptold = point;
  183. m_ptold=point;
  184. CView::OnMouseMove(nFlags, point);
  185. }
  186. void CosgSceneViewTestView::OnMButtonDown(UINT nFlags, CPoint point)
  187. {
  188. // TODO: 在此添加消息处理程序代码和/或调用默认值
  189. IsMiddleButtonDown = true;
  190. SetCapture();
  191. m_mptorigin = m_mptold = point;
  192. CView::OnMButtonDown(nFlags, point);
  193. }
  194. void CosgSceneViewTestView::OnOpenModel()
  195. {
  196. // TODO: 在此添加命令处理程序代码
  197. CFileDialog fileDlg(true,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, _T("All Files (*.*)|*.*||"));
  198. if (fileDlg.DoModal() == IDOK)
  199. {
  200.   CString filename = fileDlg.GetFileName();
  201.   std::string std_Name(filename);
  202.   m_osgFrame->InitSceneView(std_Name);
  203.   DrawScene();
  204. }
  205. }
  206. void CosgSceneViewTestView::OnLButtonUp(UINT nFlags, CPoint point)
  207. {
  208. // TODO: 在此添加消息处理程序代码和/或调用默认值
  209. IsLeftButtonDown = false;
  210. ReleaseCapture();
  211. CView::OnLButtonUp(nFlags, point);
  212. }
  213. void CosgSceneViewTestView::OnRButtonUp(UINT nFlags, CPoint point)
  214. {
  215. // TODO: 在此添加消息处理程序代码和/或调用默认值
  216. IsRightButtonDown = false;
  217. ReleaseCapture();
  218. CView::OnRButtonUp(nFlags, point);
  219. }
  220. void CosgSceneViewTestView::OnMButtonUp(UINT nFlags, CPoint point)
  221. {
  222. // TODO: 在此添加消息处理程序代码和/或调用默认值
  223. IsMiddleButtonDown = false;
  224. ReleaseCapture();
  225. CView::OnMButtonUp(nFlags, point);
  226. }
  227. //////////////////////////////////////////////////////////////////////////
  228. /* opengl坐标转换为osg坐标 */
  229. osg::Vec3 CosgSceneViewTestView::OpenglToOsg(Vector3 opengl)
  230. {
  231. osg::Vec3 des;
  232. float Xosg = opengl.x;
  233. float Yosg = opengl.z;
  234. float Zosg = -opengl.y;
  235. des.set(Xosg,Yosg,Zosg);
  236. return des;
  237. }
  238. //////////////////////////////////////////////////////////////////////////
  239. void CosgSceneViewTestView::DrawScene()
  240. {
  241. InitViewPort();
  242. ClearUserScreen();
  243. DrawOpenGLModel();
  244. m_osgFrame->OSG_Render_Frame();
  245. SwapBuffers(wglGetCurrentDC());
  246. }
  247. ///////////////////////////////////////////////////////////////////////////
  248. void CosgSceneViewTestView::DrawOpenGLModel()
  249. {
  250. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  251. glPushMatrix();
  252. ChangeScene();
  253. DrawGroundTexture();
  254. glPopMatrix();
  255. }
  256. //////////////////////////////////////////////////////////////////////////
  257. void CosgSceneViewTestView::DrawGroundTexture()
  258. {
  259. glColor4f(1.0f,1.0f,1.0f,1.0f);
  260. glBindTexture(GL_TEXTURE_2D,TextureArray[0]);
  261. glBegin(GL_QUADS);
  262. glNormal3f(0.0f,1.0f,0.0f);
  263. glTexCoord2f(0.0f,0.0f);glVertex3f(500.0f,-10.0f,-500.f);
  264. glTexCoord2f(1.0f,0.0f);glVertex3f(500.0f,-10.0f,500.0f);
  265. glTexCoord2f(1.0f,1.0f);glVertex3f(-500.0f,-10.0f,500.0f);
  266. glTexCoord2f(0.0f,1.0f);glVertex3f(-500.0f,-10.0f,-500.0f);
  267. glEnd();
  268. glFlush();
  269. glDisable(GL_TEXTURE_2D);
  270. }
  271. //////////////////////////////////////////////////////////////////////////
  272. /* 加载jpeg地形纹理*/
  273. void CosgSceneViewTestView::JPEG_Texture(UINT textureArray[], LPSTR strFileName, int ID)
  274. {
  275. if(!strFileName) return;
  276. tImageJPG *pBitMap = Load_JPEG(strFileName);
  277. if(pBitMap == NULL) return;
  278. glGenTextures(1,&textureArray[ID]);
  279. glBindTexture(GL_TEXTURE_2D,textureArray[ID]);
  280. gluBuild2DMipmaps(GL_TEXTURE_2D,3,pBitMap->sizeX,pBitMap->sizeY,GL_RGB,GL_UNSIGNED_BYTE,pBitMap->data);
  281. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
  282. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_NEAREST);
  283. if (pBitMap)
  284. {
  285.   if (pBitMap->data)
  286.   {
  287.    free(pBitMap->data);
  288.   }
  289.   free(pBitMap);
  290. }
  291. }
  292. tImageJPG* CosgSceneViewTestView::Load_JPEG(char *strfilename)
  293. {
  294. struct jpeg_decompress_struct cInfo;
  295. tImageJPG* pImgData = NULL;
  296. FILE *pFile;
  297. if ((pFile = fopen(strfilename,"rb")) == NULL)
  298. {
  299.   AfxMessageBox("Error loading jpg file.");
  300.   return NULL;
  301. }
  302. jpeg_error_mgr jerr;
  303. cInfo.err = jpeg_std_error(&jerr);
  304. jpeg_create_decompress(&cInfo);
  305. jpeg_stdio_src(&cInfo,pFile);
  306. pImgData = (tImageJPG*)malloc(sizeof(tImageJPG));
  307. Decompress_JPEG(&cInfo,pImgData);
  308. jpeg_destroy_decompress(&cInfo);
  309. fclose(pFile);
  310. return pImgData;
  311. }
  312. void CosgSceneViewTestView::Decompress_JPEG(jpeg_decompress_struct* cInfo, tImageJPG *pImgData)
  313. {
  314. jpeg_read_header(cInfo,TRUE);
  315. jpeg_start_decompress(cInfo);
  316. pImgData->rowSpan = cInfo->image_width * cInfo->num_components;
  317. pImgData->sizeX = cInfo->image_width;
  318. pImgData->sizeY = cInfo->image_height;
  319. pImgData->data = new unsigned char[pImgData->rowSpan * pImgData->sizeY];
  320. unsigned char** rowPtr = new unsigned char*[pImgData->sizeY];
  321. for (int i = 0;i<pImgData->sizeY;i++)
  322. {
  323.   rowPtr[i] = &(pImgData->data[i*pImgData->rowSpan]);
  324. }
  325. int rowsRead = cInfo->output_height - 1;
  326. while (cInfo->output_scanline < cInfo->output_height)
  327. {
  328.   rowsRead -= jpeg_read_scanlines(cInfo,&rowPtr[rowsRead],cInfo->output_height - rowsRead);
  329. }
  330. delete []rowPtr;
  331. jpeg_finish_decompress(cInfo);
  332. }
复制代码

该用户从未签到

发表于 2010-5-4 08:27:29 | 显示全部楼层
我无法一下子明白您做的所有事情,只能粗略地看一看您的实现过程:大体上这样使用SceneView是可以的,但是一定要注意OpenGL状态的切换,尤其是您的InitViewPort()和OnSize()等函数,其中所涉及的OpenGL调用和OSG的调用是否会有冲突的地方?这也许需要您非常熟悉SceneView的执行过程,并且通过适当的调试手段,例如gDEBugger,GLIntercept等来进行检查和判断

该用户从未签到

 楼主| 发表于 2010-5-4 18:47:52 | 显示全部楼层
4# array

谢谢array。。。
问题我已经解决了,我计算了一下,gluLookAt和osg::matrix:ookAt的变换矩阵其实是一样的,只是存储的方式不一样,是一种转置关系。在程序中,opengl坐标转换到osg坐标处理出现错误,导致两者不同步。
正确的转换应该是这样的:
Xosg = -Opengl.x;
Yosg = Opengl.z;
Zosg = Opengl.y;

该用户从未签到

发表于 2010-5-5 09:47:07 | 显示全部楼层
恭喜楼主,这个要了解下

该用户从未签到

 楼主| 发表于 2010-5-5 21:03:51 | 显示全部楼层
6# tianxiao888
另外,需要把文中的-m_selfCamera->m_position的负号去掉,这样就正确了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表