立方体纹理贴图代码

#include "stdafx.h"
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <gl/glaux.h>
#include <stdio.h>
#include <math.h>

GLuint texture[6];
GLfloat xrot=0.0f; // X Rotation
GLfloat yrot=0.0f; // Y Rotation
GLfloat z=0.0f; // Depth Into The Screen
static GLdouble viewer[]={0.0,0.0,5.0};
char* filenames[6]={"Data/temp7.bmp","Data/temp2.bmp","Data/temp3.bmp","Data/temp4.bmp","Data/temp5.bmp","Data/temp6.bmp"};
/*
  *载入一张图片
  *返回指向图像文件的指针,发生错误返回NULL
*/
AUX_RGBImageRec *LoadBMP(char *Filename)
{
FILE *File=NULL;
if(!Filename)
return NULL;
File=fopen(Filename,"r");
if(File)
{
fclose(File);
return auxDIBImageLoad(Filename);//导入图片
}
return NULL;
}
/*
*绑定BMP贴图
*/
int LoadGLTextures()
{
int status=FALSE;         //状态变量
AUX_RGBImageRec *TextureImage[6];//为纹理贴图创建存储空间
memset(TextureImage,0,sizeof(void *)*1);  //设指针为空
    glGenTextures(6,&texture[0]);//创建纹理,将载入的图片转化成6个纹理,保存到texture中
    //载入BMP图片,并将图像数据产生纹理
for(int i=0;i<6;i++)
{
if(TextureImage[i]=LoadBMP(filenames[i]))//通过LoadBMP函数载入图像
{
status=TRUE;
            glBindTexture(GL_TEXTURE_2D,texture[i]);// 使用来自位图数据生成的典型纹理
//当纹理放大得原始的纹理大 ( GL_TEXTURE_MAG_FILTER )或缩小得比原始得纹理小( GL_TEXTURE_MIN_FILTER )时采用线性滤波方式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//生成一个2D纹理
glTexImage2D(GL_TEXTURE_2D,    //此纹理是个2D纹理
                    0,    //代表图像的详细程度,0为最基本的图像级别
3,    //颜色成分
TextureImage[i]->sizeX, //纹理的宽度
TextureImage[i]->sizeY, //纹理的高度
0,                      //边框的值,一般默认为0
GL_RGB,                 //告诉OpenGL图像数据由红、绿、蓝三色数据组成
GL_UNSIGNED_BYTE,       //组成图像的数据是无符号字节类型
TextureImage[i]->data);  //告诉OpenGL纹理数据的来源,此例中指向存放在
}
}
//释放图像资源
for(int i=0;i<6;i++)
{
if(TextureImage[i])
{
if(TextureImage[i]->data)
{
free(TextureImage[i]->data);
}
free(TextureImage[i]);
}
}
return status;


}
/*
   *对屏幕进行一些初始化设置
*/
int InitGL(GLvoid)
{
if(!LoadGLTextures())
return FALSE;
glEnable(GL_TEXTURE_2D);//启用2D纹理
glShadeModel(GL_SMOOTH);//将两点的颜色启用过度的效果
glClearColor(0.0f,0.0f,0.0f,0.0f);//清屏,使屏幕为黑色
glClearDepth(1.0f);               //设置深度缓存为1.0
    glEnable(GL_DEPTH_TEST);//启用深度测试
glDepthFunc(GL_LEQUAL);//设置所做深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //设置透视校正为最好
return TRUE;


}
/*
   *画立方体
*/
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //清除颜色缓存和深度缓存
    glPushMatrix();
//InitGL();
glLoadIdentity(); // Reset The View
gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);//设置uvn坐标系
glTranslatef(0.0f,0.0f,z);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
// Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, -2.0f,  2.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.0f, -2.0f,  2.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.0f,  2.0f,  2.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f,  2.0f,  2.0f);
glEnd();
// Back Face
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f, -2.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f,  2.0f, -2.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 2.0f,  2.0f, -2.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 2.0f, -2.0f, -2.0f);
glEnd();
// Top Face
glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f,  2.0f, -2.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f,  2.0f,  2.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.0f,  2.0f,  2.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.0f,  2.0f, -2.0f);
glEnd();
// Bottom Face
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_QUADS);
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f, -2.0f, -2.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 2.0f, -2.0f, -2.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 2.0f, -2.0f,  2.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f,  2.0f);
glEnd();
// Right face
glBindTexture(GL_TEXTURE_2D, texture[4]);
glBegin(GL_QUADS);
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.0f, -2.0f, -2.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.0f,  2.0f, -2.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 2.0f,  2.0f,  2.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 2.0f, -2.0f,  2.0f);
glEnd();
// Left Face
glBindTexture(GL_TEXTURE_2D, texture[5]);
glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.0f, -2.0f, -2.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.0f, -2.0f,  2.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.0f,  2.0f,  2.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.0f,  2.0f, -2.0f);
glEnd();


glPopMatrix();
glutSwapBuffers();
//return TRUE;
}

/*
     *窗口大小变化时使用
*/
void myReshape(int w,int h)
{
GLfloat nRange=2.0f;
//防止被0除
    if(h==0)
 h=1;
//设置屏幕视口大小,视口是OpenGL最终在屏幕上绘制图元的一个屏幕矩形区域,它被一个框架窗口所包围。
glViewport(0,0,w,h);
//告诉opengl后续的矩阵运算将施加到投影变换矩阵堆栈中
    //将三维实体最终画到屏幕上需要通过向屏幕投影变为二维实体
    //这可以通过两种投影变换实现:一个是透视投影变换,一个是平行投影变换
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//初始化投影变换矩阵为单位矩阵
//glOrtho函数指定投影变换为平行投影变换,
    //其视景体是一个长方体,位于视景体外的物体都将不出现在屏幕上
    //其六个参数指定了长方体的六个面,他将创建一个平行投影变换矩阵
    //他将与前面初始化的投影变换矩阵相乘实现平行投影变换
//要建立透视投影矩阵将调用glFrustum函数,他建立一个四棱台视景体
    //更多的是用gluPerspective来创建透视投影,它将自动建立四棱台视景体
if(w<=h)
//glFrustum(-2.0,2.0,-2.0*(GLfloat)h/(GLfloat)w,2.0*(GLfloat)h/(GLfloat)w,1.0,20.0);
glFrustum(-nRange,nRange,-nRange*(GLfloat)h/(GLfloat)w,nRange*(GLfloat)h/(GLfloat)w,1.0,nRange*10.0f);
else
//glFrustum(-2.0,2.0,-2.0*(GLfloat)w/(GLfloat)h,2.0*(GLfloat)w/(GLfloat)h,1.0,20.0);
glFrustum(-nRange,nRange,-nRange*(GLfloat)w/(GLfloat)h,nRange*(GLfloat)w/(GLfloat)h,1.0,nRange*10.0f);

//告诉opengl后续的矩阵运算将施加到模型视图矩阵堆栈中,opengl的模型坐标系和世界坐标系是重合的
    //通过乘以一些列变换矩阵,他可以对场景中的物体做一系列平移、放缩、旋转操作
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keys(unsigned char key,int x,int y)
{
//改变视点的位置
if(key=='x')
viewer[0]-=1.0;
if(key=='X')
viewer[0]+=1.0;
if(key=='y')
viewer[1]-=1.0;
if(key=='Y')
viewer[1]+=1.0;
if(key=='z')
viewer[2]-=1.0;
if(key=='Z')
viewer[2]+=1.0;

if (key=='-')
{
z-=1.0f;
}
if (key=='+')
{
z+=1.0f;
}
if (key=='8')
{
xrot-=10.0f;
}
if (key=='2')
{
xrot+=10.0f;
}
if (key=='6')
{
yrot+=10.0f;
}
if (key=='4')
{
yrot-=10.0f;
}


glutPostRedisplay();//强制glut更新当前当前窗口中的内容
}

int main(int argc,char **argv)
{
glutInit(&argc,argv);//初始化GLUT库
//初始化OpenGL窗口的GLUT库的显示模式,
    //GLUT_DOUBLE是使用图形双缓冲,GLUT_RGB指定颜色使用RGB三个分量表示,
//GLUT_DEPTH指定32bit的深度缓存,深度缓存用来对图形按其到观察者的距离的远近排序,远的先画,近的后画
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowPosition(150, 100);  //设置窗口起始位置
//设置显示窗口的初始宽度和高度的象素数
glutInitWindowSize(600,600);
//创建显示窗口
glutCreateWindow("colorcube");
InitGL();
//设置窗口的重绘回调函数,当窗口改变大小(包括第一次显示)、被遮挡后又重新出现时都需要重绘
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay); 
//设置键盘上的ASCII键点击事件的回调函数以处理ASCII键点击消息
glutKeyboardFunc(keys);
    //开启z轴方向上的深度测试机制
glEnable(GL_DEPTH_TEST);
//开始程序主循环
glutMainLoop();

return 0;

结果图:



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
若要在 OpenGL 使用立方体贴图,需要进行以下步骤: 1. 加载立方体贴图的六个面的纹理图像。 2. 创建一个立方体贴图对象,并将六个纹理图像绑定到不同的立方体贴图面上。 3. 在渲染时,使用立方体贴图坐标来获取对应的纹理颜色值。 下面是一个简单的使用 OpenGL 加载和使用立方体贴图的示例代码: ```c++ // 加载立方体贴图的六个面的纹理图像 unsigned int textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); int width, height, nrChannels; for (unsigned int i = 0; i < 6; i++) { std::string filename = "cube_" + std::to_string(i) + ".jpg"; unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); stbi_image_free(data); } else { std::cout << "Failed to load texture " << filename << std::endl; stbi_image_free(data); } } // 创建立方体贴图对象 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // 在渲染时使用立方体贴图 glUseProgram(shaderProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); glUniform1i(glGetUniformLocation(shaderProgram, "skybox"), 0); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); ``` 需要注意的是,在加载立方体贴图时,需要使用 GL_TEXTURE_CUBE_MAP_POSITIVE_X 等枚举值来指定每个面的纹理目标。在渲染时,需要将立方体贴图绑定到纹理单元上,并使用 glUniform1i 函数将纹理单元的索引传递给着色器的 uniform 变量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值