OpenGL透明效果源码(VS2015/x64)

Data 2018/7/4  by WJB

知识点:

       Blend 混合是将源色和目标色以某种方式混合生成特效的技术。混合常用来绘制透明或半透明的物体。在混合中起关键作用的α值实际上是将源色和目标色按给定比率进行混合,以达到不同程度的透明。α值为0则完全透明,α值为1则完全不透明。混合操作只能在RGBA模式下进行,颜色索引模式下无法指定α值。物体的绘制顺序会影响到OpenGL的混合处理。

glEnable( GL_BLEND );   // 启用混合

glDisable( GL_BLEND );  // 禁用关闭混合

glBlendFunc( GLenum sfactor , GLenum dfactor );         // 混合函数

sfactor 源混合因子      dfactor 目标混合因子

glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ); // 是最常使用的

若源色为 ( 1.0 , 0.9 , 0.7 , 0.8 )

源色使用 GL_SRC_ALPHA

即 0.8*1.0 , 0.8*0.9 , 0.8*0.8 , 0.8*0.7

结果为 0.8 , 0.72 , 0.64 , 0.56

目标色为 ( 0.6 , 0.5 , 0.4 , 0.3 )

目标色使用GL_ONE_MINUS_SRC_ALPHA

即 1 - 0.8 = 0.2

0.2*0.6 , 0.2*0.5 , 0.2*0.4 , 0.2*0.3

结果为 0.12 , 0.1 , 0.08 , 0.06

由此而见,使用这个混合函数,源色的α值决定了结果颜色的百分比。

这里源色的α值为0.8,即结果颜色中源色占80%,目标色占20%。

特别说明:如果二维数据,位置点z值为0,或者没有z值,则不需要开始深度测试

#include "stdafx.h"
#include "glut.h"
#pragma comment(lib, "glut32.lib")

void Initialization()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);


GLfloat lightSpecular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lightPosition[] = { 0.5, 0.5, 4.0, 0.0 };

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //指定混合函数
glShadeModel(GL_SMOOTH);

glMaterialfv(GL_FRONT, GL_SPECULAR, lightSpecular);
glMaterialf(GL_FRONT, GL_SHININESS, 100.0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);

glEnable(GL_BLEND);        //启用混合状态
glEnable(GL_LIGHTING);        //启用光照
glEnable(GL_LIGHT0);        //打开光源0
glEnable(GL_DEPTH_TEST);    //启用深度检测
glEnable(GL_COLOR_MATERIAL);//材质跟踪当前绘图色
}


void OnDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //双缓冲机制 

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();   //装载
{
glTranslatef(0.0f, 0.0f, -3.0f);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glutSolidTorus(1.0f, 2.0f, 30.0f, 30.0f);//绘制圆环
}
glPopMatrix();  //装出

glPushMatrix();
{
glTranslatef(1.0f, 1.0f, 3.0f);
glColor4f(0.0f, 1.0f, 0.0f, 0.5);
glutSolidSphere(2.0f, 30.0f, 30.0f);//绘制球体
}
glPopMatrix();

glPushMatrix();
glTranslatef(-1, -1, 4);
glColor4f(0.0f, 0.0f, 1.0f, 0.5);
glBegin(GL_QUADS);  //绘制四边形
glVertex3f(0, 0, 0);
glVertex3f(5, 0, 0);
glVertex3f(5, 5, 0);
glVertex3f(0, 5, 0);
glEnd();
glPopMatrix();

glPushMatrix();
glColor4f(0.0f, 1.0f, 1.0f, 0.5);
glTranslatef(-1, -1, 5);
glRotatef(60, 0, 0, 1);
glBegin(GL_QUADS);
glVertex3f(0, 0, 0);
glVertex3f(5, 0, 0);
glVertex3f(5, 5, 0);
glVertex3f(0, 5, 0);
glEnd();
glPopMatrix();


glutSwapBuffers();
}

void OnReShape(int w, int h)
{
glViewport(0, 0, w, h);


glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影模式
glLoadIdentity();

if (h != 0)
{
GLfloat aspect = GLfloat(w) / GLfloat(h);

if (w < h)
{
glOrtho(-6.0f, 6.0f, -6.0f * aspect, 6.0f * aspect, -6.0f, 6.0f);//三维正交投影
}
else
{
glOrtho(-6.0f / aspect, 6.0f / aspect, -6.0f, 6.0f, -6.0f, 6.0f);
}
}
glMatrixMode(GL_MODELVIEW);
}

void main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 480);
glutCreateWindow("OpenGL透明");

glutReshapeFunc(OnReShape);
glutDisplayFunc(OnDisplay);

Initialization();
glutMainLoop();  //主程序循环

}// blenddeom.cpp : 定义控制台应用程序的入口点。

效果图:


源码下载:https://download.csdn.net/download/wangjianbo09/10519075

猜你喜欢

转载自blog.csdn.net/wangjianbo09/article/details/80911128