`
tiankefeng0520
  • 浏览: 143363 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

OpenGL学习二十七:混合

 
阅读更多

混合步骤:
1.设置混合模式
2.启用混合

glColor4f(1.0f,1.0f,1.0f,0.5f);   // 全亮度, 50% Alpha 混合
glBlendFunc(GL_SRC_ALPHA,GL_ONE);  // 基于源象素alpha通道值的半透明混合函数
glEnable(GL_BLEND);  // 打开混合

 

                    

OpenGL 会把源颜色和目标颜色各自取出(源颜色认为是片段。目标演示是帧缓冲区内容),并乘以一个系数(源颜色乘以的系数称为“源因子”,目标颜色乘以的系数称为“目标因子”),然后相加,这样就得到了新的颜色。(也可以不是相加,新版本的OpenGL可以设置运算方式,包括加、减、取两者中较大的、取两者中较小的、逻辑运算等,但我们这里为了简单起见,不讨 论这个了) 下面用数学公式来表达一下这个运算方式。假设源颜色的四个分量(指红色,绿色,蓝色,alpha值)是(Rs, Gs, Bs, As),目标颜色的四个分量是(Rd, Gd, Bd, Ad),又设源因子为(Sr, Sg, Sb, Sa),目标因子为(Dr, Dg, Db, Da)。则混合产生的新颜色可以表示为: (Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da) 当然了,如果颜色的某一分量超过了1.0,则它会被自动截取为1.0,不需要考虑越界的问题。

源因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个参数,前者表示源因子,后者表示目标因子。这两个参数可以是多种值,下面介绍比较常用的几种。

GL_ZERO: 表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。
GL_ONE: 表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。
GL_SRC_ALPHA:表示使用源颜色的alpha值来作为因子。
GL_DST_ALPHA:表示使用目标颜色的alpha值来作为因子。
GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子。
GL_ONE_MINUS_DST_ALPHA:表示用1.0减去源颜色的alpha值来作为因子。
GL_SRC_COLOR
GL_ONE_MINUS_SRC_COLOR
GL_DST_COLOR
GL_ONE_MINUS_DST_COLOR

 

混合方程式组合像素
void glBlendEquation(Glenum mode)
假设缓冲区颜色为(1,0,0) 片段颜色是(1,1,0)
GL_FUNC_ADD=(1,1,0)+(1,0,0)=(1,1,0)
GL_FUNC_SUBTRACT=(1,1,0)-(1,0,0)=(0,1,0)
GL_FUNC_REVERSE_SUBTRACT=(1,0,0)-(1,1,0)=(0,0,0)
GL_MIN=min((1,0,0),(1,1,0))=(1,0,0)
GL_MAX=max((1,0,0),(1,1,0))=(1,1,0)
GL_LOGIC_OP

 

#include "header.h"

GLfloat	xrot;				
GLfloat	yrot;				
GLfloat xspeed;				
GLfloat yspeed;				
GLfloat	z=-5.0f;			

GLfloat LightAmbient[]=		{ 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[]=		{ 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[]=	{ 0.0f, 0.0f, 2.0f, 1.0f };

GLuint	filter;				
GLuint	texture[3];			


AUX_RGBImageRec *LoadBMP(char *Filename)				
{
	FILE *File=NULL;								

	if (!Filename)									
	{
		return NULL;									
	}

	File=fopen(Filename,"r");					

	if (File)											
	{
		fclose(File);									
		return auxDIBImageLoad(Filename);				
	}

	return NULL;										
}

int LoadGLTextures()								
{
	int Status=FALSE;								

	AUX_RGBImageRec *TextureImage[1];					

	memset(TextureImage,0,sizeof(void *)*1);           	


	if (TextureImage[0]=LoadBMP("Data/glass.bmp"))
	{
		Status=TRUE;									

		glGenTextures(3, &texture[0]);					

		// Create Nearest Filtered Texture
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		// Create Linear Filtered Texture
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		// Create MipMapped Texture
		glBindTexture(GL_TEXTURE_2D, texture[2]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
	}

	if (TextureImage[0])								
	{
		if (TextureImage[0]->data)						
		{
			free(TextureImage[0]->data);				
		}

		free(TextureImage[0]);							
	}

	return Status;										
}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		
{
	if (height==0)										
	{
		height=1;										
	}

	glViewport(0,0,width,height);						

	glMatrixMode(GL_PROJECTION);						
	glLoadIdentity();								

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							
	glLoadIdentity();									
}

int InitGL(GLvoid)									
{
	if (!LoadGLTextures())								
	{
		return FALSE;								
	}

	glEnable(GL_TEXTURE_2D);							
	glShadeModel(GL_SMOOTH);						
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				
	glClearDepth(1.0f);									
	glEnable(GL_DEPTH_TEST);							
	glDepthFunc(GL_LEQUAL);								
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	

	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);		
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);		
	glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);	
	glEnable(GL_LIGHT1);								

	glColor4f(1.0f, 1.0f, 1.0f, 0.5);				
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);				
	return TRUE;									
}

void DrawGLScene(void)									
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();									
	glTranslatef(0.0f,0.0f,z);

	glRotatef(xrot,1.0f,0.0f,0.0f);
	glRotatef(yrot,0.0f,1.0f,0.0f);

	glBindTexture(GL_TEXTURE_2D, texture[filter]);

	glBegin(GL_QUADS);
		// Front Face
		glNormal3f( 0.0f, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		// Back Face
		glNormal3f( 0.0f, 0.0f,-1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		// Top Face
		glNormal3f( 0.0f, 1.0f, 0.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		// Bottom Face
		glNormal3f( 0.0f,-1.0f, 0.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		// Right face
		glNormal3f( 1.0f, 0.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
		// Left Face
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
	glEnd();

	xrot+=xspeed;
	yrot+=yspeed;
	glFlush();
}

void rotate()
{
	glutPostRedisplay();
}
void keyboard(unsigned char key,int x,int y)
{
	switch (key)
	{
	case 'L':
		glEnable(GL_LIGHTING);
		glutPostRedisplay();
		break;
	case 'l':
		glDisable(GL_LIGHTING);
		glutPostRedisplay();
		break;
	case 'B':
		glEnable(GL_BLEND);			
		glDisable(GL_DEPTH_TEST);	
		glutPostRedisplay();
		break;
	case 'b':
		glDisable(GL_BLEND);	
		glEnable(GL_DEPTH_TEST);	
		glutPostRedisplay();
		break;
	case 'F':
		filter+=1;
		if (filter>2)
		{
			filter=0;
		}	
		glutPostRedisplay();
		break;
	case 'W':
		yspeed+=0.01f;	
		glutIdleFunc(rotate);
		break;
	case 'S':
		yspeed-=0.01f;	
		glutIdleFunc(rotate);
		break;
	case 'A':
		xspeed+=0.01f;	
		glutIdleFunc(rotate);
		break;
	case 'D':
		xspeed-=0.01f;	
		glutIdleFunc(rotate);
		break;
	case 'Z':
		z-=0.01f;	
		glutIdleFunc(rotate);
		break;
	case 'X':
		z+=0.01f;	
		glutIdleFunc(rotate);
		break;
	case 'R':
		glutIdleFunc(NULL);
		break;
	}

}


int main(int argc,char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
	glutInitWindowSize(800,600);
	glutInitWindowPosition(100,100);
	glutCreateWindow("混合");
	InitGL();
	glutDisplayFunc(DrawGLScene);
	glutKeyboardFunc(keyboard);
	glutReshapeFunc(ReSizeGLScene);
	glutMainLoop();
}

 

  • 大小: 25.7 KB
  • 大小: 27.2 KB
分享到:
评论

相关推荐

    学习OpenGL必备教程nehe_opengl_chs.chm & 全部课程的源程序

    非常值得学习的OpenGL必备教程!含有48课详细教程和源代码,原教程为英文,DancingWind整理,感谢DancingWind!源代码均在vc6.0经过调试,如果您要在vc.net上使用,自动转换后,须进行必要修改,在VC2005中是将菜单...

    OpenGL_study:使用本教程https进行OpenGL学习的存储库

    OpenGL 学习库 相关资料 教程地址: 原教程地址: 中文教程地址: 参考网址: OpenGL API doc: GLFW: GLEW:   stb: assimp: OpenGL tutorial video: Xcode GLFW & GLEW 环境配置: 目录 注:以下各部分并非...

    OpenGL入门学习之九——使用混合来实现半透明效果.pdf

    OpenGL入门学习之九——使用混合来实现半透明效果.pdf

    OpenGL-ES学习示例

    OpenGL-ES 学习示例 描述:1、GLKit 绘制图片和正方体2、GLSL 绘制金字塔、颜色纹理混合3、GLSL 滤镜集合:灰度、旋涡、正方形马赛克、六边形马赛克4 、GLSL 抖音部分特效:分屏、缩放、抖动、灵魂出窍、毛刺iOS_...

    OpenGL 射击游戏 exe

    学习OpenGL的基础综合性完整VC++工程,包含了基础的视图变换,纹理贴图,雾和混合等内容。利用选择制作的简单的OpenGL射击游戏,希望对你的学习有所帮助。

    OpenGL编程指南(第四版)(PDF)+源码

    本书是OpenGL ARB推荐的OpenGL 1.4版学习指南。本书首先阐述OpenGL的功能和计算机图形学基本知识,包括状态管理和几何体的绘制、模型变换、视点变换和投影变换、颜色和光照;然后深入探讨一些高级技术,包括反走样、...

    opengl写的动画

    根据opengl例子写的一个小动画,可以学习opengl的纹理及混合模式

    Nehe的OpenGL教程电子书

    学习如何用OpenGL来显示列表。只用一行代码预构建和显示物体。使用预编译物体加速你的程序。不要再一次又一次写重复的代码。让显示列表为你做所有的工作吧!这一章里我们将建造Q-bert金字塔(Q-bert是一款游戏),感谢...

    OpenGL学习源代码 VC6.0

    新手学习OpenGL的好资料,从最简单入门,逐步加深。 可以实现3D物体的旋转,俯视 ,大小变换 ,纹理,光照,混合,透视,雾等 包括多个VC6.0工程:OpenGL程序框架、图形字体、纹理图形字、粒子系统、蒙板。。。等等

    OpenGL 射击游戏

    学习OpenGL的基础综合性完整VC++工程,包含了基础的视图变换,纹理贴图,雾和混合等内容。 利用选择制作的简单的OpenGL射击游戏,希望对你的学习有所帮助。

    qt opengl 2d纹理到球面

    看书过后,用qt实现的一个把2维纹理贴到球面的工程,其中还包含混合光,采用opengl es 3.0;初学者可以学习下

    OpenGL ES 3.x游戏开发 上卷 吴亚峰.pdf

    介绍了纹理映射的基本原理与使用,介绍了使用OpenGL ES 3.0开发各种3D基本形状的实现,包括圆柱、圆锥、圆环、螺旋管、几何球以及贝塞尔曲线旋转面等内容,讲解了 3D 模型加载,介绍了混合和雾的基本原理与使用以及...

    qt_opengl_demo.zip

    QT,c++学习Opengl , Glut库学习Demo Lesson01创建一个OpenGLWindow Lesson02创建您的第一个多边形和四边形 Lesson03平滑色彩 Lesson04旋转多边形 Lesson05 SolidObjects Lesson06 TextureMapping Lesson07 ...

    OpenGL ES 3.x游戏开发 上卷 高清版

    内容覆盖了学习OpenGL ES 3.x的必知必会的知识到基于OpenGL ES 3.x实现各种基础特效的技术 ● 介绍了OpenGL ES 3.x渲染管线的知识和使用OpenGL ES 3.x的着色语言 ● 介绍了OpenGL ES 3.x中的光照、纹理映射、3 D ...

    OpenGL入门学习.pdf

    二、点、直线和多边形..........................................................................................................................8 2.1、点、直线和多边形......................................

    OPenGL编程书籍

    学习如何用OpenGL来显示列表。只用一行代码预构建和显示物体。使用预编译物体加速你的程序。不要再一次又一次写重复的代码。让显示列表为你做所有的工作吧!这一章里我们将建造Q-bert金字塔(Q-bert是一款游戏),感谢...

    Qt OpenGL 教程

    Qt 开发过程中,如何调用GPU加速界面响应,一直是开发难点,从这个点切入,详细介绍了Qt开发中如何使用OPENGL,混合开发,C++语言,易懂,推荐大家一起学习。

    OpenGL Programming Guide 7th.pdf

    本书是OpenGL ARB推荐的OpenGL 1.4版学习指南。  本书首先阐述OpenGL的功能和计算机图形学基本知识,包括状态管理和几何体的绘制、模型变换、视点变换和投影变换、颜色和光照;然后深入探讨一些高级技术,包括反...

    OpenGLDemo:OpenGL学习演示

    OpenGL learn demo 01-环境配置 02-移动 03-图元 04-花托(剔除、深度测试、多边形模式) 05-裁剪 06-颜色混合 07-抗锯齿 08-移动(矩阵变换) 09-更多对象(球体、花托、圆柱圆锥、圆盘) 10-正投影矩阵 11-透视投影...

    OpenGL编程指南(第四版).pdf

    本书是OpenGL ARB推荐的OpenGL 1.4版学习指南。本书首先阐述OpenGL的功能和计算机图形学基本知识,包括状态管理和几何体的绘制、模型变换、视点变换和投影变换、颜色和光照;然后深入探讨一些高级技术,包括反走样、...

Global site tag (gtag.js) - Google Analytics