OpenGL学习笔记之加载纹理
2017-08-30 09:12
477 查看
OpenGL学习笔记之加载纹理
纹理贴图步骤
1、在主函数打开纹理贴图的开关 glEnable(GL_TEXTURE_2D); 2、加载位图文件 struct BMP { int iWidth;//图片像素宽 int iHeight;//图片像素高 char* pColor;//图片颜色首地址 BMP(int width = 0,int height = 0,char* color = NULL):iWidth(width),iHeight(height),pColor(color) { } }; BMP CGameManager::LoadBmp(const char* pFileName) { FILE* pFile;//文件指针 fopen_s(&pFile,pFileName,"rb");//打开文件名为pFileName的文件 if(pFile == NULL) std::cout<<"文件不存在!"<<std::endl; fseek(pFile,0,SEEK_END);//让文件指针偏向文件尾 int iFileLength = ftell(pFile);//得到文件的大小 rewind(pFile);//让文件指针指向文件头 pBmpFileHeader = (BITMAPFILEHEADER*)new char[iFileLength]; fread(pBmpFileHeader,1,iFileLength,pFile);//将文件读取到pBmpFileHeader指向的内存中 fclose(pFile);//关闭文件 if(pBmpFileHeader->bfType != 'MB')//如果文件的类型的不是位图文件(MB--代表位图) { delete [] pBmpFileHeader;//释放内存 return BMP(0,0,0);//返回空位图 } BMP bmp;//定义一个BMP结构体的对象bmp bmp.iWidth = ((BITMAPINFOHEADER*)(pBmpFileHeader + 1))->biWidth; bmp.iHeight = ((BITMAPINFOHEADER*)(pBmpFileHeader + 1))->biHeight; bmp.pColor = (char*)pBmpFileHeader + pBmpFileHeader->bfOffBits;//颜色的偏移量 return bmp; } 3、创建纹理 GLuint CGameManager::LoadTexture(const char* pFileName)//加载纹理 { GLuint TextureID;// glGenTextures(1,&TextureID);//在显存创建一个空间,并得到空间编号 glBindTexture(GL_TEXTURE_2D,TextureID);//将创建的空间与TextureID号绑定 BMP bmp = LoadBmp(pFileName);//加载位图 glTexParameterf(GL_TEXTURE_2D/*二维纹理*/,GL_TEXTURE_MIN_FILTER/*缩小*/,GL_LINEAR/*线性采样*/);//设置纹理参数 glTexParameterf(GL_TEXTURE_2D/*二维纹理*/,GL_TEXTURE_MAG_FILTER/*放大*/,GL_LINEAR/*线性采样*/);//设置纹理参数 //把图片处理为纹理 glTexImage2D(GL_TEXTURE_2D/*二维纹理*/,0/*表示不创建多级渐进纹理*/,GL_RGB/*RGB模式*/, bmp.iWidth/*纹理像素宽*/,bmp.iHeight/*纹理像素高*/,0/*不设置纹理边界*/, GL_BGR_EXT/*表示纹理像素的格式为B、G、R的排列*/,GL_UNSIGNED_BYTE,bmp.pColor/*纹理像素颜色的起始地址*/); return TextureID; } 4、使用纹理 void CGameManager::Darw() { glBindTexture(GL_TEXTURE_2D,TextureID);//将TextureID所绑定的纹理作为当前绘图纹理 glBegin(GL_ ea68 TRIANGLES); { glTexCoord2f(0,1);//纹理贴图坐标(使用纹理贴图坐标系) glVertex2f(g_vector2D.fX,g_vector2D.fY); glTexCoord2f(1,1); glVertex2f(g_vector2D.fX+0.4f,g_vector2D.fY); glTexCoord2f(0.5,0); glVertex2f(g_vector2D.fX+0.2f,g_vector2D.fY-0.4f); } glEnd(); }
纹理贴图坐标系
源代码
//工具#pragma once #include <gl/glew.h> #include <gl/glut.h> #include <iostream> #include <windows.h> const int ISCREENWIDTH = 650; const int ISCREENHEIGHT = 650; struct Vector2D { float fX; float fY; }; struct BMP { int iWidth; int iHeight; char* pColor; BMP(int width = 0,int height = 0,char* color = NULL):iWidth(width),iHeight(height),pColor(color) { } };
//主函数
#include "head.h" //第一个参数是命令的个数,第二个参数是命令内容 int main(int argc,char** argv) { std::cout<<argc<<std::endl;//输出命令个数 for(int i = 0; i < argc; ++i)//输出命令内容 { std::cout<<argv[i]<<std::endl; } glutInit(&argc,argv);//初始化glut库(创建窗口需要) glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//初始化显示模式 GLUT_RGBA 颜色 GLUT_DOUBLE 双缓冲 int iScreenWidth = glutGet(GLUT_SCREEN_WIDTH); int iScreenHeight = glutGet(GLUT_SCREEN_HEIGHT); glutInitWindowPosition((iScreenHeight - ISCREENWIDTH)/2,(iScreenHeight - ISCREENHEIGHT)/2 );//初始化我们创建的窗口在屏幕左上角的位置 glutInitWindowSize(ISCREENWIDTH,ISCREENHEIGHT);//初始化创建窗口的宽高 int iWindowID = glutCreateWindow("OpenGL");//创建窗口,并返回窗口的ID,传窗口的标题 glutDisplayFunc(DisplayFunc);//屏幕显示的回调函数 glutIdleFunc(IdleFunc);//闲置时回调函数(当没有消息时调用) glutKeyboardFunc(KeyboardFunc);//数字、字母键的按键检测的回调函数 glutSpecialFunc(SpecialFunc);//特殊按键检测(F1~F12,控制键) glutMouseFunc(MouseFunc);//鼠标检测 glutMotionFunc(MotionFunc);//鼠标按着拖动检测 glutPassiveMotionFunc(PassiveMotionFunc);//鼠标移动检测 glEnable(GL_LINE_STIPPLE);//开启画虚线的模式 glEnable(GL_TEXTURE_2D);//开启贴图开关 glClearColor(0.0f,0.6f,0.6f,1.0f);//指定屏幕背景色,最后参数为透明度 CGameManager::GetInstance().Init(); glutMainLoop();//消息主循环 //glutDestroyWindow(iWindowID);//销毁窗口 return 1; }
//主函数需要的函数
#include "Tool.h" #include "GameManager.h" void DisplayFunc();//显示函数 void IdleFunc();//闲置时调用的函数 void KeyboardFunc(unsigned char Key,int x,int y);//数字、字母键按键检测 void SpecialFunc(int Key,int x,int y);//F1~F12、控制键检测 void MouseFunc(int button,int state,int x,int y);//鼠标检测 void MotionFunc(int x,int y);//鼠标按着拖动 void PassiveMotionFunc(int x,int y);//鼠标移动
#include "head.h" Vector2D g_vector2D = {-0.2f,0.2f}; void DisplayFunc() { glClear(GL_COLOR_BUFFER_BIT);//用指定的颜色清屏 CGameManager::GetInstance().Darw(); glFlush();//提交绘图命令 glutSwapBuffers();//交换前台缓冲与后台缓冲(GLUT_DOUBLE双缓冲模式需要) } //闲置时调用的函数 void IdleFunc() { CGameManager::GetInstance().Run(); glutPostRedisplay();//重新绘制(即调用DisplayFunc()函数) } //数字、字母键按键检测 void KeyboardFunc(unsigned char Key,int x,int y) { CGameManager::GetInstance().KeyboardFunc(Key,x,y); } //F1~F12、控制键检测 void SpecialFunc(int Key,int x,int y) { CGameManager::GetInstance().SpecialFunc(Key,x,y); } //鼠标检测 void MouseFunc(int button,int state,int x,int y) { //button 鼠标按键 0 -- 左键 1 -- 中键 2 -- 右键 //state 鼠标状态 0 -- 按下 1 -- 抬起 //x,y 鼠标的像素点坐标(以窗口的左上角为原点的坐标系) std::cout<<"鼠标的坐标:x = "<<x<<" ,y = "<<y<<std::endl; CGameManager::GetInstance().MouseFunc(button,state,x,y); } //鼠标按着拖动 void MotionFunc(int x,int y) { //x,y 鼠标的像素点坐标(以窗口的左上角为原点的坐标系) std::cout<<"鼠标按着拖动的坐标:x = "<<x<<" ,y = "<<y<<std::endl; } //鼠标移动 void PassiveMotionFunc(int x,int y) { //x,y 鼠标的像素点坐标(以窗口的左上角为原点的坐标系) std::cout<<"鼠标移动的坐标:x = "<<x<<" ,y = "<<y<<std::endl; }
//游戏管理器
#pragma once #include "Tool.h" class CGameManager { GLuint TextureID;//纹理编号 Vector2D g_vector2D; BITMAPFILEHEADER* pBmpFileHeader;//指向位图文件的指针 CGameManager(); CGameManager(const CGameManager& that); public: static CGameManager& GetInstance(); void Init(); void Darw(); void Run(); void End(); void KeyboardFunc(unsigned char Key,int x,int y); void SpecialFunc(int Key,int x,int y); void MouseFunc(int button,int state,int x,int y); GLuint LoadTexture(const char* pFileName);//加载纹理 BMP LoadBmp(const char* pFileName);//加载位图 };
#include "GameManager.h" CGameManager::CGameManager() { } CGameManager::CGameManager(const CGameManager& that) { } CGameManager& CGameManager::GetInstance() { static CGameManager gameManager; return gameManager; } void CGameManager::Init() { TextureID = LoadTexture("Texture.bmp"); } void CGameManager::Darw() { glBindTexture(GL_TEXTURE_2D,TextureID);//将TextureID所绑定的纹理作为当前绘图纹理 glBegin(GL_TRIANGLES); { glTexCoord2f(0,1);//纹理贴图坐标(使用纹理贴图坐标系) glVertex2f(g_vector2D.fX,g_vector2D.fY); glTexCoord2f(1,1); glVertex2f(g_vector2D.fX+0.4f,g_vector2D.fY); glTexCoord2f(0.5,0); glVertex2f(g_vector2D.fX+0.2f,g_vector2D.fY-0.4f); } glEnd(); } void CGameManager::Run() { } void CGameManager::End() { } void CGameManager::KeyboardFunc(unsigned char Key,int x,int y) { if(Key == 'w' || Key == 'W') { if(g_vector2D.fY < 1.0f)//界限判定 g_vector2D.fY += 0.05f; } if(Key == 's' || Key == 'S') { if(g_vector2D.fY - 0.4f > -1.0f)//界限判定 g_vector2D.fY -= 0.05f; } if(Key == 'a' || Key == 'A') { if(g_vector2D.fX > -1.0f)//界限判定 g_vector2D.fX -= 0.05f; } if(Key == 'd' || Key == 'D') { if(g_vector2D.fX + 0.4f< 1.0f)//界限判定 g_vector2D.fX += 0.05f; } } void CGameManager::SpecialFunc(int Key,int x,int y) { if(Key == GLUT_KEY_UP) { if(g_vector2D.fY < 1.0f)//界限判定 g_vector2D.fY += 0.05f; } if(Key == GLUT_KEY_DOWN) { if(g_vector2D.fY - 0.4f > -1.0f)//界限判定 g_vector2D.fY -= 0.05f; } if(Key == GLUT_KEY_LEFT) { if(g_vector2D.fX > -1.0f)//界限判定 g_vector2D.fX -= 0.05f; } if(Key == GLUT_KEY_RIGHT) { if(g_vector2D.fX + 0.4f< 1.0f)//界限判定 g_vector2D.fX += 0.05f; } } void CGameManager::MouseFunc(int button,int state,int x,int y) { if(button == 0) { if(state == 0) { std::cout<<"鼠标左键按下"<<std::endl; } if(state == 1) { std::cout<<"鼠标左键抬起"<<std::endl; } } if(button == 1) { if(state == 0) { std::cout<<"鼠标中键按下"<<std::endl; } if(state == 1) { std::cout<<"鼠标中键抬起"<<std::endl; } } if(button == 2) { if(state == 0) { std::cout<<"鼠标右键按下"<<std::endl; } if(state == 1) { std::cout<<"鼠标右键抬起"<<std::endl; } } } GLuint CGameManager::LoadTexture(const char* pFileName)//加载纹理 { GLuint TextureID;// glGenTextures(1,&TextureID);//在显存创建一个空间,并得到空间编号 glBindTexture(GL_TEXTURE_2D,TextureID);//将创建的空间与TextureID号绑定 BMP bmp = LoadBmp(pFileName);//加载位图 glTexParameterf(GL_TEXTURE_2D/*二维纹理*/,GL_TEXTURE_MIN_FILTER/*缩小*/,GL_LINEAR/*线性采样*/);//设置纹理参数 glTexParameterf(GL_TEXTURE_2D/*二维纹理*/,GL_TEXTURE_MAG_FILTER/*放大*/,GL_LINEAR/*线性采样*/);//设置纹理参数 //把图片处理为纹理 glTexImage2D(GL_TEXTURE_2D/*二维纹理*/,0/*表示不创建多级渐进纹理*/,GL_RGB/*RGB模式*/, bmp.iWidth/*纹理像素宽*/,bmp.iHeight/*纹理像素高*/,0/*不设置纹理边界*/, GL_BGR_EXT/*表示纹理像素的格式为B、G、R的排列*/,GL_UNSIGNED_BYTE,bmp.pColor/*纹理像素颜色的起始地址*/); return TextureID; } BMP CGameManager::LoadBmp(const char* pFileName) { FILE* pFile;//文件指针 fopen_s(&pFile,pFileName,"rb");//打开文件名为pFileName的文件 if(pFile == NULL) std::cout<<"文件不存在!"<<std::endl; fseek(pFile,0,SEEK_END);//让文件指针偏向文件尾 int iFileLength = ftell(pFile);//得到文件的大小 rewind(pFile);//让文件指针指向文件头 pBmpFileHeader = (BITMAPFILEHEADER*)new char[iFileLength]; fread(pBmpFileHeader,1,iFileLength,pFile);//将文件读取到pBmpFileHeader指向的内存中 fclose(pFile);//关闭文件 if(pBmpFileHeader->bfType != 'MB')//如果文件的类型的不是位图文件(MB--代表位图) { delete [] pBmpFileHeader;//释放内存 return BMP(0,0,0);//返回空位图 } BMP bmp;//定义一个BMP结构体的对象bmp bmp.iWidth = ((BITMAPINFOHEADER*)(pBmpFileHeader + 1))->biWidth; bmp.iHeight = ((BITMAPINFOHEADER*)(pBmpFileHeader + 1))->biHeight; bmp.pColor = (char*)pBmpFileHeader + pBmpFileHeader->bfOffBits;//颜色的偏移量 return bmp; }
//运行效果
相关文章推荐
- OpenGL学习笔记-2015.4.1——纹理加载与控制
- OpenGL学习笔记 (6) —— 纹理映射
- OpenGL学习笔记6:高级纹理知识
- OPENGL学习笔记整理(二):纹理知多少?
- OpenGL学习笔记之纹理贴图
- OpenGL_Qt学习笔记之_06(纹理滤波、光照和色彩融合)
- LearnOpenGL学习笔记4:纹理
- OpenGL学习笔记6:高级纹理知识
- opengl编程学习笔记(四)(纹理映射)(结合nvdia OpenglSDk 的nvimage类)
- LearnOpenGL学习笔记4:纹理
- OpenGL学习笔记(十二):纹理的使用
- openGL之纹理贴图---openGL学习笔记(十三)
- OpenGL学习笔记4:纹理
- OpenGL学习笔记——纹理贴图
- opengl学习笔记——纹理贴图
- OpenGL 学习笔记-2015.4.18——立方体纹理映射-天空盒子-环境映射
- OpenGL学习笔记:纹理
- OpenGL学习笔记——纹理贴图
- OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结
- OpenGL学习笔记4:纹理