【OpenGL 100分!!!】各位好心的OpenGL高手近来帮忙!!!!纹理和显示列表问题!!!!!!

doall4u 2003-08-30 12:15:20
小D现从数据库中读出了一个方格网的128*128个点(正方形的一块),用了三个数组分别存放了点的X,Y和高程,然后在OPENGL中构造一个DEM,由于必须把方格网变成三角网(否责OPENGL无法渲染),我就把每个小方格沿对角线给切了.然后三个点一组画出若干个小三角,最后构成一个地形.现在地形可以正常显示,而且每个面的法向量也设置了,加上了光照.但是现在由于我是每20毫秒刷新一下场景,我在VC中用的OnTimer,每20毫秒做一次VIEW的刷新,好象是什么Invalidate()函数.是从书上学的.所以总要去重画128*128个点,总要每三个点计算法向量.还没有加上纹理坐标的计算就CPU利用率100%了!!!!在不加纹理的情况下,SDI窗口最大化CPU利用率100%,不最大化最多只有2%(很不明白,怎么差这么多),加了纹理以后不论什么时候都100%,可以肯定是CPU在画的时候不停的做各种OPENGL计算,因为内存一切正常.我看了书上说了用显示列表,于是我就用了,但是更槽,不加纹理的情况下怎么样都是100%,加了纹理更不用说,不知道显示列表怎么用.各位大侠有没有什么好的方法帮我解决解决,我也是才接触OpenGL和VC.
注:我的方法是:
1:我是把绘图的部分封装成DEM类,在VIEW的RenderScene()中调用DEM类的.Draw()方法来画的.不知道各位在画的物体比较多的时候是怎么做的,用不用把降水,房屋,水坝都封装成类来做呢??????
2:实现动画可不可以用别的方法,不用TIMEER,这种方法好实现,但是跟CPU利用率有直接关系,如果拉长时间间隔又要影响动画效果.
3:我伪代码是这样写的,源代码在公司
DEM类的Draw():(没敢加纹理)
for(int i=0;i<16384;i++) //128*128个点
{
if(如果不是最后一列又不是最后一行的点) //选则点来构造三角
{
glBegin(GL_TRAINGLES);//开始画三角形
//每个方格分成两个三角形
//第一个
Jisuan();//计算法向量
glNormal(*,*,*);//指定法向量
glVertex3f(x[i],y[i],z[i]); //第一个点
glVertex3f(x[i+1],y[i+1],z[i+1]);//第二个点
glVertex3f(x[i+1+行宽],y[i+1+行宽],z[i+1+行宽]);//第三个点
//第二个
Jisuan();//计算法向量
glNormal(*,*,*);//指定法向量
glVertex3f(x[i],y[i],z[i]);//第一个点
glVertex3f(x[i+1+行宽],y[i+1+行宽],z[i+1+行宽]);//第二个点
glVertex3f(x[i+行宽],y[i+行宽],z[i+行宽]);//第三个点
glEnd();
}
}//大概是这样
加上显示列表后
glNewList(1,GL_CONPILE);
for(int i=0;i<16384;i++) //128*128个点
{
if(如果不是最后一列又不是最后一行的点) //选则点来构造三角
{
glBegin(GL_TRAINGLES);//开始画三角形
//每个方格分成两个三角形
//第一个
Jisuan();//计算法向量
glNormal(*,*,*);//指定法向量
glVertex3f(x[i],y[i],z[i]);//第一个点
glVertex3f(x[i+1],y[i+1],z[i+1]);//第二个点
glVertex3f(x[i+1+行宽],y[i+1+行宽],z[i+1+行宽]);//第三个点
//第二个
Jisuan();//计算法向量
glNormal(*,*,*);//指定法向量
glVertex3f(x[i],y[i],z[i]);//第一个点
glVertex3f(x[i+1+行宽],y[i+1+行宽],z[i+1+行宽]);//第二个点
glVertex3f(x[i+行宽],y[i+行宽],z[i+行宽]);//第三个点
glEnd();
}
}
glEndList(1,GL_CONPILE);
然后在DEM类中建立另一方法DEM.Complie(),里面是上面的代码,然后.Draw()方法里面改成只有一行代码:glCallList(1);
虽然画出地形了,但利用率比以前更高了???应该怎么办?????我用显示列表的方法对吗????
大家帮帮忙!!!!怎么能把CPU利用率降下来啊>>

另:这里什么时候能有OPENGL的专栏啊?????!!!!!
...全文
96 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
look4u 2004-03-06
  • 打赏
  • 举报
回复
GZ
doall4u 2003-09-09
  • 打赏
  • 举报
回复
再次UP!!
王嘉平 2003-09-09
  • 打赏
  • 举报
回复
>>SDI窗口最大化CPU利用率100%,不最大化最多只有2%.
肯定有问题,应该没有差那么多。

>>每20毫秒做一次VIEW的刷新,好象是什么Invalidate()函数。
这样你是想要大约50fps , 不知道你的机器是什么配置,16k个四边形可能CPU是要满荷了。但是你想重绘不要用Invalidate,直接在OnTimer里面调用DrawSence就好了。但是感觉这个不是根本问题。

不过还有一个要提醒你,你有没有装了硬件加速的OpenGL库。你一定看了我的树,你运行一下看看你的OpenGL版本是什么,如果带有Genrice GDI字样的,就是软加速。
doall4u 2003-09-05
  • 打赏
  • 举报
回复
up
doall4u 2003-09-04
  • 打赏
  • 举报
回复
我做的是一个动画,要在DEM上实现下月所以总要刷新,有什么好办法降低CPU利用率
Leon8086 2003-09-02
  • 打赏
  • 举报
回复
简单说几句,不知道有没有帮助:
首先法向量不要即时计算,法向量自动计算的计算量是非常大的。根据你的需求,法向量完全可以一次计算,多次使用,因为整个过程中法向量是不变的。

至于OnTimer的问题,我认为RealTime Render最好不要用Timer,因为这样帧数控制就很成问题(使用的方法我在后面讲)。事实上使用Timer Render的程序在占用率上比使用IdleRender的要低——如果你做过DDraw程序的话就会很明显。GL渲染的占用率似乎一向很高,我之前的一个Demo用Timer,占用率一般都有50%以上。此外我不明白为何要降低CPU的占用率,这只有在你的渲染控制是多线程的时候才有意义。

对于Display List,compile list会占用比较大的内存,另外你上面的程序并没有给出用list Render的代码,不清楚你怎么控制的。list跟上面我说的法向量的做法应该是一样的,一次编译,到处使用。

OnInitiateUpdate()
{
//...
CompileList();
//...
}

OnRender()
{
//...
glCallList(?);
//...
}

Windows的GL的渲染控制可能比较特别,比如在我机器上,GL的FPS没有上过60(最大60),我不知道这是什么问题,相反地同样功能的D3D程序FPS却可以达到很高。

对于Windows窗口结构的APP,一般采用的是IdleRender的方法——当有消息的时候响应消息,否则渲染,这种控制方法简单有效。使用API的可以修改你的消息循环结构,用PeekMessage取代GetMessage取得消息,如果空闲则渲染。MFC的程序复杂一些,要用CWinApp的OnIdle函数完成这个功能。

不过我用GL在MFC上存在问题,即便使用了OnIdle处理空闲消息也不能达到预期的效果(D3D美有这个问题),而且非常奇怪地当有消息进入的时候(比如鼠标移动,键盘按键)才渲染,反之没有消息进入就停在那里了。这里还要请教一下各位高手。
kyanitelj 2003-09-01
  • 打赏
  • 举报
回复
为什么会使用timer来刷新场景?有这个必要吗?
alphapaopao 2003-09-01
  • 打赏
  • 举报
回复
128*128 数据量不算太大。正如 SeainBlue(爱海) 所说的,不必不断的进行刷新。如果采用 timer 玩易造成消息堵塞就不好办了,GUI界面无法响应用户操作。

绘制动作应该由用户的输入进行驱动,用户有输入(改变观察角度),再进行绘制一次。
另外,显示列表好像的确没什么效果。我也试过的。

OpenGL 中 的 glDrawElement 值得一试,它的速度还是相当快的。

同时建议采用 QueryPerformance() 、GetPerformance() (具体名字可能有误) 的方法,来测算你的绘制函数的时间。
潘李亮 2003-09-01
  • 打赏
  • 举报
回复
我一般不用 Timer,一般也不用MFC。
doall4u 2003-08-31
  • 打赏
  • 举报
回复
up!
SeainBlue 2003-08-31
  • 打赏
  • 举报
回复
至于你的动画实现,一般情况下是需要不断刷新的。
但是如果场景本身没有什么变化,刷新也就没有必要了

最后如果还是不行,只能考虑优化绘制部分的算法
对于数据量大的情况只能考虑在绘制的时候,重新绘制变化的部分;
对于不变的部分不要重新绘制,可以减少绘制的数据量,进而减少CPU利用率
SeainBlue 2003-08-31
  • 打赏
  • 举报
回复
我接触的一些情况是这样的:

在OnDraw函数中当然还是要绘制地形或者包括地物在内的场景了
但是将WM_TIMER相应函数去掉,也就是取消不断的刷新,只是在需要的时候用视图的
Invalidate()进行刷新就可以了。

这样可以明显把CPU利用率降下来
比如漫游的情况下,键盘操作之后需要让场景有些变化,这时候可以调用Invalidate()重新绘制场景。
SeainBlue 2003-08-31
  • 打赏
  • 举报
回复
"我在VC中用的OnTimer,每20毫秒做一次VIEW的刷新"

我不认为相应WM_TIMER是什么好办法,作为地形本身,如果显示出来就可以的化,没有必要让它每隔一段时间刷新一遍,要知道这是很占用CPU资源的。

doall4u 2003-08-31
  • 打赏
  • 举报
回复
up
DFlyingchen 2003-08-31
  • 打赏
  • 举报
回复

CSDN上这方面的高手好像不是很多,到专业的论坛去问问吧…
klbt 2003-08-30
  • 打赏
  • 举报
回复
超长问题,顶!

1,451

社区成员

发帖
与我相关
我的任务
社区描述
多媒体/设计/Flash/Silverlight 开发 图象工具使用
社区管理员
  • 图象工具使用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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