#include <windows.h> // Windows的头文件
#include <glew.h> // 包含最新的gl.h,glu.h库
#include <glut.h> // 包含OpenGL实用库
#include <stdio.h>       // 标准输入/输出库的头文件
#include <glaux.h>       // GLaux库的头文件HGLRC hRC = NULL; // 窗口着色描述表句柄
HDC hDC = NULL; // OpenGL渲染描述表句柄
HWND hWnd = NULL; // 保存我们的窗口句柄
HINSTANCE hInstance; // 保存程序的实例bool keys[256]; // 保存键盘按键的数组
bool active = TRUE; // 窗口的活动标志,缺省为TRUE
bool fullscreen = TRUE; // 全屏标志缺省,缺省设定成全屏模式LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // WndProc的定义GLfloat xrot;         // X 旋转
GLfloat yrot;         // Y 旋转
GLfloat xspeed = 0.0f;         // X 旋转速度
GLfloat yspeed = 0.0f;         // Y 旋转速度GLfloat z=-5.0f;        // 深入屏幕的距离GLuint  texture[3];       // 存储一个纹理BOOL light;         // 光源的开/关
BOOL lp;         // L键按下了么?
BOOL fp;         // F键按下了么?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;         // 滤波类型GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{  // 防止被零除  if (height==0)                {  height=1;   // 将Height设为1         }  // 重置当前的视口  glViewport(0, 0, width, height);  glMatrixMode(GL_PROJECTION);// 选择投影矩阵  glLoadIdentity();// 重置投影矩阵  // 设置视口的大小  gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);  glMatrixMode(GL_MODELVIEW);// 选择模型观察矩阵  glLoadIdentity();// 重置模型观察矩阵
}  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;       // 状态指示器AUX_RGBImageRec *TextureImage[1];     // 创建纹理的存储空间memset(TextureImage,0,sizeof(void *)*1);    // 将指针设为 NULL// 载入位图,检查有无错误,如果位图没找到则退出if (TextureImage[0]=LoadBMP("bitmap1.bmp")){Status=TRUE;       // 将 Status 设为 TRUE// 创建 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
}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
}int DrawGLScene(GLvoid)        // 从这里开始进行所有的绘制
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   // 清除屏幕和深度缓存glLoadIdentity();       // 重置当前的模型观察矩阵glTranslatef(0.0f,0.0f,z);      // 移入/移出屏幕 z 个单位glRotatef(xrot,1.0f,0.0f,0.0f);      // 绕X轴旋转glRotatef(yrot,0.0f,1.0f,0.0f);      // 绕Y轴旋转glBindTexture(GL_TEXTURE_2D, texture[filter]);    // 选择由filter决定的纹理glBegin(GL_QUADS);       // 开始绘制四边形// 前侧面glNormal3f( 0.0f, 0.0f, 1.0f);     // 法线指向观察者glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); // 后侧面glNormal3f( 0.0f, 0.0f,-1.0f);     // 法线背向观察者glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 顶面glNormal3f( 0.0f, 1.0f, 0.0f);     // 法线向上glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); // 底面glNormal3f( 0.0f,-1.0f, 0.0f);     // 法线朝下glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); // 右侧面glNormal3f( 1.0f, 0.0f, 0.0f);     // 法线朝右glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); // 左侧面glNormal3f(-1.0f, 0.0f, 0.0f);     // 法线朝左glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); glEnd();        // 四边形绘制结束xrot+=xspeed;        // xrot 增加 xspeed 单位yrot+=yspeed;        // yrot 增加 yspeed 单位return TRUE;
}GLvoid KillGLWindow(GLvoid) {  // 正常销毁窗口if (fullscreen) {          // 我们处于全屏模式吗?ChangeDisplaySettings(NULL, 0);// 是的话,切换回桌面ShowCursor(TRUE); // 显示鼠标指针}if (hRC) {                   // 我们拥有OpenGL渲染描述表吗?if (!wglMakeCurrent(NULL, NULL)) {      // 我们能否释放DC和RC描述表?MessageBox(NULL, "释放DC或RC失败", "关闭错误", MB_OK | MB_ICONINFORMATION);}if (!wglDeleteContext(hRC)) {MessageBox(NULL, "释放RC失败。", "关闭错误", MB_OK | MB_ICONINFORMATION);}hRC = NULL;}if (hDC && !ReleaseDC(hWnd, hDC)) // 我们能否释放 DC?{MessageBox(NULL, "释放DC失败。", "关闭错误", MB_OK | MB_ICONINFORMATION);hDC = NULL; // 将 DC 设为 NULL}if (hWnd && !DestroyWindow(hWnd)) // 能否销毁窗口?{MessageBox(NULL, "释放窗口句柄失败。", "关闭错误", MB_OK |MB_ICONINFORMATION);hWnd = NULL; // 将 hWnd 设为 NULL}if (!UnregisterClass("OpenG", hInstance)) // 能否注销类?{MessageBox(NULL, "不能注销窗口类。", "关闭错误", MB_OK | MB_ICONINFORMATION);hInstance = NULL; // 将 hInstance 设为 NULL}
}// 创建OpenGL窗口
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 设为 0WindowRect.right = (long)width; // 将Right 设为要求的宽度WindowRect.top = (long)0; // 将Top 设为 0WindowRect.bottom = (long)height; // 将Bottom 设为要求的高度fullscreen = fullscreenflag;hInstance = GetModuleHandle(NULL);  //取得窗口实例wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; //移动时重画并取得窗口DCwc.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 = "OpenG"; // 设定类名字if (!RegisterClass(&wc)) // 尝试注册窗口类{MessageBox(NULL, "注册窗口失败", "错误", MB_OK | MB_ICONEXCLAMATION);return FALSE; // 退出并返回FALSE}if (fullscreen) // 要尝试全屏模式吗?{DEVMODE dmScreenSettings; // 设备模式memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // 确保内存清空为零dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Devmode 结构的大小dmScreenSettings.dmPelsWidth = width; // 所选屏幕宽度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, "全屏模式在当前显卡上设置失败!\n使用窗口模式?", "NeHe G",MB_YESNO | MB_ICONEXCLAMATION) == IDYES){fullscreen = FALSE; // 选择窗口模式(Fullscreen=FALSE)}else{// 弹出一个对话框,告诉用户程序结束MessageBox(NULL, "程序将被关闭", "错误", 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, // 扩展窗体风格"OpenG", // 类名字(LPTSTR)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, "不能创建一个窗口设备描述表", "错误", MB_OK |MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}static PIXELFORMATDESCRIPTOR pfd = // /pfd 告诉窗口我们所希望的东       东,即窗口使用的像素格式{sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小1, // 版本号PFD_DRAW_TO_WINDOW | // 格式支持窗口PFD_SUPPORT_OPENGL | // 格式必须支持OpenGLPFD_DOUBLEBUFFER, // 必须支持双缓冲PFD_TYPE_RGBA, // 申请 RGBA 格式bits, // 选定色彩深度0, 0, 0, 0, 0, 0, // 忽略的色彩位0, // 无Alpha缓存0, // 忽略Shift Bit0, // 无累加缓存0, 0, 0, 0, // 忽略聚集位16, // 16位 Z-缓存 (深度缓存)0, // 无蒙板缓存0, // 无辅助缓存PFD_MAIN_PLANE, // 主绘图层0, // Reserved0, 0, 0 // 忽略层遮罩};if (!(hDC = GetDC(hWnd))) // 取得设备描述表了么?{KillGLWindow(); // 重置显示区MessageBox(NULL, "不能创建一种相匹配的像素格式", "错误", MB_OK |MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // Windows 找到相应的象素格式了{KillGLWindow(); // 重置显示区MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // Windows 找到相应的象素格式了吗 ?{KillGLWindow(); // 重置显示区MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // 能够设置象素格式么?{KillGLWindow(); // 重置显示区MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}if (!(hRC = wglCreateContext(hDC))) // 能否取得着色描述表?{KillGLWindow(); // 重置显示区MessageBox(NULL, "不能创建OpenGL渲染描述表", "错误", MB_OK |MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}if (!wglMakeCurrent(hDC, hRC)) // 尝试激活着色描述表{KillGLWindow(); // 重置显示区MessageBox(NULL, "不能激活当前的OpenGL渲然描述表", "错误", MB_OK |MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}ShowWindow(hWnd, SW_SHOW); // 显示窗口SetForegroundWindow(hWnd); // 略略提高优先级SetFocus(hWnd); // 设置键盘的焦点至此窗口ReSizeGLScene(width, height); // 设置透视 GL 屏幕if (!InitGL()) // 初始化新建的GL窗口{KillGLWindow(); // 重置显示区MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);return FALSE; // 返回 FALSE}return TRUE; // 成功
}LRESULT CALLBACK WndProc(HWND hWnd, // 窗口的句柄UINT uMsg, // 窗口的消息WPARAM wParam, // 附加的消息内容LPARAM lParam) // 附加的消息内容
{switch (uMsg) // 检查Windows消息{case WM_ACTIVATE: // 监视窗口激活消息{if (!HIWORD(wParam)) // 检查最小化状态{active = TRUE; // 程序处于激活状态}else{active = FALSE; // 程序不再激活}return 0; // 返回消息循环}case WM_SYSCOMMAND: // 系统中断命令{switch (wParam) // 检查系统调用{case SC_SCREENSAVE: // 屏保要运行?case SC_MONITORPOWER: // 显示器要进入节电模式?return 0; // 阻止发生}break; // 退出}case WM_CLOSE: // 收到Close消息?{PostQuitMessage(0); // 发出退出消息return 0; // 返回}case WM_KEYDOWN: // 有键按下么?{keys[wParam] = TRUE; // 如果是,设为TRUEreturn 0; // 返回}case WM_KEYUP: // 有键放开么?{keys[wParam] = FALSE; // 如果是,设为FALSEreturn 0; // 返回}case WM_SIZE: // 调整OpenGL窗口大小{ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord=Width,HiWord = Heightreturn 0; // 返回}}// 向 DefWindowProc传递所有未处理的消息。return DefWindowProc(hWnd, uMsg, wParam, lParam);
}int WINAPI WinMain(HINSTANCE hInstance, // 当前窗口实例HINSTANCE hPrevInstance, // 前一个窗口实例LPSTR lpCmdLine, // 命令行参数int nCmdShow) // 窗口显示状态
{MSG msg; // Windowsx消息结构BOOL done = FALSE; // 用来退出循环的Bool 变量// 提示用户选择运行模式if (MessageBox(NULL, "你想在全屏模式下运行么?", "设置全屏模式", MB_YESNO |MB_ICONQUESTION) == IDNO){fullscreen = FALSE; // FALSE为窗口模式}// 创建OpenGL窗口if (!CreateGLWindow("NeHe's OpenGL程序框架", 640, 480, 16, fullscreen)){return 0; // 失败退出}while (!done) // 保持循环直到 done=TRUE{if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // 有消息在等待吗?{if (msg.message == WM_QUIT) // 收到退出消息?{done = TRUE; // 是,则done=TRUE}else // 不是,处理窗口消息{TranslateMessage(&msg); // 翻译消息DispatchMessage(&msg); // 发送消息}}else // 如果没有消息{// 绘制场景。监视ESC键和来自DrawGLScene()的退出消息if (active) // 程序激活的么?{if (keys[VK_ESCAPE]) // ESC 按下了么?{done = TRUE; // ESC 发出退出信号}else // 不是退出的时候,刷新屏幕{DrawGLScene(); // 绘制场景SwapBuffers(hDC);    // 交换缓存if (keys['L'] && !lp)    // L 键已按下并且松开了?{lp=TRUE;    // lp 设为 TRUElight=!light;    // 切换光源的 TRUE/FALSEif (!light)    // 如果没有光源{glDisable(GL_LIGHTING);  // 禁用光源}else     // 否则{glEnable(GL_LIGHTING);  // 启用光源}}if (!keys['L'])     // L键松开了么?{lp=FALSE;    // 若是,则将lp设为FALSE}if (keys['F'] && !fp)    // F键按下了么?{fp=TRUE;    // fp 设为 TRUEfilter+=1;    // filter的值加一if (filter>2)    // 大于2了么?{filter=0;   // 若是重置为0}printf("%d\n",filter);}if (!keys['F'])     // F键放开了么?{fp=FALSE;    // 若是fp设为FALSE}if (keys[VK_PRIOR])    // PageUp按下了?{z-=0.02f;    // 若按下,将木箱移向屏幕内部}if (keys[VK_NEXT])    // PageDown按下了么{z+=0.02f;    // 若按下的话,将木箱移向观察者}if (keys[VK_UP])    // Up方向键按下了么?{xspeed-=0.001f;    // 若是,减少xspeed}if (keys[VK_DOWN])    // Down方向键按下了么?{xspeed+=0.001f;    // 若是,增加xspeed}if (keys[VK_RIGHT])    // Right方向键按下了么?{yspeed+=0.001f;    // 若是,增加yspeed}if (keys[VK_LEFT])    // Left方向键按下了么?{yspeed-=0.001f;    // 若是, 减少yspeed}}}if (keys[VK_F1]) // F1键按下了么?{keys[VK_F1] = FALSE; // 若是,使对应的Key数组中的值为 FALSEKillGLWindow(); // 销毁当前的窗口fullscreen = !fullscreen; // 切换 全屏 / 窗口 模式// 重建 OpenGL 窗if (!CreateGLWindow("NeHe's OpenGL 程序框架", 640, 480, 16, fullscreen)){return 0; // 如果窗口未能创建,程序退出}}}}// 关闭程序KillGLWindow(); // 销毁窗口return (msg.wParam); // 退出程序
}

NeHe OpenGL教程 第七课:光照和键盘 代码相关推荐

  1. NeHe OpenGL教程 第十课:3D世界

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. NeHe OpenGL教程 第二十三课:球面映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. NeHe OpenGL教程 第二十一课:线的游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. NeHe OpenGL教程 第四课:旋转

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. NeHe OpenGL教程 第二十六课:反射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. NeHe OpenGL教程 第十五课:纹理图形字

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. NeHe OpenGL教程 第四十课:绳子的模拟

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. NeHe OpenGL教程 第四十七课:CG顶点脚本

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. NeHe OpenGL教程 第三十六课:从渲染到纹理

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

最新文章

  1. 妙用Java 8中的 Function接口 消灭if...else(非常新颖的写法)
  2. win10下使用certutil工具对文件的SHA1、MD5和SHA256哈希结果做验证(超简单,附图)
  3. 使用 asp.net mvc和 jQuery UI 控件包
  4. [html] 请说说你在写布局时对于浏览器兼容性的感受或总结
  5. 深度学习之RetinaNet
  6. Matplotlib 中文用户指南 3.8 路径教程
  7. linux c开发项目,linux c 服务器开发项目
  8. 五一劳动节,你在加班劳动吗?
  9. win10-linux双系统安装教程
  10. 如何用计算机算分组数据方差,『分组数据如何Excel计算标准差』Excel表格求分组数据的方差...
  11. vscode免密登录需要更改authorized_keys的权限
  12. 小米手机自动进入Recovery恢复模式,且不停重启
  13. Tesseract OCR图片提取中文并转换为Excel的示例(附Python代码)
  14. java 扩展名读取_java 读取excel文件,根据文件后缀名
  15. Qt 使用WPS或HTML生成word文档
  16. 运算(与运算)和|运算(或运算)
  17. dockerfile构建LNRP环境练手
  18. 地球上20张最惊人的照片_地球上30个惊人的自然景点
  19. 《Python学习手册》读书笔记
  20. VMware centos7 下开放端口

热门文章

  1. Hie with the Pie(Floyd+状压dp)
  2. 四种方法解决:Windows10下使用SVN文件夹不显示小绿勾
  3. win10语言包在c盘哪里,win10系统通过卸载语言包释放c盘空间的操作方法
  4. mysql blob 读取 图片_mysql中以blob形式存储的图片文件 通过ajax方式传输 在js中设置成img控件的src...
  5. 2022年G2电站锅炉司炉复习题及模拟考试
  6. 部落冲突-建筑大师基地军队建筑介绍(兵营、建筑大师训练营、星空实验室、战争机器)
  7. matlab图片投稿,投稿时图片DPI的设置及相关心得
  8. 山东春考计算机组装与维修,山东春考计算机组装与维修模拟试题(11页)-原创力文档...
  9. VMware 安装 Linux 系统
  10. Mysql 主从复制实战(学习笔记十三)