OpenGL--纹理组合器函数

  • 理论基础
    纹理组合器函数(glTexEnvf):简单点讲就是指定纹理贴图和材质混合的方式。固定管线时代,它只是告诉你,纹理的像素读取出来之后,其实还可以经过一些复杂变换,然后才拿去使用,这样可以搞出一些绚丽效果。不过现在shader可以进行更多更自由的变换,所以这东西现在就没什么用了。

  • 实例代码
#include "GLTools.h"

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

#define imageWidth 8
#define imageHeight 8

static GLubyte image0[imageHeight][imageWidth][4];
static GLubyte image1[imageHeight][imageWidth][4];

static GLuint texName[4];

void makeImages(void)
{
    int i, j, c;
    for (i = 0; i < imageHeight; i++) {
        for (j = 0; j < imageWidth; j++) {
            c = ((i&2)==0)*255;
            image0[i][j][0] = (GLubyte) c;
            image0[i][j][1] = (GLubyte) c;
            image0[i][j][2] = (GLubyte) c;
            image0[i][j][3] = (GLubyte) 255;
            c = ((j&4)!=0)*128;
            image1[i][j][0] = (GLubyte) 0;
            image1[i][j][1] = (GLubyte) c;
            image1[i][j][2] = (GLubyte) c;
            image1[i][j][3] = (GLubyte) 255;
        }
    }
}

void init(void)
{
    GLint numunits[1];

    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);

    makeImages();
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glGenTextures(4, texName);
    //创建两个纹理对象
    glBindTexture(GL_TEXTURE_2D, texName[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    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, GL_RGBA, imageWidth, imageHeight,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, image0);

    glBindTexture(GL_TEXTURE_2D, texName[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    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, GL_RGBA, imageWidth, imageHeight,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
    //绘制四边形作为材质
    glNewList (1, GL_COMPILE);
    glBegin(GL_QUADS);
    glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 0.0);
    glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0);
    glColor3f (0.5, 1.0, 0.25);
    glVertex3f(0.0, 0.0, 0.0);
    glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 2.0);
    glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 2.0);
    glColor3f (1.0, 1.0, 1.0);
    glVertex3f(0.0, 1.0, 0.0);
    glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 2.0);
    glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 2.0, 2.0);
    glColor3f (1.0, 1.0, 1.0);
    glVertex3f(1.0, 1.0, 0.0);
    glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 0.0);
    glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 2.0, 0.0);
    glColor3f (1.0, 0.5, 0.25);
    glVertex3f(1.0, 0.0, 0.0);
    glEnd();
    glEndList ();
}

void display(void)
{
    static GLfloat constColor[4] = {0.0, 0.0, 0.0, 0.0};

    glClear(GL_COLOR_BUFFER_BIT);

    //没有使用贴图的方形图
    glDisable(GL_TEXTURE_2D);
     /*(1,1)*/
    glPushMatrix();
    glTranslatef(0.0, 5.0, 0.0);
    glCallList(1);
    glPopMatrix();

    //启用贴图,在原图与现在纹理做调整混合模式下,分别绘制纹理对象0,1
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//调整
    /*(1,2)*/
    glPushMatrix();
    glBindTexture(GL_TEXTURE_2D, texName[0]);
    glTranslatef(1.0, 5.0, 0.0);
    glCallList(1);
    glPopMatrix();
     /*(1,3)*/
    glPushMatrix();
    glBindTexture(GL_TEXTURE_2D, texName[1]);
    glTranslatef(2.0, 5.0, 0.0);
    glCallList(1);
    glPopMatrix();

    //启动纹理组合器模式下,用纹理对象0实现的效果
    /*(2,2)*/
    glBindTexture(GL_TEXTURE_2D, texName[0]);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);//启动纹理组合器函数
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
    glPushMatrix();
    glTranslatef(1.0, 4.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(2,3)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
    glPushMatrix();
    glTranslatef(2.0, 4.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(2,4)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
    glPushMatrix();
    glTranslatef(3.0, 4.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(2,5)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
    glPushMatrix();
    glTranslatef(4.0, 4.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(2,6)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB);
    glPushMatrix();
    glTranslatef(5.0, 4.0, 0.0);
    glCallList(1);
    glPopMatrix();

    //启动纹理组合器模式下,用纹理对象0在加重颜色蓝色成分下实现的效果
    /*(3,2)*/
    constColor[3] = 0.2;
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
    glBindTexture(GL_TEXTURE_2D, texName[0]);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
    glPushMatrix();
    glTranslatef(1.0, 3.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(3,3)*/
    constColor[3] = 0.4;
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
    glPushMatrix();
    glTranslatef(2.0, 3.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(3,4)*/
    constColor[3] = 0.6;
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
    glPushMatrix();
    glTranslatef(3.0, 3.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(3,5)*/
    constColor[4] = 0.8;
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
    glPushMatrix();
    glTranslatef(4.0, 3.0, 0.0);
    glCallList(1);
    glPopMatrix();

    //多重纹理下使用纹理组合器函数
    glActiveTextureARB (GL_TEXTURE0_ARB);
    glEnable (GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texName[0]);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glActiveTextureARB (GL_TEXTURE1_ARB);
    glEnable (GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texName[1]);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
    /*(4,2)*/
    glPushMatrix();
    glTranslatef(1.0, 2.0, 0.0);
    glCallList(1);
    glPopMatrix();

    /*(4,3)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
    glPushMatrix();
    glTranslatef(2.0, 2.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(4,4)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
    glPushMatrix();
    glTranslatef(3.0, 2.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(4,5)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
    glPushMatrix();
    glTranslatef(4.0, 2.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(4,6)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB);
    glPushMatrix();
    glTranslatef(5.0, 2.0, 0.0);
    glCallList(1);
    glPopMatrix();

    //使用组合器的一些例子
     /*(5,2)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0);
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
    glPushMatrix();
    glTranslatef(1.0, 1.0, 0.0);
    glCallList(1);
    glPopMatrix();
    /*(5,3)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
    glPushMatrix();
    glTranslatef(2.0, 1.0, 0.0);
    glCallList(1);
    glPopMatrix();
    glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);

    /*  using SOURCE0 and SOURCE1, reverse the order of subtraction Arg1-Arg0  */
    /*(5,6)*/
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
    glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
    glPushMatrix();
    glTranslatef(5.0, 1.0, 0.0);
    glCallList(1);
    glPopMatrix();

    glActiveTextureARB (GL_TEXTURE1_ARB);//指定第二层纹理关闭贴图
    glDisable (GL_TEXTURE_2D);
    glActiveTextureARB (GL_TEXTURE0_ARB); //恢复为第一层,即就是没有开启多重纹理模式

    glFlush();
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 7.0, 0.0, 7.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void keyboard (unsigned char key, int x, int y)
{
    switch (key) {
        case 27:
            exit(0);
            break;
        default:
            break;
    }
}

int main(int argc, char** argv)
{
    //扩展库接口需要获得它的函数的指针后才能使用
    glActiveTextureARB   = (PFNGLACTIVETEXTUREARBPROC)glutGetProcAddress("glActiveTextureARB");
    glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glutGetProcAddress("glMultiTexCoord2fARB");

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(400, 400);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0; 
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值