📄 纹理处理加键盘操作.txt
字号:
#include <windows.h> // Windows的头文件
#include <gl\gl.h> // OpenGL32库的头文件
#include <gl\glu.h> // GLu32库的头文件
#include <gl\glaux.h> // GLaux库的头文件
#include <stdio.h> // 标准输入/输出库的头文件
HGLRC hRC=NULL;
// 永久着色描述表
HDC hDC=NULL;
// 私有GDI设备描述表
HWND hWnd=NULL;
// 保存我们的窗口句柄
HINSTANCE hInstance;
// 保存程序的实例
bool keys[256];
// 用于键盘例程的数组
bool active=TRUE;
// 窗口的活动标志,缺省为TRUE
bool fullscreen=TRUE;
// 全屏标志缺省设定成全屏模式
BOOL light;
// 光源的开/关
BOOL lp;
// L键按下了么?
BOOL fp;
// F键按下了么?
GLfloat xrot;
// X 旋转
GLfloat yrot;
// Y 旋转
GLfloat xspeed;
// X 旋转速度
GLfloat yspeed;
// Y 旋转速度
GLfloat z=-5.0f;
// 深入屏幕的距离
GLfloat LightAmbient[]=
{
0.5f, 0.5f, 0.5f, 1.0f
};
//环境光参数 ( 新增 )
GLfloat LightDiffuse[]=
{
1.0f, 1.0f, 1.0f, 1.0f
};
// 漫射光参数 ( 新增 )
GLfloat LightPosition[]=
{
0.0f, 0.0f, 2.0f, 1.0f
};
// 光源位置 ( 新增 )
GLuint filter;
// 滤波类型
GLuint texture[3];
// 3种纹理的储存空间
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// WndProc定义
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// WndProc的定义
AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图图象
{
FILE *File=NULL;
// 文件句柄
if (!Filename) // 确保文件名已提供。
{
return NULL;
// 如果没提供,返回 NULL
}
File=fopen(Filename,"r");
//尝试打开文件
if (File) // 文件存在么?
{
fclose(File);
// 关闭句柄
return auxDIBImageLoad(Filename);
//载入位图并返回指针
}
return NULL;
// 如果载入失败,返回 NULL
}
int LoadGLTextures() // 载入位图并转换成纹理
{
int Status=FALSE;
// Status 指示器
AUX_RGBImageRec *TextureImage[1];
// 创建纹理的存储空间
memset(TextureImage,0,sizeof(void *)*1);
// 将指针设为 NULL
// 载入位图,检查有错,或位图不存在的话退出。
if (TextureImage[0]=LoadBMP("Data/picture1.bmp"))
{
Status=TRUE;
// Status 设为 TRUE
glGenTextures(3, &texture[0]);
// 创建纹理
// 创建 Nearest 滤波贴图
glBindTexture(GL_TEXTURE_2D, texture[0]);
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, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
// 创建线性滤波纹理
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
// 创建 MipMapped 纹理
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
// ( 新增 )
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
if (TextureImage[0]) // 纹理是否存在
{
if (TextureImage[0]->data) // 纹理图像是否存在
{
free(TextureImage[0]->data);
// 释放纹理图像占用的内存
}
free(TextureImage[0]);
// 释放图像结构
}
return Status;
// 返回 Status 变量
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置并初始化GL窗口大小
{
if (height==0) // 防止被零除
{
height=1;
// 将Height设为1
}
glViewport(0, 0, width, height);
// 重置当前的视口(Viewport)
glMatrixMode(GL_PROJECTION);
// 选择投影矩阵
glLoadIdentity();
// 重置投影矩阵
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
// 选择模型观察矩阵
glLoadIdentity();
// 重置模型观察矩阵
}
int InitGL(GLvoid) // 此处开始对OpenGL进行所有设置
{
if (!LoadGLTextures()) // 跳转到纹理载入例程
{
return FALSE;
// 如果不能载入纹理返回 FALSE
}
glEnable(GL_TEXTURE_2D);
// 启用纹理映射
glShadeModel(GL_SMOOTH);
// 启用阴影平滑
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// 黑色背景
glClearDepth(1.0f);
// 深度缓存设置
glEnable(GL_DEPTH_TEST);
// 启用深度测试
glDepthFunc(GL_LEQUAL);
// 所作的深度测试类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// 高度优化的透视投影计算
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
// 设置环境光
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
// 设置漫射光
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
// 光源位置
glEnable(GL_LIGHT1);
// 启用一号光源
return TRUE;
// 初始化 OK
}
GLvoid KillGLWindow(GLvoid)
{
// 正常销毁窗口
if (fullscreen)
{
// 我们处于全屏模式吗?
ChangeDisplaySettings(NULL,0);
// 是的话,切换回桌面
ShowCursor(TRUE);
// 显示鼠标指针
}
if (hRC)
{
// 我们拥有着色描述表吗?
if (!wglMakeCurrent(NULL,NULL))
{
// 我们能否释放DC和RC描述表?
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC))
{
// 我们能否删除RC?
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL;
// 将RC设为 NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // 我们能否释放 DC?
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL;
// 将 DC 设为 NULL
}
if (hWnd && !DestroyWindow(hWnd)) // 能否销毁窗口?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL;
// 将 hWnd 设为 NULL
}
if (!UnregisterClass("OpenGL",hInstance)) // 能否注销类?
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL;
// 将 hInstance 设为 NULL
}
}
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat;
// 保存查找匹配的结果
WNDCLASS wc;
// 窗口类结构
DWORD dwExStyle;
// 扩展窗口风格
DWORD dwStyle;
// 窗口风格
RECT WindowRect;
// 取得矩形的左上角和右下角的坐标值
WindowRect.left=(long)0;
// 将Left 设为 0
WindowRect.right=(long)width;
// 将Right 设为要求的宽度
WindowRect.top=(long)0;
// 将Top 设为 0
WindowRect.bottom=(long)height;
// 将Bottom 设为要求的高度
fullscreen=fullscreenflag;
// 设置全局全屏标志
hInstance = GetModuleHandle(NULL);
// 取得我们窗口的实例
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
// 移动时重画,并为窗口取得DC
wc.lpfnWndProc = (WNDPROC) WndProc;
// WndProc处理消息
wc.cbClsExtra = 0;
// 无额外窗口数据
wc.cbWndExtra = 0;
// 无额外窗口数据
wc.hInstance = hInstance;
// 设置实例
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
// 装入缺省图标
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// 装入鼠标指针
wc.hbrBackground = NULL;
// GL不需要背景
wc.lpszMenuName = NULL;
// 不需要菜单
wc.lpszClassName = "OpenGL";
// 设定类名字
if (!RegisterClass(&wc)) // 尝试注册窗口类
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
//退出并返回FALSE
}
if (fullscreen)
{
// 要尝试全屏模式吗?
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
// 设备模式
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
// 确保内存分配
dmScreenSettings.dmPelsWidth = width;
// Devmode 结构的大小
dmScreenSettings.dmPelsHeight = height;
// 所选屏幕宽度
dmScreenSettings.dmBitsPerPel = bits;
// 所选屏幕高度
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// 每象素所选的色彩深度
// 尝试设置显示模式并返回结果?注: CDS_FULLSCREEN 移去了状态条?
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// 若模式失败,提供两个选项:退出或在窗口内运行?
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE;
// 选择窗口模式(Fullscreen=FALSE)
}
else
{
// 弹出消息窗口告知用户程序将结束?并返回FALSE告诉程序窗口未能成功创建?程序退出
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE;
//退出并返回 FALSE
}
}
}
if (fullscreen)// 仍处于全屏模式吗?
{
dwExStyle=WS_EX_APPWINDOW;
// 扩展窗体风格
dwStyle=WS_POPUP;
// 窗体风格
ShowCursor(FALSE);
// 隐藏鼠标指针
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
// 扩展窗体风格
dwStyle=WS_OVERLAPPEDWINDOW;
// 窗体风格
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
// 调整窗口达到真正要求的大小
if (!(hWnd=CreateWindowEx( dwExStyle,// 扩展窗体风格
"OpenGL", // 类名字
title, // 窗口标题
WS_CLIPSIBLINGS | // 必须的窗体风格属性
WS_CLIPCHILDREN | // 必须的窗体风格属性
dwStyle, // 选择的窗体属性
0, 0, // 窗口位置
WindowRect.right-WindowRect.left, // 计算调整好的窗口宽度
WindowRect.bottom-WindowRect.top, // 计算调整好的窗口高度
NULL, // 无父窗口
NULL, // 无菜单
hInstance, // 实例
NULL))) // 不向WM_CREATE传递任何东东
{
KillGLWindow();
// 重置显示区
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
// 返回 FALSE
}
static PIXELFORMATDESCRIPTOR pfd= //pfd 告诉窗口我们所希望的东东
{
sizeof(PIXELFORMATDESCRIPTOR), //上诉格式描述符的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 格式必须支持窗口
PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL
PFD_DOUBLEBUFFER, // 必须支持双缓冲
PFD_TYPE_RGBA, // 申请 RGBA 格式
bits, // 选定色彩深度
0, 0, 0, 0, 0, 0, // 忽略的色彩位
0, // 无Alpha缓存
0, // 忽略Shift Bit
0, // 无聚集缓存
0, 0, 0, 0, // 忽略聚集位
16, // 16位 Z-缓存 (深度缓存)
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主绘图层
0, // 保留
0, 0, 0 // 忽略层遮罩
};
if (!(hDC=GetDC(hWnd))) //取得设备描述表了么?
{
KillGLWindow();
// 重置显示区
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
// 返回 FALSE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -