声明:因网易博客将关闭,移到此
/**
这里使用到的是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,