EasyX有没有什么画半透明图形的方法?

0

或者有没有获取屏幕缓存区首地址的方法?通过用户自定义的算法来产生类似于半透明的效果。我之前仿照手机CAPP的体系试着做了一些,自定义了一个屏幕缓存区,再用putpixel将屏幕缓存区的内容打到屏幕上。但这效率太低了,刷新一个640*480的屏幕需要将近一秒。所以有没有更方便快捷的方法?

这里是我的源码,其实有四个文件的我整合到一块了。

//这里开始是types.h

#ifndef types_h
#define types_h 1

typedef int int32;
typedef unsigned int uint32;
typedef short int16;
typedef unsigned short uint16;
//typedef long long int64;
//typedef unsigned long long uint64;
typedef signed char int8;
typedef unsigned char uint8;
typedef struct{uint8 r,g,b;} rgb;
typedef struct{uint8 a,r,g,b;} argb;

#endif

//这里开始是2D-types.h

#ifndef _2D_types_h
#define _2D_types_h 1

#include "types.h"

typedef struct{int32 x,y;} xy32;
typedef struct{uint32 x,y;} uxy32;
typedef struct{double x,y;} fxy64;

#endif

//这里开始是base.h

#ifndef TCC
#define TCC 1

#include <graphics.h>
#include <malloc.h>
#include "types.h"
#include "2D-types.h"

static rgb *buf;
static uint32 scrw,scrh;
#define SCRW getScrWidth()
#define SCRH getScrHeigh()

//#define scrref 1

uint32 getScrWidth()
{return scrw;}
uint32 getScrHeigh()
{return scrh;}

extern int base_main();

void cls(rgb clr)//清屏
{
	uint32 size=scrw*scrh;
	for(uint32 a=0;a<size;a++)
		buf[a]=clr;
}

void dpointex(uxy32 dzn,argb clr)//在屏幕缓存区打一个点
{
	if(dzn.x>=scrw||dzn.y>=scrh) return;
	rgb *clr2=&buf[dzn.x+dzn.y*scrw];
	uint16 a=(uint16)clr.a+1;
	uint16 A=257-a;
	clr2->r=(a*clr.r+A*clr2->r)>>8;
	clr2->g=(a*clr.g+A*clr2->g)>>8;
	clr2->b=(a*clr.b+A*clr2->b)>>8;
}

void drect(uxy32 dzn,uxy32 size,argb clr)//画实心长方形
{
	size.x+=dzn.x;
	size.y+=dzn.y;
	uint16 a=(uint16)clr.a+1;
	uint16 A=257-a;
	if(size.x>scrw) size.x=scrw;
	if(size.y>scrh) size.y=scrh;
	for(;dzn.y<size.y;dzn.y++)
	{
		for(uint32 b=dzn.x;b<size.x;b++)
		{
			uint32 bit=b+scrw*dzn.y;
			//buf[bit].r=(clrbuf[bit].r*A;
			buf[bit].r=((uint16)a*clr.r+(uint16)A*buf[bit].r)>>8;
			buf[bit].g=((uint16)a*clr.g+(uint16)A*buf[bit].g)>>8;
			buf[bit].b=((uint16)a*clr.b+(uint16)A*buf[bit].b)>>8;
		}
	}
}

void ref(uint32 x,uint32 y,uint32 w,uint32 h)//刷新屏幕
{
	w+=x;
	h+=y;
	if(w>scrw) w=scrw;
	if(h>scrh) h=scrh;
	for(;y<h;y++)
		for(uint32 a=x;a<w;a++)
		{
			rgb clr=buf[a+scrw*y];
			putpixel(a,y,RGB(clr.r,clr.g,clr.b));
		}
#ifdef scrref
	FlushBatchDraw();
#endif
}

int main()//虚假初始函数
{
	scrw=640;
	scrh=480;
	initgraph(scrw,scrh);
	buf=(rgb*)calloc(scrh,scrw*3);
#ifdef scrref
	BeginBatchDraw();
#endif
	return base_main();
}

#ifdef main
#undef main
#endif

#define main base_main

void exitApp()//退出函数
{
	free(buf);
#ifdef scrref
	EndBatchDraw();
#endif
	closegraph();
}

#ifdef scrref
#undef scrref
#endif

#endif

//这里开始是main.cpp

//#include <stdio.h>
//#include <windows.h>
#include <graphics.h>
#include <conio.h>
#include "base.h"

int main()
{
	//initgraph(640,480);
	//setcolor(YELLOW);
	uxy32 a={100,100},b={100,150};
	argb clr={127,0,255,255},clr1={127,255,0,255};
	rgb clr2={0,0,0};
	for(;a.x<200;a.x++)
	{
		cls(clr2);
		drect(a,a,clr);
		drect(b,a,clr1);
		ref(a.x-1,a.y,a.x+1,a.y+50);
		//ref(0,0,SCRW,SCRH);
		//Sleep(10);
	}
	exitApp();
	return 0;
}
ava
C酱

2020-8-3

0

半透明贴图的方法请参考 CodeBus 的技术文章:https://codebus.cn/yangw/a/transparent-putimage

获取显示缓冲区的函数:https://docs.easyx.cn/GetImageBuffer

直接操作显示缓冲区实现高速绘图的例子:https://codebus.cn/search?q=显示缓冲区

ava
慢羊羊

2020-8-3

技术讨论社区