OpenGL_9 混合

混合即透明显示(透明的实现是将前面物体的颜色与后面物体的颜色混合),这里需要用到Alpha值,Alpha值为0为全透明,1为全不透明

关键点:混合公式(R,G,B,Alpha) = (Rs * Sr + Rd * Dr, Gs * Sg + Gd * Dg, Bs * Sb + Bd * Db, As * Sa + Ad * Da

通常,S+D = 1,故混色公式同时可写成

(R,G,B,Alpha) = (Rs * As + Rd * (1 - As), Gs * As + Gd * (1 - As), Bs * As + Bs * (1 - As), As * As + Ad * (1 - As))

注意点:正确的混色过程应该是先绘制全部的场景之后再绘制透明的图形。并且要按照与深度缓存相反的次序来绘制(先画最远的物体)。

开始声明全局变量:

BOOL blend;//是否混合
BOOL bp;
OpenGL初始化函数中需要使用glColor4f()函数(使用了Alpha值)

int InitGL(GLvoid)
{
	if (!LoadGLTextures())//调用纹理载入
	{
		return FALSE;
	}
	glEnable(GL_TEXTURE_2D);//启用纹理映射
	glShadeModel(GL_SMOOTH);	//设置深度缓存
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);	//启用深度测试
	glDepthFunc(GL_LEQUAL);		//所作深度测试的类型
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);//设置环境光
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);//设置漫反射
	glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);//设置光源位置
	glEnable(GL_LIGHT1);//启用一号光源
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//反锯齿
	glColor4f(1.0f, 1.0f, 1.0f, 0.5f);//全亮度,50%Alph混合
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);//基于源像素alpha通道值的半透明混合函数
	return TRUE;
}
WinMain()函数中定义了B键对混合开启和关闭的操作

代码如下:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;
	BOOL done = FALSE;
	if (MessageBox(NULL, L"你想在全屏模式下运行吗", L"设置全屏模式", MB_YESNO | MB_ICONQUESTION) == IDNO)
	{
		fullscreen = FALSE;
	}
	if (!CreateGLWindow(L"OpenGL程序框架", 640, 480, 16, fullscreen))
	{
		return 0;
	}
	while (!done)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))//有消息在等待吗
		{
			if (msg.message == WM_QUIT)
			{
				done = TRUE;
			}
			else
			{
				TranslateMessage(&msg);//翻译消息
				DispatchMessage(&msg);//发送消息
			}
		}
		else
		{
			if (active)
			{
				if (keys[VK_ESCAPE])//ESC按下
				{
					done = TRUE;
				}
				else
				{
					DrawGLScene();
					SwapBuffers(hDC);
				}
				if (keys['L'] && !lp)//L键按下并且未松开
				{
					lp = TRUE;
					light = !light;
					if (!light)//如果没有光源
					{
						glDisable(GL_LIGHTING);//禁用光源
					}
					else
					{
						glEnable(GL_LIGHTING);//启用光源
					}
				}
				if (!keys['L'])//L键松开了
				{
					lp = FALSE;
				}
				if (keys['F'] && !fp)//F键按下并且未松开
				{
					fp = TURE;
					filter += 1;
					if (filter > 2)
					{
						filter = 0;
					}
				}
				if (!keys['F'])
				{
					fp = FALSE;
				}
				if (keys[VK_PRIOR])//PageDown按下了
				{
					z -= 0.02f;//若按下,木箱远离观察者
				}
				if (keys[VK_UP])//PageUp按下
				{
					z += 0.02f;//若按下,木箱靠近观察者
				}
				if (keys[VK_UP])//Up方向键按下
				{
					yspeed += 0.01f;
				}
				if (keys[VK_DOWN])//Down方向键按下
				{
					yspeed -= 0.01f;
				}
				if (keys[VK_RIGHT])//Right方向键按下
				{
					xspeed += 0.01f;
				}
				if (keys[VK_LEFT])//Left方向键按下
				{
					xspeed -= 0.01f;
				}
				if (keys['B'] && !bp)//B键按下
				{
					bp = TRUE;
					blend = !blend;
					if (blend)//混合打开
					{
						glEnable(GL_BLEND);//打开混合
						glDisable(GL_DEPTH_TEST)//关闭深度测试
					}
					else
					{
						glDisable(GL_BLEND);//关闭混合
						glEnable(GL_DEPTH_TEST);//打开深度测试
					}
				}
				if (!keys['B'])
				{
					bp = FALSE;
				}
				if (keys[VK_F1])//F1按下
				{
					keys[VK_F1] = FALSE;
					KillGLWindow();
					fullscreen = !fullscreen;
					if (!CreateGLWindow(L"OpenGL程序框架", 640, 480, 16, fullscreen))//重建OpenGL窗口
					{
						return 0;
					}
				}
			}
		}
	}

	KillGLWindow();
	return(msg.wParam);
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值