OPENGL画图的问题

jiangshx 2004-04-15 02:17:09
先画了一个背景,然后随着鼠标移动,在鼠标当前位置画坐标线(一条横线,一条纵线),我每次都得重画背景,再画线,浪费很多时间,用什么方法不用画背景,而直接画线,是用模板缓存(GL_STENCIL_BUFFER_BIT)吗,我不会用,哪位老大提点一下小弟。
...全文
169 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiangshx 2004-04-22
  • 打赏
  • 举报
回复
谢谢!
wwwdfq1977 2004-04-20
  • 打赏
  • 举报
回复
顺便说一句:d3d中都是强制采用顶点缓冲,这也是d3d比opengl快的原因之一
wwwdfq1977 2004-04-20
  • 打赏
  • 举报
回复
写错了
'可以向顶点传送很大的数据"应改为"可以向显卡传送很大的数据"
wwwdfq1977 2004-04-20
  • 打赏
  • 举报
回复
好复杂!!,我看的眼睛都花了,没看明白你画了什么,不过,我可以向你如下建议:
1.尽可能避免每一帧都计算,好像你的背景不要每一帧都计算吧,把背景计算好后,存入到一个数组中去,伪代码如下:
if(isComputerBackGround)//只是在需要刷新背景时才计算
{
computeBackGround();//计算好背景,存入数组
isComputerBackGround=false;
}
DrawBackGround();//将数组中的东西画出
2.最好一次尽可能传递尽可能多的数据给显卡,尽可能少的传递数据
例如:glVertex2d传递的是双精度型,它的数据传输量比glvertex2f和glVertexw2i多出一倍
glVertex2xv的效率比glVertex2x高,而使用顶点数组函数glVertexPointer函数一次可以向顶点传送很大的数据,效率远远高出上面的函数,他还可以传递unsigned short型数据,这样数据传送量还可以减少了一倍,关于顶点数组的使用可以看opengl超级宝典或者其他书籍,也可到网上寻找
如果可能,还可采用顶点缓冲(vertex buffer object)将顶点数据缓存在显卡,但是旧的显卡可能不支持,具体使用方法去看www.gameres.com上面的一篇文章
所以你可以先算好顶点数据,存入到一个unsigned short型数组,并用glVertexPointer发送之,而不是采用如下代码
glBegin(GL_LINES);
if(i==0)continue;
if(i%2==0)glVertex2d(42,i);
else glVertex2d(46,i);
glVertex2d(50,i);
glEnd();
这种方法效率极低(不仅每次发送的数据少,而且总的数据发送量还多)
3诸如glEnable(GL_SCISSOR_TEST),glPushAttrib(GL_CURRENT_BIT); 之类能不要就不要(我不知道你要裁剪什么)

jiangshx 2004-04-19
  • 打赏
  • 举报
回复
我也是刚学,所以不知道是不是分不同的表面,还请明白人救命!!
jiangshx 2004-04-19
  • 打赏
  • 举报
回复
我用BCB5.0做的 ,小弟初学,请各位指正
long i,j,x1,y1,x2,y2;
int *listindex;
//分三个区画坐标系,曲线区,横坐标区,纵坐标区
glEnable(GL_SCISSOR_TEST); //*********************曲线区
glScissor(50,25,Pan_Map->ClientRect.Right,(Pan_Map->ClientRect.Bottom-25)*20/22+1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(0,540,0,220); //横坐标0~540,纵坐标0~220
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(50,25,Pan_Map->ClientRect.Right-50,Pan_Map->ClientRect.Bottom-25);
glPushMatrix();
glPushAttrib(GL_CURRENT_BIT);

glColor4ub(0,75,0,128);
glBegin(GL_LINES);
for(i=0;i<201;i+=10){ //20条横线
glVertex2d(0,i);
glVertex2d(540,i);
}
for(i=0;i<541;i+=10){ //54条纵线
glVertex2d(i,0);
glVertex2d(i,200);
}
glEnd();
glEnable (GL_BLEND); //使透明
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA );
glShadeModel(GL_FLAT);
if(fCurve){ //开始画曲线
listindex=new int[curvenum/3];
if(listSelect!=-1){ //最后画选中的曲线
listindex[curvenum/3-1]=listSelect;
for(i=0,j=0;j<curvenum/3;j++){
if(j==listSelect)continue;
listindex[i]=j;i++;
}
}
else{
for(i=0;i<curvenum/3;i++){
listindex[i]=i;
}
}
int icp,icm,icu;
icp=FUNC(currpeak[pType],currs[pType][2]); //峰值
icm=FUNC(currmin[pType],currs[pType][1]); //最小值
icu=FUNC(currunit[pType],currs[pType][0]); //单元值
for(j=0;j<curvenum/3;j++){
if(listindex[j]==listSelect)glLineWidth(2); //选中的曲线宽度为2
if(list[listindex[j]][8]==0){glLineWidth(1);continue;}
SetLineColor(list[listindex[j]][1]); //设置曲线的颜色
glBegin(GL_LINE_STRIP);
for(i=0;i<540;i++){ //540条竖线
if((map_view[listindex[j]][i][0]-(-1))!=0){ //如果有数据画该线
if((map_view[listindex[j]][i][0]-(-100000))==0){
glEnd();
glColor4ub(255,255,255,128);
glBegin(GL_LINE_STRIP);
glVertex2d(i,-1);
glVertex2d(i,200);
break;
}
else{
if((map_view[listindex[j]][i][0]>icp)||(map_view[listindex[j]][i][1]>icp)
||(map_view[listindex[j]][i][2]>icp)||(map_view[listindex[j]][i][3]>icp)){
glColor4ub(255,255,255,128);
glVertex2d(i+1,201);
}
else{
SetLineColor(list[listindex[j]][1]);
glVertex2d(i+1,(map_view[listindex[j]][i][0]-icm)*200/(icu*20));
}
if(map_view[listindex[j]][i][1]!=-1){
glVertex2d(i+1,(map_view[listindex[j]][i][1]-icm)*200/(icu*20));
glVertex2d(i+1,(map_view[listindex[j]][i][2]-icm)*200/(icu*20));
glVertex2d(i+1,(map_view[listindex[j]][i][3]-icm)*200/(icu*20));
}
}
}
}
glEnd();
glLineWidth(1); //默认线宽
}
delete [] listindex;
}
glDisable(GL_BLEND); //取消透明
if(tbarCur->Down&&fMouseOn){ //当前鼠标位置画坐标线 横线和纵线
glColor4ub(0,255,255,128);
glLineStipple(1,0xaaaa); //画虚线
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINES);
x1=(mousepos.x-50)*540/(Pan_Map->ClientRect.Right-50)+1; //算出当前鼠标位置
y1=(Pan_Map->ClientRect.Bottom-mousepos.y-25)*200/((Pan_Map->ClientRect.Bottom-25)*20/22);
glVertex2d(0,y1);
glVertex2d(540,y1);
glVertex2d(x1,0);
glVertex2d(x1,220);
glEnd();
glDisable(GL_LINE_STIPPLE);
}
if(tbarArea->Down){ //画选中区域方框
if(fMouseLeftDown){
glColor4ub(255,0,255,128);
glLineStipple(1,0xaaaa); //画虚线
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINE_LOOP);
x1=(poStart.x-50)*540/(Pan_Map->ClientRect.Right-50)+1; //两个顶点位置
y1=(Pan_Map->ClientRect.Bottom-poStart.y-25)*200/((Pan_Map->ClientRect.Bottom-25)*20/22);
x2=(poEnd.x-50)*540/(Pan_Map->ClientRect.Right-50)+1;
y2=(Pan_Map->ClientRect.Bottom-poEnd.y-25)*200/((Pan_Map->ClientRect.Bottom-25)*20/22);
glVertex2d(x1,y1);
glVertex2d(x1,y2);
glVertex2d(x2,y2);
glVertex2d(x2,y1);
glEnd();
glDisable(GL_LINE_STIPPLE);
}
}
glPopAttrib();
glPopMatrix();

glEnable(GL_SCISSOR_TEST); //*********************横轴区
glScissor(0,0,Pan_Map->ClientRect.Right,25);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(0,54,25,0); //横坐标0~54,纵坐标25~0
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(50,0,Pan_Map->ClientRect.Right-50,25);

glPushMatrix();
glPushAttrib(GL_CURRENT_BIT);
glLoadIdentity();
glColor4ub(0,255,0,128);
glBegin(GL_LINES);
for(i=0;i<54;i++){
if(i==0)continue;
glVertex2d(i,0);
if(i%5==0){
if(i%10==0)glVertex2d(i,8);
else glVertex2d(i,6);
}
else glVertex2d(i,3);
}
glVertex2d(0,0.1);
glVertex2d(540,0.1);
glEnd();
glEnable(GL_SCISSOR_TEST); //*********************纵轴区
glScissor(0,25,50,Pan_Map->ClientRect.Bottom-25);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(0,50,0,22); //横坐标0~50,纵坐标0~22
glMatrixMode(GL_MODELVIEW);

glViewport(0,25,50,Pan_Map->ClientRect.Bottom-25);

glPushMatrix();
glPushAttrib(GL_CURRENT_BIT);
glLoadIdentity();

for(i=0;i<21;i++){
glColor4ub(0,255,0,128);
glBegin(GL_LINES);
if(i==0)continue;
if(i%2==0)glVertex2d(42,i);
else glVertex2d(46,i);
glVertex2d(50,i);
glEnd();
}
glBegin(GL_LINES);
glVertex2d(49.9,0);
glVertex2d(49.9,220);
glEnd();
glPopAttrib();
glPopMatrix();

SwapBuffers(hDC);
wwwdfq1977 2004-04-19
  • 打赏
  • 举报
回复
肯定是每次都要画背景的,即使画背景也应该不会很慢,关键看你怎么画的,你不妨把你画的代码贴出来,否则没有人知道你出了什么问题
模板缓冲的作用是禁止写颜色缓冲,用于制造一些特殊的效果,对你的这个问题应该没用
jiangshx 2004-04-17
  • 打赏
  • 举报
回复
wlpwind 2004-04-17
  • 打赏
  • 举报
回复
不熟,难道opengl不分不同的表面么?
如果分得话很容易,背景和鼠标线分别单独做一个面就可以了
heavenchang 2004-04-17
  • 打赏
  • 举报
回复
不好意思,我也不知道

但我以前用别我东西加了十几张图
也是动态贴图片

我也碰到了运行很慢的情况
后来我在程序一开始就加载了这些图片,这样就快多了


看样子,也帮不了你什么了
heavenchang 2004-04-17
  • 打赏
  • 举报
回复
我想你应先载入buffer,然后再做什么
不然一定耗资源
heavenchang 2004-04-17
  • 打赏
  • 举报
回复
择了要清除的缓存及其清除值后,就可以调用glClear()来完成清除的操作了。这个清除函数为:

  void glClaear(Glbitfield mask);

  清除指定的缓存。参数mask可以是下面这些位逻辑的或,

  GL_COLOR_BUFFER_BIT
  GL_DEPTH_BUFFER_BIT
  GL_STENCIL_BUFFER_BIT
  GL_ACCUM_BUFFER_BIT

  这些位逻辑确定所要清除的缓存。注意:GL_COLOR_BUFFER_BIT清除RGBA方式颜色缓存还是清除颜色表方式颜色缓存,要依赖当前系统设置的颜色方式。当清除颜色缓存后,所有启动写操作的颜色缓存都被清除
jiangshx 2004-04-16
  • 打赏
  • 举报
回复
救命的问题,请高手不吝赐教

8,301

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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