初来乍到,问个问题:怎样直接写屏(不通过OPENGL、DIRECTX等)?(100分)

  • 主题发起人 主题发起人 bbw
  • 开始时间 开始时间
用gdi,有高手测试,他用gdi做的图形mud客户端,在2000下比ddraw只慢10%,win9x下慢20%
 
编译后将文件扩展名改为 .scr,Copy到Windows目录下,就可以在屏幕保护程序中看到
"我写的屏保" 了
 
在dos下还可以考虑直接写屏,但在windows有点难度,要先获得写内存的权限。
再写显卡缓冲。 有难度。
 
Windows一般不让访问视屏的缓冲区,不通过Windows的功能调用很难
 
这样算不算:
var
WinHwnd : Hwnd;
ExCanvas : TCanvas;
begin
winHwnd := GetDC(0);
ExCanvas := TCanvas.Create;
ExCanvas.Handle := WinHwnd;
...........
end;
 
这个当然不算!
 
Windows 下,即使 directX OpenGl 也不是直接写屏的.
 
那为什么会这么快呢?他们是怎么做到的?
 
除非你还用Dos否则别考虑直接写屏了,不现实
不同硬件的访问方式不同,
现在的硬件都支持直接绘图,
放着不用,自己直接写屏,反而慢多了
如果需要速度,就用DirectX吧
 
LiChaoHui,如果不用DirectX呢?如果想用类似DirectX做图的方式呢?用delphi行吗?
 
直接调用显卡驱动程序也行阿,
但我不知道能否调用,和怎么调用
 
DirectX 和 OpenGL 是由硬件辅助的。
 
我刚做了个程序,显示一个图片,还要整张放大、局部放大、拖动,有些像acdsee,
但速度慢,缩放我就用StretchBlt了,大些的图,再放大后要是再在上面做点上面,
比如移动一个TShape,很慢,一个1M的bmp,放大4倍,居然还死了机(win2000),
用DoubleBuffered还是慢,怎么办?acdsee怎么这么快?
 
主要还是你算法和使用的问题
acdsee一样用的gdi..
 
我写的东西,Dos的,实现800 * 600 的文字和绘图

#include "dos.h"
#include "mem.h"
#include "fcntl.h"
#include "io.h"
void put_256pixel(int x,int y,unsigned char color);
void set_mode ( int m );
void set_page ( int bank_number );
void init256();
void close256();
void bar(int x1,int y1,int x2,int y2,unsigned char color);

void puts256(unsigned char *s,int x,int y,int color)
{
char th,tw,i,j,mat[32]={0},canput;
unsigned char *p,*ROM;
struct REGPACK reg;
reg.r_ax=0x1130;
reg.r_bx=0x0600;
intr(0x10,&reg);
ROM=(unsigned char*)MK_FP(reg.r_es,reg.r_bp); /*获得ROM字符集首址*/
while(*s!=0)
{
tw=8;
th=16;
p=ROM+(*s)*16;
memcpy(mat,p,16); /* 16 bytes every character */
s=s+1;

for(j=0;j<th;j++)
for(i=0;i<tw;i++)
{
canput=((mat[j]>>(7-i))&amp;1);
if(canput)
put_256pixel(i+x+2,y+j,color);
}
x=x+8;
} /*end while*/
}

void set_mode ( int m )
{ union REGS i, o ;
i.x.ax = 0x4f02 ;
i.x.bx = m ;
int86 ( 16, &amp;i, &amp;o ) ;
}
void set_page ( int bank_number ) /* change the current page to Blank_number */
{ union REGS i, o ;
i.x.ax = 0x4F05 ;
i.x.bx = 0 ;
i.x.dx = bank_number ;
int86 ( 16, &amp;i, &amp;o ) ;
}

void init256() /* set mode to 800x600 256*/
{
set_mode(0x103);
}

void close256()
{
set_mode(0x03);
}

void bar(int x1,int y1,int x2,int y2,unsigned char color)
{
register int j,i,n[8]={736,672,608,544,480,416,352,288};
register char page_new,page_old;
register char page_end,lastpage,*p=MK_FP(0xa000,0000);
register char buffer[800];
long position;
page_old=8;
memset(buffer,color,800);
for(j=y1;j<=y2;j++) /* j is line number */
{ position=800L*j+x1;
page_new=position/65536;
page_end=(800L*j+x2)/65536;
if(page_new!=page_old)
{ set_page(page_new);
page_old=page_new;
}
if(page_new!=page_end) /*处理显示行跨页*/
{ memcpy(p+position%65536,buffer,n[page_new]-x1);
set_page(page_new+1);
memcpy(p,buffer,x2-n[page_new]+1);
}
else memcpy(p+position%65536,buffer,x2-x1+1);
}
}
void put_256pixel( int x, int y, unsigned char color )
{
static unsigned short curr_vesa_seg = 0xffff ;
unsigned short vesa_seg,vesa_offset ;
unsigned long seg_size = 0xffff + 1L ;
unsigned long offset ;
offset = ( ( unsigned long ) y * ( unsigned long ) 800 + ( unsigned long ) x ) ;
vesa_seg = offset / seg_size ;
vesa_offset = offset % seg_size ;
if ( vesa_seg != curr_vesa_seg )
{ set_page ( vesa_seg ) ;
curr_vesa_seg = vesa_seg ;
}
pokeb ( 0xa000, ( unsigned ) vesa_offset, color ) ;
}
void rectangle256(int x1,int y1,int x2,int y2,unsigned color)
{ bar(x1,y1,x2,y1,color);
bar(x1,y1,x1,y2,color);
bar(x2,y1,x2,y2,color);
bar(x1,y2,x2,y2,color);
}
int main()
{ int i,j;
unsigned char color=10;
char num[4];
init256();


rectangle256(80,80,500,500,10);

puts256("When I was yong I'd listen to the radio!",100,100,10);
bar(100,118,450,118,10);
puts256("**** haha ha ha waint ,alkdslLASDFS!",100,200,13);
bar(100,218,450,218,13);
puts256("司马",100,300,4);
bar(100,318,450,318,4);
puts256("To Be Continued!",100,400,12);
bar(100,418,450,418,12);
getch();
close256();
return 0;
}

 
后退
顶部