[迁移]opengl学习从头开始(笔记17 多重纹理 凹凸映射)

声明:因网易博客将关闭,移到此

/**
    这里使用到的是opengl 和 glut 进行编写学习的笔记,一个简单的出口
    使用到的开发库有 linux (gl glu glut) windows(opengl32.lib glu32.lib glut32.lib)

    实现: 多重纹理,凹凸映射
        
        看完代码应该意识到
        g_texture 是图片Base.bmp加载进来的纹理
        g_bump      是图片 Bump.bmp加载进来的纹理 r g b 为 原来的50%
        g_invbmp  是通过 Bump.bmp 的每个像素 255 减获得的

    原理
        浮雕就是计算灯光和面法线之间的偏向获取纹理偏差,之后g_bump和g_invbump的纹理进行偏移
        之后在进行混合绘制
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        // 这个函数也是一个关键的点,自己网络上搜索下是如何使用的吧
        //
        //
        这里使用的两种方式:
        1 不使用多重纹理实现
        2 使用多重纹理实现

    例子:这里需要检测你的显卡是否支持GL_ARB_multitexture-support
        它的作用是使你可以同时吧2个以上的不同纹理映射到opengl图元上
        
        关键的几个函数,在里面进行小小的改动会出现一些不一样的东西^_^
        setupbumps 这个是计算纹理的偏离量的
        vmatmult 这个是把灯光的位置转换到对象坐标系中

        键盘事件:
            k 是否给浮雕贴上贴图
            l 使用那种浮雕 这里有2中浮雕实现方式
            h 切换是否使用浮雕效果
            j 这个是用于切换查看3个纹理 g_texture g_bump g_invbump
                是什么样子的

    题外:
        opengl的矩阵格式
            0 4 8 12
            1 5 9 13
            2 6 10 14
            3 7 11 15
        
    问题:

        

*/

#include <iostream>
#include <GL/glut.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#ifdef _MSC_VER

#endif

#ifdef __GNUC__
#include <unistd.h>
#endif

using namespace std;

#define MAX_EMBOSS (GLfloat)0.01f // 突起最大值
#define MAX_EXTENSION_SPACE 10240 // 扩展字符串字符
#define MAX_EXTENSION_LENGHT 256 //  一个扩展的最大字符长度

bool g_emboss = false;        // 这个是允许浮雕效果,还是使用颜色
bool g_bumps=true;            // 开启凹凸纹理
bool g_multitextureSupported = false;    // 判断是否支持我们要的扩展
bool g_useMultitexture = true;            // 是否使用扩展

GLint g_maxTexelUnits = 1;        //;

GLfloat    xrot = 0.0f;        // X Rotation
GLfloat    yrot = 0.0f;        // Y Rotation
GLfloat xspeed = 0.1f;        // X Rotation Speed
GLfloat yspeed    = 0.1f;        // Y Rotation Speed
GLfloat    z=-5.0f;

// 1 使用 g_texture 2 使用g_bump 3 使用 g_invbump
GLuint g_drawType = 0;        // 这里使用绘制的方式,

GLuint g_texture;    // 存储3张纹理
GLuint g_bump;        // 3张凹凸纹理
GLuint g_invbump;        // 凹纹理

GLuint g_glLogo;    // opengl logo
GLuint g_multiLogo;

GLfloat g_LightAmbient[] = {0.2f, 0.2f, 0.2f};    // 环境光
GLfloat g_LightDiffuse[] = {1.0f, 1.0f, 1.0f};    // 漫反射
GLfloat g_LightPosition[] = {0.0f, 0.0f, 2.0f};

GLfloat g_Gray[] = { 0.5f, 0.5f, 0.5f, 1.0f};

// 下面的数据存储的是立方体的面,格式是2个纹理定点,3个坐标
//
GLfloat g_data[] = {
    // front
    0.0f, 0.0f,        -1.0f, -1.0f,  1.0f,
    1.0f, 0.0f,        +1.0f, -1.0f,  1.0f,
    1.0f, 1.0f,        +1.0f,  1.0f,  1.0f,
    0.0f, 1.0f,        -1.0f,  1.0f,  1.0f,
    // back
    1.0f, 0.0f,        -1.0f, -1.0f, -1.0f,
    1.0f, 1.0f,        -1.0f,  1.0f, -1.0f,
    0.0f, 1.0f,         1.0f,  1.0f, -1.0f,
    0.0f, 0.0f,         1.0f, -1.0f, -1.0f,
    // top
    0.0f, 1.0f,        -1.0f,  1.0f, -1.0f,
    0.0f, 0.0f,        -1.0f,  1.0f,  1.0f,
    1.0f, 0.0f,         1.0f,  1.0f,  1.0f,
    1.0f, 1.0f,         1.0f, +1.0f, -1.0f,
    // bottom
    1.0f, 1.0f,        -1.0f, -1.0f, -1.0f,
    0.0f, 1.0f,         1.0f, -1.0f, -1.0f,
    0.0f, 0.0f,         1.0f, -1.0f, 1.0f,
    1.0f, 0.0f,        -1.0f, -1.0f, 1.0f,
    // right
    1.0f,0.0f,        1.0f, -1.0f, -1.0f,
    1.0f, 1.0f,        1.0f,  1.0f, -1.0f,
    0.0f, 1.0f,        1.0f,  1.0f,  1.0f,
    0.0f, 0.0f,        1.0f, -1.0f,  1.0f,
    // left
    0.0f, 0.0f,        -1.0f, -1.0f, -1.0f,
    1.0f, 0.0f,        -1.0f, -1.0f,  1.0f,
    1.0f, 1.0f,        -1.0f,  1.0f,  1.0f,
    0.0f, 1.0f,        -1.0f,  1.0f, -1.0f
};

// 看到一个扩展是否在字符串中
bool isInString(char *string, const char *search)
{
    int pos = 0;
    int maxpos = strlen(search) - 1;
    int len = strlen(string);
    char *other;
    for (int i = 0; i < len; i++)
    {
        if ((i == 0) || ((i > 1) && string[i-1] == '\n'))
        {
            other = &string[i];
            pos = 0;
            while (string[i] != '\n')
            {
                if (string[i] == search[pos]) pos++;
                if ((pos > maxpos) && string[i+1] == '\n') return true;
                i++;
            }

        }
    }
    return false;
}

// 初始化多重纹理
// 判断是否支持我们需要的扩展
bool initMultitexture(void)
{
    char *extensions = strdup((char*)glGetString(GL_EXTENSIONS));
    int len = strlen(extensions);
    for (int i = 0; i < len; i++)
        if (extensions[i] == ' ') extensions[i] = '\n';

#ifdef EXT_INFO
        cout<<"supported GL extensions:\n"<<extensions<<endl;
#endif
        if (isInString(extensions, "GL_ARB_mutitexture")
                && true
                && isInString(extensions, "GL_EXT_texture_env_combine"))
        {
            glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&g_maxTexelUnits);
            cout<<"maxTexelUnits:"<<g_maxTexelUnits<<endl;
#ifdef EXT_INFO
            cout<<"the GL_ARB_multitexture extension will be used."<<endl;
#endif
            return true;
        }

    g_useMultitexture = false;
    return false;
}

// 初始化
void initLight(void)
{
    glLightfv(GL_LIGHT1, GL_AMBIENT, g_LightAmbient);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, g_LightDiffuse);
    glLightfv(GL_LIGHT1, GL_POSITION, g_LightPosition);

    glEnable(GL_LIGHT1);
}



// 图片的类型 包含宽 高 数据
struct Image
{
    unsigned long sizeX;
    unsigned long sizeY;
    char *data;
};
typedef struct Image Image;

// 我们用来旋转下模型吧
float g_angle = 0;


// 下面是读取自定义格式的模型信息文件使用的函数


//----------------------------------------------------------
// 读取图片文件
int ImageLoad(const char *filename, Image *image)
{
    FILE *file;
    unsigned long size; // 图片长度
    unsigned long i;    // 计数
    unsigned short int planes;
    unsigned short int bpp;
    char temp;            // bgr -rgb 变换

    if ((file = fopen(filename, "rb")) == NULL)
    {
        printf("File Not Found: %s\n", filename);
        return 0;
    }

    // 跳过文件的头部,准备读取宽度和高度
    // 如果想自己具体的情况可以去看看bmp图片的相关信息
    fseek(file, 18, SEEK_CUR);

    // 读取宽度
    if ((i = fread(&image->sizeX, 4, 1, file)) != 1)
    {
        printf("Error reading width from %s. \n", filename);
        return 0;
    }
    printf("Width of %s: %lu\n", filename, image->sizeX);
    
    // 读取宽度
    if ((i = fread(&image->sizeY, 4, 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值