`
tiankefeng0520
  • 浏览: 145700 次
  • 性别: 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学习

    ### OpenGL学习知识点详解 #### 一、OpenGl简介与预备知识 **1.1 引言** 本教程旨在为读者提供一个系统性学习OpenGl的平台。OpenGl是一种跨语言、跨平台的应用程序接口(API),用于渲染二维、三维矢量图形。它是...

    OpenGL编程指南第七版(PDF扫描版)

    《OpenGL编程指南第七版》是一本深度探讨OpenGL技术的权威性参考书,它全面覆盖了OpenGL的核心概念、功能以及最新的编程技巧。此书是计算机图形学领域的宝贵资源,尤其适合那些希望深入理解并掌握OpenGL技术的专业...

    OpenGL编程指南第七版(红宝书)

    ### OpenGL编程指南第七版(红宝书)知识点详解 #### 一、OpenGL简介与发展历程 - **OpenGL**:OpenGL(Open Graphics Library)是一种用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。它使用...

    Android下 OpenGL ES 2.0 混合半透明效果demo

    在这个"Android下 OpenGL ES 2.0 混合半透明效果demo"中,我们将探讨如何在Android应用中实现半透明效果的混合。 首先,理解OpenGL ES 2.0的核心概念至关重要。它基于着色器模型,这意味着开发者可以编写顶点着色器...

    OpenGL学习资料文档.rar

    本资源集合包含了一套完整的OpenGL学习资料,适合初学者入门。 首先,"OpenGL编程指南第七版"是学习OpenGL的基础书籍,它深入浅出地介绍了OpenGL的工作原理和基本概念,包括上下文创建、窗口系统集成、绘图函数、...

    OpenGL.rar_OpenGL pdf_OpenGL 参考手册_opengl_opengl 参考_中英文

    4. **状态机**:OpenGL的状态机管理着各种图形属性,如颜色、深度测试、混合模式等。开发者可以通过调用函数来改变这些状态。 5. **缓冲区**:OpenGL使用各种缓冲区来存储数据,如顶点缓冲区、索引缓冲区和帧缓冲区...

    OpenGL入门学习之十四——OpenGL版本和OpenGL扩展.pdf

    #### 二、OpenGL版本的向下兼容性 OpenGL的一个重要特点是其向下兼容性。这意味着,如果某个特性或功能在较低版本中存在,那么在较高版本中也一定会存在。这种设计确保了开发人员能够平滑地迁移代码,并利用新版本...

    OpenGL混合例子

    通过研究源代码,你可以学习到如何设置OpenGL状态、处理颜色混合以及使用GLUT库来构建一个简单的图形应用程序。这个例子对于任何想要提升OpenGL技能,尤其是对透明效果感兴趣的开发者来说,都是宝贵的资源。

    glew1.5.0 OpenGL学习资源

    "glew1.5.0 OpenGL学习资源"这个压缩包文件显然包含了GLEW 1.5.0版本的相关资料,这对于学习和开发使用OpenGL的应用程序来说非常宝贵。 GLEW的主要作用在于管理和加载OpenGL扩展。在OpenGL的发展过程中,许多新的...

    OpenGL学习内容以及参考书籍和网站-2008.

    ### OpenGL学习内容以及参考书籍和网站-2008 #### 一、OpenGL背景与历史 OpenGL(Open Graphics Library)是一种跨平台的应用程序接口(API),用于渲染2D和3D矢量图形。它最初由Silicon Graphics Inc. (SGI) 开发...

    OpenGL经典学习书籍

    其次,《OpenGL编程指南》第七版,也被称为“红宝书”,是OpenGL学习的经典之作。这本书全面介绍了OpenGL 4.x版本,包括新的核心模式、固定功能管道的移除、向量和矩阵运算、着色语言GLSL、纹理、帧缓冲对象、几何...

    Android OpenGL ES学习

    在学习Android OpenGL ES时,首先需要理解基本概念,例如顶点、图元、着色器等。顶点是构成几何形状的基本元素,图元是顶点连接形成的形状(如点、线段、三角形),而着色器则是负责计算像素颜色的程序。 1. **顶点...

    OpenGL2.1.pdf

    #### 二、OpenGL 2.1系统概述 ##### 2.1 OpenGL基础 - **浮点计算**:OpenGL中的所有数学运算都基于浮点运算,这确保了高精度和一致性。 - **GL状态**:OpenGL通过一组可配置的状态来管理渲染环境。这些状态包括颜色...

    opengl学习代码-自用

    这个“opengl学习代码-自用”压缩包很可能是为了帮助学习和理解OpenGL编程而准备的一系列示例代码。下面我们将深入探讨OpenGL的一些核心概念、使用场景以及学习资源。 1. OpenGL简介: OpenGL是一种跨语言、跨平台...

    OpenGL ES 学习demo

    在这个“OpenGL ES 学习demo”中,我们可以看到一系列的示例代码和项目,用于帮助初学者理解并实践基本的OpenGL ES绘图操作。 首先,让我们来探讨一下OpenGL ES的基础概念: 1. **坐标系统**:OpenGL ES 使用右手...

    opengl课件 opengl课件

    - 纹理映射和混合:如何使用纹理增强图形表现力,以及如何实现透明和混合效果。 - 属性和状态管理:如何设置和修改OpenGL的状态,以影响渲染结果。 通过这份课件,你可以系统地学习OpenGL,从基础知识到高级特性,...

Global site tag (gtag.js) - Google Analytics