OpenGL--雾

标签: opengl 雾坐标
2125人阅读 评论(0) 收藏 举报
分类:
  • 理论基础
    雾效果:计算机图像有时候由于过于清晰和锐利,反而显得不太逼真。我们可以通过添加雾效果,使整幅图像变得更加逼真。所谓雾效果,就是使远处的物体看上去逐渐变得模糊。雾效果可以提高性能,因为它可以不绘制那些因为雾的影响而不可见的物体。其实现原理其实就是根据雾距离观察点的距离计算出一个混合因子,然后用它把雾颜色与目标颜色进行混合得到的效果。

  • 实例代码
    1,RGBA模式下的5个雾化球体
#include "GLTools.h"
#include "GLShaderManager.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

static GLint fogMode;

static void init(void)
{
    GLfloat position[] = { 0.5, 0.5, 3.0, 0.0 };

    glEnable(GL_DEPTH_TEST);

    glLightfv(GL_LIGHT0, GL_POSITION, position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    {   //{}使模块划分更加清楚
        GLfloat mat[3] = {0.1745, 0.01175, 0.01175};
        glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
        mat[0] = 0.61424; mat[1] = 0.04136; mat[2] = 0.04136;
        glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
        mat[0] = 0.727811; mat[1] = 0.626959; mat[2] = 0.626959;
        glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
        glMaterialf (GL_FRONT, GL_SHININESS, 0.6*128.0);
    }

    glEnable(GL_FOG);//激活雾效果
    {
        GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
        /*雾方程式模式,有三种形式,根据物体距离观察点的距离能
        够算得一个雾因子(默认是计算机自动算出的,但我们也可以自
        己控制雾因子),雾就是通过雾因子把雾颜色与源片段的颜色进
        行混合得到的*/
        fogMode = GL_EXP;
        glFogi (GL_FOG_MODE, fogMode);
        glFogfv (GL_FOG_COLOR, fogColor);//雾颜色
        glFogf (GL_FOG_DENSITY, 0.35);//雾密度
        glHint (GL_FOG_HINT, GL_DONT_CARE);//在渲染质量与速度上没有偏向
        glFogf (GL_FOG_START, 1.0);//雾开始值(距离观察点开始距离)
        glFogf (GL_FOG_END, 5.0);//雾结束值
    }
    glClearColor(0.5, 0.5, 0.5, 1.0);
}

static void renderSphere (GLfloat x, GLfloat y, GLfloat z)
{
    glPushMatrix();
    glTranslatef (x, y, z);
    glutSolidSphere(0.4, 16, 16);
    glPopMatrix();
}


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    renderSphere (-2., -0.5, -1.0);
    renderSphere (-1., -0.5, -2.0);
    renderSphere (0., -0.5, -3.0);
    renderSphere (1., -0.5, -4.0);
    renderSphere (2., -0.5, -5.0);
    glFlush();
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w,
                 2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
    else
        glOrtho (-2.5*(GLfloat)w/(GLfloat)h,
                 2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity ();
}

void keyboard(unsigned char key, int x, int y)
{
    //雾效果逼真程度:GL_EXP < GL_EXP2 < GL_LINEAR
    switch (key) {
        case 'f':
        case 'F':
            if (fogMode == GL_EXP) {
                fogMode = GL_EXP2;
                printf ("Fog mode is GL_EXP2\n");
            }
            else if (fogMode == GL_EXP2) {
                fogMode = GL_LINEAR;
                printf ("Fog mode is GL_LINEAR\n");
            }
            else if (fogMode == GL_LINEAR) {
                fogMode = GL_EXP;
                printf ("Fog mode is GL_EXP\n");
            }
            glFogi (GL_FOG_MODE, fogMode);
            glutPostRedisplay();
            break;
        case 27:
            exit(0);
            break;
        default:
            break;
    }
}


int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutCreateWindow(argv[0]);
    init();
    glutReshapeFunc (reshape);
    glutKeyboardFunc (keyboard);
    glutDisplayFunc (display);
    glutMainLoop();
    return 0;

}

这里写图片描述

2,雾坐标形式使用雾(自己控制雾方程式)

#include "GLTools.h"
#include "GLShaderManager.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

/*不认识glFogCoordfEXT()的解决方案*/
#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
#define GL_FOG_COORDINATE_EXT 0x8451
PFNGLFOGCOORDFEXTPROC glFogCoordfEXT = NULL;

static GLfloat f1, f2, f3;

static void init(void)
{
    GLfloat fogColor[4] = {0.0, 0.25, 0.25, 1.0};
    f1 = 1.0f;
    f2 = 5.0f;
    f3 = 10.0f;

    glEnable(GL_FOG);//激活雾效果
    glFogi (GL_FOG_MODE, GL_EXP);//设置雾方程式
    glFogfv (GL_FOG_COLOR, fogColor);//雾颜色
    glFogf (GL_FOG_DENSITY, 0.25);//雾密度
    glHint (GL_FOG_HINT, GL_DONT_CARE);//没有偏向
    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);//使用雾坐标
    glClearColor(0.0, 0.25, 0.25, 1.0);
}


void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f (1.0f, 0.75f, 0.0f);
    glBegin (GL_TRIANGLES);
    /*使用雾坐标,手动指定每个顶点距离观察点的距离,
    不会随观察点的变化而变化*/
    glFogCoordfEXT (f1);
    glVertex3f (2.0f, -2.0f, 0.0f);
    glFogCoordfEXT (f2);
    glVertex3f (-2.0f, 0.0f, -5.0f);
    glFogCoordfEXT (f3);
    glVertex3f (0.0f, 2.0f, -10.0f);
    glEnd();

    glutSwapBuffers();
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective (45.0, 1.0, 0.25, 25.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity ();
    glTranslatef (0.0, 0.0, -5.0);
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
        case 'c':
            //不使用雾坐标
            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
            glutPostRedisplay();
            break;
        case 'C':
            //使用雾坐标
            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
            glutPostRedisplay();
            break;
        //改变顶点雾坐标
        case '1':
            f1 = f1 + 0.25;
            glutPostRedisplay();
            break;
        case '2':
            f2 = f2 + 0.25;
            glutPostRedisplay();
            break;
        case '3':
            f3 = f3 + 0.25;
            glutPostRedisplay();
            break;
        case '8':
            if (f1 > 0.25) {
                f1 = f1 - 0.25;
                glutPostRedisplay();
            }
            break;
        case '9':
            if (f2 > 0.25) {
                f2 = f2 - 0.25;
                glutPostRedisplay();
            }
            break;
        case '0':
            if (f3 > 0.25) {
                f3 = f3 - 0.25;
                glutPostRedisplay();
            }
            break;
        //前后移动观察点
        case 'b':
            glMatrixMode (GL_MODELVIEW);
            glTranslatef (0.0, 0.0, -0.25);
            glutPostRedisplay();
            break;
        case 'f':
            glMatrixMode (GL_MODELVIEW);
            glTranslatef (0.0, 0.0, 0.25);
            glutPostRedisplay();
            break;
        case 27:
            exit(0);
            break;
        default:
            break;
    }
}


int main(int argc, char** argv)
{
    glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC) glutGetProcAddress("glFogCoordfEXT");

    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutCreateWindow(argv[0]);
    init();
    glutReshapeFunc (reshape);
    glutKeyboardFunc (keyboard);
    glutDisplayFunc (display);
    glutMainLoop();
    return 0;

}

这里写图片描述

查看评论

openGL之雾效果---openGL学习笔记(十二)

雾效果:使所绘制物体距离观察者越远越看的不清晰。     步骤:首先启用雾,然后设置雾颜色,再指定从多远开始到多远结束,最后指定使用哪种雾方程式。   注:指定雾开始结束只针对线性雾的方程式...
  • a358333644
  • a358333644
  • 2016-03-15 17:39:19
  • 1338

OpenGL学习笔记:雾(fog)

使用fog步骤: 1. enable. glEnable(GL_FOG); // 使用雾气 2. 设置雾气颜色。glFogfv(GL_FOG_COLOR, fogColor); 3. 设置雾气的...
  • lcphoenix
  • lcphoenix
  • 2011-07-30 15:54:09
  • 4630

OpenGL: 雾化效果

#include #pragma comment(lib, "glut32.lib") #define MODE_NONE 0 #define MODE_LINEAR 1 #define MODE...
  • Augusdi
  • Augusdi
  • 2014-03-04 23:38:14
  • 4016

opengl体积雾,很实用

  • 2013年06月24日 09:51
  • 917KB
  • 下载

[OpenGL 2.0] 体积雾 | 体渲染初步

上面是雾的浓度由低到高的两张截图, 由于是初步尝试所以以下的描述可能存在问题 ---------------------------- 这里的体积雾是一种后期效果,是对体渲染的一个初步尝试,主要...
  • pizi0475
  • pizi0475
  • 2013-11-05 07:39:31
  • 4104

OpenGL 4.0 GLSL 模拟 雾效果

一个简单的雾效果可以通过混合每个片元的颜色和一个常量的雾颜色来实现,雾的密度量由顶点到相机的距离确定。 我们可以用线性关系或者非线性关系来来表达在顶点到相机之间的雾量。 如下图所示:用线性关系模拟...
  • zhuyingqingfen
  • zhuyingqingfen
  • 2014-02-12 13:59:24
  • 3389

OpenGL 雾

原 文:Lesson 16: Cool Looking Fog译 者:sakura  难道你不想把“雾”加入到你的OpenGL程序中吗?那么在这课里我将要为您展现如何实现这项功能。这是我第一次写教程,...
  • pizi0475
  • pizi0475
  • 2010-02-26 17:23:00
  • 1179

opengl实现线性雾

实现线性雾的几个关键因素 1,指定雾的开始距离,结束距离,雾颜色 2,将模型上的点变换到眼睛坐标系 3,计算雾浓度 效果图 雾的顶点shader attribute vec3 pos;//顶点坐标...
  • hb707934728
  • hb707934728
  • 2017-09-14 11:08:57
  • 446

OpenGL如何实现雾化效果

作为一个OpenGL新手,我今天就跟大家分享一下我学习
  • u012706792
  • u012706792
  • 2014-09-07 19:16:54
  • 1316

Opengl雾气效果

  • 2013年05月08日 01:13
  • 92KB
  • 下载
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 26万+
    积分: 4946
    排名: 7164
    我的GitHub主页
    最新评论