OpenGL透明与混色效果

在OpenGL中,物体透明技术通常被叫做混合(Blending)

透明是物体(或物体的一部分)非纯色而是混合色,这种颜色来自于不同浓度的自身颜色和它后面的物体颜色。

一个有色玻璃窗就是一种透明物体,玻璃有自身的颜色,但是最终的颜色包含了所有玻璃后面的颜色。这也正是混合这名称的出处,因为我们将多种(来自于不同物体)颜色混合为一个颜色,透明使得我们可以看穿物体。

透明物体可以是完全透明(它使颜色完全穿透)或者半透明的(它使颜色穿透的同时也显示自身颜色)。一个物体的透明度,被定义为它的颜色的alpha值。alpha颜色值是一个颜色向量的第四个元素,当alpha值是0.0时就表示物体是完全透明的,alpha值为0.5时表示物体的颜色由50%的自身的颜色和50%的后面的颜色组成。

我们之前所使用的纹理都是由3个颜色元素组成的:红、绿、蓝,但是有些纹理同样有一个内嵌的aloha通道,它为每个纹理像素(Texel)包含着一个alpha值。这个alpha值告诉我们纹理的哪个部分有透明度,以及这个透明度有多少。

要使用OpenGL的混合功能,只需要调用:glEnable(GL_BLEND);即可;要关闭OpenGL的混合功能,只需要调用:glDisable(GL_BLEND);即可。

为了在场景中增加光照,需要执行以下步骤:

  1. 设置一个或多个光源,设定光源的有关属性;
  2. 选择一种光照模型;
  3. 设置物体的材质属性及色彩的Alpha色彩混合属性值。

二、示例代码

#include "stdafx.h"
#include <gl/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();  //主程序循环
}

效果如下:

三、总结

进一步了解OpenGL程序的光照与材质参数的设置方法,并能使用alpha透明度参数实现不同几何对象的视觉色彩混合效果。

时间: 2024-10-15 18:59:38

OpenGL透明与混色效果的相关文章

UILabel混色显示

效果: 源码: // // RootViewController.m // ColorLabels // // Copyright (c) 2014年 Y.X. All rights reserved. // #import "RootViewController.h" #import "YXGCD.h" @interface RootViewController () @property (nonatomic, strong) UIView *upView; @p

反色效果函数

// 反色效果函数 public static Bitmap chageToInvert(Bitmap bitmap) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); int colorArray[] = new int[width * height]; int r, g, b, index; bitmap.getPixels(colorArray, 0, width, 0, 0, width, height);

android TextView里边实现图文混配效果

用TextView实现这样的效果,图片文字混排,文字不同颜色字体,打电话和吊起浏览器等等 代码如下: @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myTextView = (TextView) this.findViewById(R.id.img_iv); //创建一个

Android状态栏透明(沉浸式效果)

Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q4878802/9058275 1. 修改状态栏和导航栏的属性为透明 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //透明状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_T

CSS文字环绕图片 图文混排效果

CSS实现文字环绕图片效果,也就是大家常见到的文中图效果,比如文字会自动围绕一个方块状的图片广告,这一切都是自动的,不需要另外排版,对此有需要有网页,可借鉴本代码,主要是利用CSS的clear属性实现. <html> <head> <title>CSS文字环绕图片 图文混排效果丨石家庄电缆附件</title> </head> <body> <div style="float:left;"> <di

img里的align属性能保证图文的混排效果以及vspace和hspace

(1)如果不实用align,那么img标签只是行内标签占据一行,图文混排效果如下: (2)使用了align属性: <img src="1.jpg" alt="这是xx图片" width="200" align="left"/> (3)主要注意的是,如果需要等比例缩放图片,一般只设置宽,或者只设置高.两个都设置就真按照你写的数字来缩放了. (4)还有一个图片边距的属性,这几个属性平时使用频率并不高,但是十分使用.尤其

C# WPF 歌词控件(支持逐字定位描色效果)

原文:C# WPF 歌词控件(支持逐字定位描色效果) 之前做了一个模仿网易云歌词的控件,实现了加载网易云歌词并能随音乐播放进度定位歌词.今天呢将在这个控件的基础上增加逐字定位描色功能,如下图效果(QQ音乐PC)所示: 我所使用的实现方法很简单粗暴,把每句歌词每个字切开,单独显示在一个描色的控件中,然后拼成一行完整的歌词,随音乐播放进度去找相应的字进行描色. 而最重要的描色功能是怎么实现的呢? 答案是:使用ClipToBounds属性 当控件ClipToBounds属性为TRUE时,超出控件范围的

[Swift通天遁地]八、媒体与动画-(15)使用TextKit实现精美的图文混排效果

本文将演示制作一款更加精美的图文的图文混排效果:将文字紧贴图片边缘的图文混排效果. 往项目中导入一份文本文件. 在左侧的项目导航区,打开视图控制器的代码文件[ViewController.swift] 1 import UIKit 2 3 class ViewController: UIViewController { 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 // Do any additional setup afte

OpenGL中创建聚光灯的效果

现在,我们使用如下的数组来指定一个光源的位置: // 指定光源位置的数组 GLfloat lightPos[] = {0.0f, 0.0f, 75.0f, 1.0f}; // 设置光源0的位置 glLightfv(GL_LIGHT0,GL_POSITION,lightPos); lightPos数组的最后一个值在此为1.0,它表示光源的实际位置就在(X,Y,Z)所表示的位置.在默认情况下,光线从这个位置均匀地向四周发射.如果我们把lightPos数组的最后一个值设为0.0,可以使光源看上去像是来