查看: 3441|回复: 4

在GLUT的显示回调中修改VBO数据,但没有刷新到屏幕,[已解]

[复制链接]

该用户从未签到

发表于 2011-6-20 17:43:26 | 显示全部楼层 |阅读模式
本帖最后由 CR苏杭 于 2011-6-21 10:15 编辑

应该说是没有立即刷新到屏幕。如果把屏幕拖来拖去,松开鼠标以后就会看到已经刷新了。
(代码有部分很乱,忍一忍。XD)
求解。
解决了,在idle回调中glutPostRedisplay();

顺便传一本GLUT的使用手册。
传不上来。-_-b
链接在此:http://www.opengl.org/documentation/specs/glut/glut-3.spec.pdf

  1. // OPENGL头文件
  2. #include <gl/glew.h>
  3. #include <GL/glut.h>
  4. #include <GL/glu.h>
  5. #include <GL/gl.h>

  6. #include <string>
  7. #include <sstream>
  8. #include <assert.h>
  9. #define _USE_MATH_DEFINES
  10. #include <math.h>

  11. //////////////////////////////////////////////////////////////////////////
  12. // 关于GLUT的部分
  13. //////////////////////////////////////////////////////////////////////////


  14. // 窗口参数
  15. const int gWinWidth = 1024;
  16. const int gWinHeight = 768;
  17. const char* gWinTitile = "glut beginning!";
  18. float eye_z;  // 视点和原点位置的z差

  19. // “退出”菜单ID
  20. static const int QUIT_VALUE = 99;
  21. // 显示列表ID
  22. GLuint listID;
  23. // 缓存对象 modify by cr 2011/6/20
  24. GLuint buffers[2];// 顶点,颜色

  25. // insert by cr 2011/06/20
  26. bool useDisplayList = true;
  27. bool useVertexArrays = false;
  28. bool useBufferObjects = false;

  29. GLfloat* vertices = NULL;
  30. GLuint   verticesNum;

  31. // 重要回调1:显示回调,GLUT调用它完成重绘。
  32. static void display(void)
  33. {
  34.         glClear(GL_COLOR_BUFFER_BIT);

  35.         // 将模型矩阵往后退eye_z,即向屏幕里移动eye_z
  36.         glLoadIdentity();
  37.         glTranslatef(0.f,0.f,-eye_z);

  38.         glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
  39.         GLfloat* ptr = (GLfloat*) glMapBuffer(GL_ARRAY_BUFFER,GL_READ_WRITE);
  40.         for (unsigned int i = 0; i< verticesNum; i+=3)
  41.         {
  42.                 ptr[i] += 10.f;
  43.         }
  44.         glUnmapBuffer(GL_ARRAY_BUFFER);


  45.         if (useBufferObjects)
  46.         {
  47.                 glDrawArrays(GL_TRIANGLES, 0, 3);
  48.         }
  49.         else
  50.         {
  51.                 if (useDisplayList)
  52.                         // 绘制显示列表的内容
  53.                         glCallList(listID);

  54.         }

  55.         // 交换缓存,即将后缓存中的内容刷新到帧缓存,
  56.         // 帧缓存中的内容会被显示设备即刻显示出来。
  57.         glutSwapBuffers();

  58.         assert(glGetError() == GL_NO_ERROR);
  59. }




  60. // 重要回调2:重塑回调。
  61. // 在窗口size发成变化时,GLUT会调用它。类同c#中窗体的sizechanged()
  62. static void reshape(int w, int h)
  63. {
  64.         // 更新视口
  65.         glViewport(0,0,w,h);

  66.         // 更新投影矩阵和屏幕纵横比
  67.         glMatrixMode(GL_PROJECTION);
  68.         glLoadIdentity();
  69.         eye_z = (h/2) / atanf(M_PI*50./180.);
  70.         gluPerspective(50., (double)w/(double)h, 1., 10000.);

  71.         // 矩阵状态置为模型变换
  72.         glMatrixMode(GL_MODELVIEW);

  73.         assert(glGetError() == GL_NO_ERROR);
  74. }

  75. // 重要回调3:GLUT菜单回调。类同c#中menuitem::clicked()
  76. static void mainMenuCB(int value)
  77. {
  78.         if (value == QUIT_VALUE)
  79.                 exit(0);
  80. }

  81. // 一些重要的初始化
  82. static void initGLUT(void)
  83. {
  84.         // 关闭抖动。
  85.         // 抖动是色位不够的时候用较少的颜色来模拟缺少的颜色的一种方法
  86.         glDisable(GL_DITHER);

  87.         // 获得GL版本
  88.         // getGetString()
  89.         std::string ver((const char*) glGetString(GL_VERSION));
  90.         assert(!ver.empty());
  91.         std::istringstream verStream(ver);

  92.         // 分解版本号,major.minor.xx, 最后的xx没有取出
  93.         int major, minor ;
  94.         char dummySep;
  95.         verStream >> major >> dummySep >> minor;

  96.         // 即OpenGL1.1以上才支持定点数组,但原先的判断方法貌似有问题
  97.         //const bool useVertexArrays = ( (major >= 1) && (minor >= 1) );        //原先的 delete by cr 2011/6/20
  98.         //const bool useVertexArrays =  ((major*10+minor) >= 11);                        // modify by cr 2011/6/20
  99.         useVertexArrays  =  ((major*10+minor) >= 11);
  100.         // 1.5以上支持缓存对象
  101.         //const bool useBufferObjects =  ((major*10+minor) >= 15);                        // modify by cr 2011/6/20
  102.         useBufferObjects =  ((major*10+minor) >= 15);


  103.                 verticesNum = 3*3;
  104.                 vertices = (GLfloat*)malloc( sizeof(GLfloat) * verticesNum );
  105.                 GLfloat* tmpptr = vertices;
  106.                 *tmpptr = -100.f; tmpptr ++;
  107.                 *tmpptr = -100.f; tmpptr ++;
  108.                 *tmpptr = 0.f; tmpptr ++;
  109.                 *tmpptr = 100.f; tmpptr ++;
  110.                 *tmpptr = -100.f; tmpptr ++;
  111.                 *tmpptr = 0.f; tmpptr ++;
  112.                 *tmpptr = 0.f; tmpptr ++;
  113.                 *tmpptr = 100.f; tmpptr ++;
  114.                 *tmpptr = 0.f;

  115.                 GLfloat data[] = {
  116.                         -100.f, -100.f, 0.f,
  117.                         100.f, -100.f, 0.f,
  118.                         0.f, 100.f, 0.f};

  119.         GLfloat color[] = {
  120.                 1.f, 1.f, 0.f, 1.f,
  121.                 1.f, 0.f, 0.f, 1.f,
  122.                 0.f, 1.f, 0.f, 1.f};

  123.         if (useBufferObjects)
  124.         {
  125.                 //// 从缓存池获取2个未用的id给vboid
  126.                 glGenBuffers(2, buffers);

  127.                 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);  
  128.                 glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(GLfloat) * 3, vertices, GL_DYNAMIC_DRAW);

  129.                 //glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);               
  130.                 //glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(GLfloat) * 4, color, GL_DYNAMIC_DRAW);

  131.                 glEnableClientState(GL_VERTEX_ARRAY);
  132.                 glVertexPointer(3, GL_FLOAT, 0, 0);
  133.                 //glVertexPointer(3, GL_FLOAT, 0, 0);

  134.                 //glDeleteBuffers(n, &buffers);

  135.         }
  136.         // 使用顶点数组
  137.         else
  138.         {               
  139.                 if (useVertexArrays)
  140.                 {
  141.                         glEnableClientState(GL_VERTEX_ARRAY);
  142.                         glVertexPointer(3, GL_FLOAT, 0, data);
  143.                         glEnableClientState(GL_COLOR_ARRAY);
  144.                         glColorPointer(4, GL_FLOAT, 0, color);
  145.                         //glNormalPointer()
  146.                         //glTexCoordPointer()
  147.                 }


  148.                 if (useDisplayList)
  149.                 {
  150.                         // 创建显示列表ID
  151.                         listID = glGenLists(1);
  152.                         // 编译显示列表
  153.                         //(即从这里开始到glEndList为止的gl代码都会被编译成一系列指令直接存储在GPU的显存内)
  154.                         glNewList(listID, GL_COMPILE);
  155.                 }

  156.                 if (useVertexArrays)
  157.                 {
  158.                         glDrawArrays(GL_TRIANGLES, 0, 3);
  159.                 }
  160.                 else
  161.                 {
  162.                         glBegin( GL_TRIANGLES );
  163.                         glColor4fv(&color[0]);
  164.                         glVertex3fv( &data[0] );
  165.                         glColor4fv(&color[4]);
  166.                         glVertex3fv( &data[3] );
  167.                         glColor4fv(&color[8]);
  168.                         glVertex3fv( &data[6] );
  169.                         glEnd();
  170.                 }

  171.                 if (useDisplayList)
  172.                 {
  173.                         // 显示列表结束
  174.                         glEndList();
  175.                 }

  176.         }


  177.         assert(glGetError() == GL_NO_ERROR);

  178.         // 绑定显示回调和重塑回调
  179.         // Tips: F12转到定义查看更多GLUT回调
  180.         glutDisplayFunc(display);
  181.         glutReshapeFunc(reshape);

  182.         // 创建右键菜单,参数是回调函数
  183.         int mainMenu = glutCreateMenu(mainMenuCB);
  184.         glutAddMenuEntry("退出", QUIT_VALUE);
  185.         glutAttachMenu(GLUT_RIGHT_BUTTON);

  186. }


  187. //////////////////////////////////////////////////////////////////////////
  188. // 程序入口
  189. //////////////////////////////////////////////////////////////////////////
  190. int main(int argc, char** argv)
  191. {

  192.         // 1.glutInit
  193.         glutInit(&argc, argv);

  194.         // 2.创建GLUT窗口
  195.         glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
  196.         glutInitWindowSize(gWinWidth,gWinHeight);
  197.         glutCreateWindow(gWinTitile);

  198.         glewInit();

  199.         // 3.一系列对glut的初始化工作
  200.         initGLUT();

  201.         // 4.开始仿真循环
  202.         glutMainLoop();

  203.         return 0;

  204. }
复制代码

该用户从未签到

发表于 2011-6-21 08:32:13 | 显示全部楼层
你的display()函数里似乎不是按照bind->enable->set_pointer->draw_arrays->disable的顺序来进行的?我猜想这里可能存在一些问题,NEHE的教程也许对您会很有帮助:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45

该用户从未签到

 楼主| 发表于 2011-6-21 09:06:00 | 显示全部楼层
回复 2# array


bind,enable,pointer都是在GLUT里面顺序做的,display中只是draw了。从头到尾就没有disable。有disable的必要吗?

martz那本书上的第一个例程中用了VA,但是也是一直没有disable,我在那个基础上加上了vbo,因此也就木有disable。非要disable咩?

该用户从未签到

 楼主| 发表于 2011-6-21 09:14:40 | 显示全部楼层
回复 2# array


我把代码做了一些改动,改成在display中修改数据并使用立即模式绘制, 如下。也是一样的问题。看起来像是windows没有通知gl应该重绘,当有遮挡窗体在移动时,可以看到会刷新数据。
  1. // OPENGL头文件
  2. #include <gl/glew.h>
  3. #include <GL/glut.h>
  4. #include <GL/glu.h>
  5. #include <GL/gl.h>

  6. #include <string>
  7. #include <sstream>
  8. #include <assert.h>
  9. #define _USE_MATH_DEFINES
  10. #include <math.h>

  11. #include <iostream>

  12. //////////////////////////////////////////////////////////////////////////
  13. // 关于GLUT的部分
  14. //////////////////////////////////////////////////////////////////////////


  15. // 窗口参数
  16. const int gWinWidth = 1024;
  17. const int gWinHeight = 768;
  18. const char* gWinTitile = "glut beginning!";
  19. float eye_z;  // 视点和原点位置的z差

  20. // “退出”菜单ID
  21. static const int QUIT_VALUE = 99;
  22. // 显示列表ID
  23. GLuint listID;
  24. // 缓存对象 modify by cr 2011/6/20
  25. GLuint buffers[2];// 顶点,颜色

  26. // insert by cr 2011/06/20
  27. bool useDisplayList = false;
  28. bool useVertexArrays = false;
  29. bool useBufferObjects = false;

  30. GLfloat* vertices = NULL;
  31. GLuint   verticesNum;

  32. unsigned int num=0;


  33. GLfloat data[] = {
  34.         -100.f, -100.f, 0.f,
  35.         100.f, -100.f, 0.f,
  36.         0.f, 100.f, 0.f};

  37.         GLfloat color[] = {
  38.                 1.f, 1.f, 0.f, 1.f,
  39.                 1.f, 0.f, 0.f, 1.f,
  40.                 0.f, 1.f, 0.f, 1.f};



  41. static void idle(void)
  42. {
  43. }

  44. // 重要回调1:显示回调,GLUT调用它完成重绘。
  45. static void display(void)
  46. {
  47.         num ++;
  48.         std::cout<< " "<< num <<";" ;
  49.         glClear(GL_COLOR_BUFFER_BIT);

  50.         // 将模型矩阵往后退eye_z,即向屏幕里移动eye_z
  51.         glLoadIdentity();
  52.         glTranslatef(0.f,0.f,-eye_z);


  53.         //glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
  54.         //GLfloat* ptr = (GLfloat*) glMapBuffer(GL_ARRAY_BUFFER,GL_READ_WRITE);
  55.         //for (unsigned int i = 0; i< verticesNum; i+=3)
  56.         //{
  57.         //        ptr[i] += 1.f;
  58.         //}
  59.         //glUnmapBuffer(GL_ARRAY_BUFFER);

  60.         for (unsigned int i = 0; i< verticesNum; i+=3)
  61.         {
  62.                 data[i] += 5.f;
  63.         }

  64.         if (useBufferObjects)
  65.         {
  66.                 glDrawArrays(GL_TRIANGLES, 0, 3);
  67.         }
  68.         else
  69.         {
  70.                 if (useDisplayList)
  71.                         // 绘制显示列表的内容
  72.                         glCallList(listID);
  73.                 else
  74.                 {
  75.                         glBegin( GL_TRIANGLES );
  76.                         glColor4fv(&color[0]);
  77.                         glVertex3fv( &data[0] );
  78.                         glColor4fv(&color[4]);
  79.                         glVertex3fv( &data[3] );
  80.                         glColor4fv(&color[8]);
  81.                         glVertex3fv( &data[6] );
  82.                         glEnd();

  83.                 }

  84.         }

  85.         // 交换缓存,即将后缓存中的内容刷新到帧缓存,
  86.         // 帧缓存中的内容会被显示设备即刻显示出来。
  87.         glutSwapBuffers();

  88.         assert(glGetError() == GL_NO_ERROR);
  89. }




  90. // 重要回调2:重塑回调。
  91. // 在窗口size发成变化时,GLUT会调用它。类同c#中窗体的sizechanged()
  92. static void reshape(int w, int h)
  93. {
  94.         // 更新视口
  95.         glViewport(0,0,w,h);

  96.         // 更新投影矩阵和屏幕纵横比
  97.         glMatrixMode(GL_PROJECTION);
  98.         glLoadIdentity();
  99.         eye_z = (h/2) / atanf(M_PI*50./180.);
  100.         gluPerspective(50., (double)w/(double)h, 1., 10000.);

  101.         // 矩阵状态置为模型变换
  102.         glMatrixMode(GL_MODELVIEW);

  103.         assert(glGetError() == GL_NO_ERROR);
  104. }

  105. // 重要回调3:GLUT菜单回调。类同c#中menuitem::clicked()
  106. static void mainMenuCB(int value)
  107. {
  108.         if (value == QUIT_VALUE)
  109.                 exit(0);
  110. }

  111. // 一些重要的初始化
  112. static void initGLUT(void)
  113. {
  114.         // 关闭抖动。
  115.         // 抖动是色位不够的时候用较少的颜色来模拟缺少的颜色的一种方法
  116.         glDisable(GL_DITHER);

  117.         // 获得GL版本
  118.         // getGetString()
  119.         std::string ver((const char*) glGetString(GL_VERSION));
  120.         assert(!ver.empty());
  121.         std::istringstream verStream(ver);

  122.         // 分解版本号,major.minor.xx, 最后的xx没有取出
  123.         int major, minor ;
  124.         char dummySep;
  125.         verStream >> major >> dummySep >> minor;

  126.         // 即OpenGL1.1以上才支持定点数组,但原先的判断方法貌似有问题
  127.         //const bool useVertexArrays = ( (major >= 1) && (minor >= 1) );        //原先的 delete by cr 2011/6/20
  128.         //const bool useVertexArrays =  ((major*10+minor) >= 11);                        // modify by cr 2011/6/20
  129.         useVertexArrays  =  ((major*10+minor) >= 11);
  130.         // 1.5以上支持缓存对象
  131.         //const bool useBufferObjects =  ((major*10+minor) >= 15);                        // modify by cr 2011/6/20
  132.         //useBufferObjects =  ((major*10+minor) >= 15);

  133.         verticesNum = 3*3;
  134.         vertices = (GLfloat*)malloc( sizeof(GLfloat) * verticesNum );
  135.         GLfloat* tmpptr = vertices;
  136.         *tmpptr = -100.f; tmpptr ++;
  137.         *tmpptr = -100.f; tmpptr ++;
  138.         *tmpptr = 0.f; tmpptr ++;
  139.         *tmpptr = 100.f; tmpptr ++;
  140.         *tmpptr = -100.f; tmpptr ++;
  141.         *tmpptr = 0.f; tmpptr ++;
  142.         *tmpptr = 0.f; tmpptr ++;
  143.         *tmpptr = 100.f; tmpptr ++;
  144.         *tmpptr = 0.f;

  145.         if (useBufferObjects)
  146.         {
  147.                 //// 从缓存池获取2个未用的id给vboid
  148.                 glGenBuffers(2, buffers);

  149.                 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);  
  150.                 glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(GLfloat) * 3, vertices, GL_DYNAMIC_DRAW);

  151.                 //glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);               
  152.                 //glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(GLfloat) * 4, color, GL_DYNAMIC_DRAW);

  153.                 glEnableClientState(GL_VERTEX_ARRAY);
  154.                 glVertexPointer(3, GL_FLOAT, 0, 0);
  155.                 //glVertexPointer(3, GL_FLOAT, 0, 0);

  156.                 //glDeleteBuffers(n, &buffers);

  157.         }
  158.         // 使用顶点数组
  159.         else
  160.         {               
  161.                 if (useVertexArrays)
  162.                 {
  163.                         glEnableClientState(GL_VERTEX_ARRAY);
  164.                         glVertexPointer(3, GL_FLOAT, 0, data);
  165.                         glEnableClientState(GL_COLOR_ARRAY);
  166.                         glColorPointer(4, GL_FLOAT, 0, color);
  167.                         //glNormalPointer()
  168.                         //glTexCoordPointer()
  169.                 }


  170.                 if (useDisplayList)
  171.                 {
  172.                         // 创建显示列表ID
  173.                         listID = glGenLists(1);
  174.                         // 编译显示列表
  175.                         //(即从这里开始到glEndList为止的gl代码都会被编译成一系列指令直接存储在GPU的显存内)
  176.                         glNewList(listID, GL_COMPILE);
  177.                 }

  178.                 if (useVertexArrays)
  179.                 {
  180.                         glDrawArrays(GL_TRIANGLES, 0, 3);
  181.                 }
  182.                 else
  183.                 {
  184.                         glBegin( GL_TRIANGLES );
  185.                         glColor4fv(&color[0]);
  186.                         glVertex3fv( &data[0] );
  187.                         glColor4fv(&color[4]);
  188.                         glVertex3fv( &data[3] );
  189.                         glColor4fv(&color[8]);
  190.                         glVertex3fv( &data[6] );
  191.                         glEnd();
  192.                 }

  193.                 if (useDisplayList)
  194.                 {
  195.                         // 显示列表结束
  196.                         glEndList();
  197.                 }

  198.         }


  199.         assert(glGetError() == GL_NO_ERROR);

  200.         // 绑定显示回调和重塑回调
  201.         // Tips: F12转到定义查看更多GLUT回调
  202.         glutIdleFunc(idle);
  203.         glutDisplayFunc(display);
  204.         glutReshapeFunc(reshape);

  205.         // 创建右键菜单,参数是回调函数
  206.         int mainMenu = glutCreateMenu(mainMenuCB);
  207.         glutAddMenuEntry("退出", QUIT_VALUE);
  208.         glutAttachMenu(GLUT_RIGHT_BUTTON);

  209. }


  210. //////////////////////////////////////////////////////////////////////////
  211. // 程序入口
  212. //////////////////////////////////////////////////////////////////////////
  213. int main(int argc, char** argv)
  214. {

  215.         // 1.glutInit
  216.         glutInit(&argc, argv);

  217.         // 2.创建GLUT窗口
  218.         glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
  219.         glutInitWindowSize(gWinWidth,gWinHeight);
  220.         glutCreateWindow(gWinTitile);

  221.         // glewInit()必须在rc创建以后
  222.         glewInit();

  223.         // 3.一系列对glut的初始化工作
  224.         initGLUT();

  225.         // 4.开始仿真循环
  226.         glutMainLoop();

  227.         return 0;

  228. }
复制代码

该用户从未签到

发表于 2011-6-21 16:43:05 | 显示全部楼层
正想说glutPostRedisplay()的问题……
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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