游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3981|回复: 13

这里有个可怜的孩子求助 :(

[复制链接]

5

主题

33

帖子

35

积分

注册会员

Rank: 2

积分
35
QQ
发表于 2004-10-7 00:37:00 | 显示全部楼层 |阅读模式
我在做半透明处理的时候,是直接锁定两个SURFACE,然后两个图象对应的象素每个乘以50%相加再写回去。
如果我在定义离屏页面的时候如果是

desc.ddsCaps.dwCaps =DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;

没有DDSCAPS_SYSTEMMEMORY参数的话会慢的要死。如果加了的话,就会出现画面撕裂的现象,就是画面一扯一扯的样子。

我翻了半个月的资料了啊。。还是没找到答案,哭。。。。

有没有大哥哥大姐姐能告诉我怎么解决,或者其他的半透明处理方式,我请客 [em1]

:P

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20686
发表于 2004-10-7 00:40:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

首先,加DDSCAPS_SYSTEMMEMORY参数是让DDraw把表面保存于内存中,而非放在显存,内存的存取速度远远高于显存,所以你加DDSCAPS_SYSTEMMEMORY参数的时候做混合速度会比较快。

其次画面撕裂,我不清楚你是如何处理,你可以把所有要绘制的图片全部整理绘制到一个BackSurface(背缓冲),然后等都准备好了,再把这个背缓冲一次性更新到屏幕上,这样一般都不会有什么问题。

5

主题

33

帖子

35

积分

注册会员

Rank: 2

积分
35
QQ
 楼主| 发表于 2004-10-7 01:05:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

呵呵,谢谢sea_bug哥哥。
我处理的方式大概是下面思路:
1,把两张要用到的图片载入到离屏页 surface_1,surface_2.都是保存在内存里的形式。

2,定义一个空的离屏页surface_final,也是保存在内存里的形式,然后吧offsurface_1贴到surface_final上,然后把他和surface_2混合。

3。把surface_final贴到BackSurface(背缓冲)后,然后在用flip或者bitblt贴到mainsurface上。

我试了几遍都有问题,甚至我就直接在内存里创建surface,什么都不做,只是贴到背缓冲后在贴出来都会时不时的扯一下。但在显存里创建就没问题     :(

我在玩暗黑和仙剑2的时候也有时会一扯一扯的,但是您做的HOHO引擎的例子和一些大型的网络游戏(比如梦幻西游)就不会。

我重新装过显卡驱动和DIRECTX也没用。是不是程序实现的机制有问题呢?

我的半透明处理是这样实现的:
                DDSURFACEDESC2 descsrc,descdest;
                HRESULT result=0;
                BYTE *srcstart,*deststart;
                ZeroMemory(&descsrc,sizeof(descsrc));
                descsrc.dwSize=sizeof(descsrc);
                ZeroMemory(&descdest,sizeof(descdest));
                descdest.dwSize=sizeof(descdest);
                result=OffSurface->Lock(NULL,&descdest,DDLOCK_WAIT,NULL);
                if(result!=DD_OK)
                        debug.AddError("锁定失败");
                result=msurface->OffSurface->Lock(NULL,&descsrc,DDLOCK_WAIT,NULL);
                if(result!=DD_OK)
                        debug.AddError("锁定失败");
                srcstart=(BYTE*)descsrc.lpSurface;
                deststart=(BYTE*)descdest.lpSurface;
                int imgsrcheight=descsrc.dwHeight;
                int imgsrcwidth=descsrc.dwWidth;
                int imgdestheight=descdest.dwHeight;
                int imgdestwidth=descdest.dwWidth;
                float alpha1=1-alpha;       
                BYTE *pixelsrc=srcstart,*pixeldest=&deststart[(x+imgdestwidth*y)*4];
                for(int imgy=0;imgy<imgsrcheight;imgy++)
                {
                        pixeldest=&deststart[(x+imgdestwidth*(y+imgy))*4];
                        for(int imgx=0;imgx<imgsrcwidth;imgx++)
                        {
                                *pixeldest=(BYTE)(*pixelsrc*alpha+*pixeldest*alpha1);
                                pixelsrc++,pixeldest++;
                                *pixeldest=(BYTE)(*pixelsrc*alpha+*pixeldest*alpha1);
                                pixelsrc++,pixeldest++;
                                *pixeldest=(BYTE)(*pixelsrc*alpha+*pixeldest*alpha1);
                                pixelsrc+=2,pixeldest+=2;
                        }
                }
                OffSurface->Unlock(NULL);
                msurface->OffSurface->Unlock(NULL);




然后主程序里的循环是这样的:
void MainEnter::MainLoop()
{
        MSG msg;
        while (TRUE)
        {
                if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
                {
                        if( !GetMessage( &msg, NULL, 0, 0 ) )
                        {
                                break;
                        }
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
                else
                {
                        Surfacefinal.AddSurface(&Surface,0,0,0);
                        gamedisplay.BackSurface.AddSurface(&Surfacefinal,0,0,0);
                        gamedisplay.ShowSurface();
                        Sleep(1);        //这里想不明白,为什么要加Sleep才能运行流畅
                }
        }
}

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20686
发表于 2004-10-7 01:17:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

汗!刚想回家。。。外面呼啸的寒风。。。 看到你回复的内容那么多,不得不马上给你回复一下。:)

你的做法没有问题,而且思路挺正确,看来问题主要集中在为何图像更新到屏幕上会有撕裂现象,这个问题可能是你没有跟踪垂直回扫,当然,这个东西说起来挺复杂(我也说不清楚),但我们可以找找方法来解决,简单的方法,打开DX的例子,看他会不会闪烁,如果不会,把它的代码打开,看看最后屏幕更新部分和你写的有什么不同,Copy过来吧,呵呵!

附一段HoHo的更新屏幕部分:
m_pFrontSurface->GetSurface()->Blt( NULL, m_pBackSurface->GetSurface(), NULL, DDBLT_WAIT, NULL );

m_pFrontSurface:是我的surface前缓冲
m_pBackSurface:是我surface背缓冲
这两个结构我是做了封装,实际上GetSurface()就是把实际surface句柄取出进行blt操作。

我回家去了,还要走半小时的路~~~ 晚上回不了你帖子,明天吧!

5

主题

33

帖子

35

积分

注册会员

Rank: 2

积分
35
QQ
 楼主| 发表于 2004-10-7 01:52:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

嘿嘿,辛苦您拉。回家多喝点茶,穿多点衣服,好好睡。

我实验过垂直同步,找了不下10本书   :(
好象有个WaitForVerticalBlank(DDWAITVB_BLOCKEND,NULL);可以等待同步,没用。。


还有                DDBLTFX bltfx;
                bltfx.dwSize=sizeof(bltfx);
                bltfx.dwDDFX=DDBLTFX_NOTEARING;
看到了那个NOTEARING,好象是防止撕裂的,也没用。。

呵呵,晚上不睡觉了,看DIRECTX的例子。好象没有DDRAW,只有D3D的。  :)

60

主题

1319

帖子

1319

积分

金牌会员

Rank: 6Rank: 6

积分
1319
发表于 2004-10-7 08:05:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

你说乘50%,不是直接写成 *0.5 吧?如果是那样可真要慢死了。

5

主题

33

帖子

35

积分

注册会员

Rank: 2

积分
35
QQ
 楼主| 发表于 2004-10-7 11:24:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

呵呵,开始只是试验着看看,没考虑速度问题,用移位>>2应该就快很多了吧

继续看samples...

26

主题

417

帖子

476

积分

中级会员

总版主

Rank: 3Rank: 3

积分
476
发表于 2004-10-7 14:25:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

哦? 这回是“可怜的孩子”了。。。不是什么:PLMM , 雨夜, 跪求之类的了? 呵呵。。。

26

主题

417

帖子

476

积分

中级会员

总版主

Rank: 3Rank: 3

积分
476
发表于 2004-10-7 14:32:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

高手问题啊。。。不懂。。。

检查一下你的pixel format以及screen color depth是否与你的处理匹配

32

主题

1583

帖子

1589

积分

金牌会员

Rank: 6Rank: 6

积分
1589
发表于 2004-10-7 19:00:00 | 显示全部楼层

Re:这里有个可怜的孩子求助 :(

哇,真的处理透明全部都必须使用Lock函数锁定表面自己算了?
(我简直不敢相信2D游戏中的透明以及其他特效全部是程序一个像素一个像素自己计算出来的)

那岂不慢死了~~~难道DX中就真的没有支持位操作的绘制方法吗?

郁闷中……
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-22 16:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表