博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
开源免费跨平台opengl opencv webgl gtk blender, opengl贴图程序
阅读量:5832 次
发布时间:2019-06-18

本文共 28482 字,大约阅读时间需要 94 分钟。

三维图形的这是opengl的强项,大型3D游戏都会把它作为首选。

图像处理,是opencv的锁定的目标,大多都是C的api,也有少部分是C++的,工业图像表现,图像识别,都会考虑opencv的。
webgl,这是3维向web延伸的方案,它可以直接调用支持opengl的接口,硬件加速或者软件模拟,很强大,结和html5....
blender,可以完成三维模型制作,3D动画制作了。

 

PC 游戏还是 DirectX 开发?事实上在早年OpenGL即使在游戏领域也是对DirectX压倒性的优势。John Carmack曾嘲讽DirectX是“horribly broken” 的API。直到DirectX6时代OpenGL都被认为是比DirectX更加优秀的API,即使那个时候DirectX已经有《CS》《极品飞车5》等大作的支持,却依然不受当时FPS游戏霸主id Software的待见。作为那个时代的显卡杀手,《Quake III》都仅仅只支持OpenGL。DirectX7发布之后DirectX和OpenGL开始逐渐平起平坐。直到2000年DirectX8的发布才使DirectX在游戏领域完全确立了自己的优势 —— 支持革命性的programmable GPU rendering pipeline来代替原有的fixed function pipeline,引入了Vertex Shader和Pixel Shader。而OpenGL的核心正式支持programmable rendering pipeline已经是四年之后OpenGL 2.0发布的时候了。想想这中间会有多少游戏公司/游戏引擎公司会倒向DirectX吧。说到OpenGL衰落的原因,不得不提到OpenGL开发的机制。OpenGL早期一直是由ARB (OpenGL Architecture Review Board,成员包括Nvidia, ATI, Intel, Apple, IBM, SGI等等)成员共同维护。每个成员可以为了支持自己硬件新的feature来开发OpenGL enxtension, 所有成员一致通过的extension才能加入到下个版本OpenGL核心中。这就造成了不同成员为了各自利益互相斗争,拖慢了开发进度。微软曾经也是ARB的成员之一,后来因为受不了这种机制退出专心搞自己的DirectX去了。如果一个API越流行,那么去学习这个API的人就会越多,游戏公司会越容易招到掌握这个API的图形程序员,也就会更多的基于这个API开发游戏。用这个API的游戏越来越多,就会更多的得到硬件厂商的支持,为面向这个API的驱动做更多的优化,然后这个API就会更加流行。如此进入一个良性循环,这就造成了DirectX现在称霸游戏领域,OpenGL几乎绝迹的局面。在06年从ARB交由Khronos Group掌管之后, OpenGL最近几年也迎头赶上,从性能,易用性来说其实和DirectX已经相差不大。但是在相比DirectX没有突出优点的情况下(除了跨平台),已经习惯使用DirectX的游戏厂商也不可能重新投出OpenGL的怀抱。最后一点,OpenGL只是一个单纯的图形库,而DirectX是包含图形(Direct3D), 声音(DirectSound), 输入(DirectInput), 网络(DirectPlay)的一整套游戏开发解决方案。对开发者来说使用DirectX显然要方便的多。/*******************************************************************************************************/下面是我之前一个同事看完我的回答的评论,也贴上来吧。“还有很重要的一点, GL从不淘汰任何老的API. DX10相对于DX9,是个全新的API,革命性的更新,彻底推倒重来. 但GL为了向后兼容,保留了很多对硬件和驱动都不友好的API.除了跨平台和早期对精度的要求比DX高,其他简直是一无是处”于是Game开发者就都去用DX了。如果Linux上有类似于DX的接口,只要它真正被广泛支持了,包括但不限于OpenGL DSA 扩展,相信我,没有哪个开发者会脑袋抽风继续跟随坑爹的状态机的。OpenGL的硬件兼容性不如DirectX。用OpenGL写一个程序,在nVidia上跑起来了,百分之八十是没法在intel上跑,百分之九十九没法在AMD上跑。OpenGL直到目前为止如果不用DSA的话,设置一个对象的属性还得先绑定,这样一来就使得code变得高度依赖于一个时刻在变的状态,而且很多驱动的实现某些特定的状态下有各种bug,极难调试。例如我之前在intel上跑一个程序,如果不每帧都重新设置一个framebuffer object的render target, 那个framebuffer到了下一帧就莫名其妙的失效了,而在NV和AMD上都没有此问题,但是AMD又出了另外一个问题。DirectX的好处有微软帮你测试兼容性。一个驱动想拿到WDDM认证,先得跑通积累了十几年的test set,这样一来在实际中遇到问题的可能性就大为减少了。另外DX有开发调试环境的优势,以及更合理的API设计。dx甩opengl几条街学图形学还是多看看理论书吧,看API没什么意思。你要知道,至少到vs2008,vs自带的opengl头文件都只是1.1版本的,你这叫人如何用? 微软为了发展DX抑制OpenGL几乎每一本OpenGL书籍都会提到。 -------分割更新-------- 再有就是DX的SDK属于虽然要自己下而且很大但是可以开箱即用,OpenGL就不一样了,glew,glext,glut等等一大堆各式版本的头文件,还要自己保证兼容等等问题……不说了,都是泪对于从游戏开发者角度而言,OpenGL 曾经是个没人用的东西,Windows / Xbox 上可以用 DirectX,PS3 和 Wii 则又是另外的图像API。直到iPhone的兴起,OpenGL 居然又活了过来,你看现在连 WebGL 都出现了,有一种统一天下的感觉。游戏开发者又开始重视 OpenGL 了,当然主要还是 OpenGL ES。对于显卡公司而言,Windows 上的 D3D 驱动特别重要,会针对各种流行游戏进行定制、优化、hack……至于 OpenGL 驱动,似乎只要满足 CAD 大厂的需求即可,毕竟几乎没有 Windows 上的 OpenGL 游戏啊……现阶段,从性能考虑(D3D 驱动会特别优化),大型的游戏还是以 D3D 的形式发布,不排除 OpenGL 的优化上去以后也会有大型的桌面 OpenGL 游戏。对于微软而言,他对于OpenGL的限制非常多,比如WindowsRT,Windows Phone是不支持OpenGL,Windows商店里的应用也必须是DirectX的。Dota2的OS X和Linux版就是OpenGL的Source引擎做的近10年来,opengl追赶dx就跟java追赶C#一样。opengl原本是一种设计来做CAD的api,后来被用来搞游戏,火了之后不思进取,造成了计算模型落后到爆炸,后面才慢慢改成了dx11现在的样子的。而且opengl煞笔还要怪那些A开头公司的编译器。众所周知,一个公司一旦以A开头,那他自主研发的编译器就跟垃圾一样。opengl(和opencl一样)标准要求驱动程序自己去写编译器,就别说linux了,在windows上不同的卡都有互相不兼容的bug。而directx的标准要求驱动程序解释一个指令集的中间语言,不兼容的情况就少了好多,虽然还有,但是已经没什么所谓了。不过由于底子不好,opengl的api用起来始终没有dx11那么舒服。P.S.,由于opencl也是一个德行,在windows上的A卡定义一个struct都会导致驱动程序崩溃什么的,让人怎么用啊,只能选cuda或directcompute了。llvm是apple买的?llvm的创造者在apple工作了快有十年了,而且他还是swift的创造者,他本人已经算apple的一份子了吧。llvm确实是2000年就诞生了,但是走向成熟且大展拳脚则是在加盟apple以后吧强烈建议初学计算机图形学的玩家不要跳OpenGL这个坑,可能在你编译第一个demo的时候,这辈子就和CG绝缘了。下面就是我的血泪史:首先,OpenGL自身功能集成度太低,你要么选择大量的附加依赖项,要么写大量的代码。于是各种附加依赖层出不穷,从创建Wnd的glut到windows扩展glew,你都需要了解学习。不过你学习的过程就会惊喜的发现,有一些竟然不更新了,XP available ONLY 哦!剩下那些有更新也是一个丑的不能看的网站(还不如GNU系列的网站,你懂得),只提供源码(由于服务器缘故,下载速度让我还以为被墙了),需要自己编译。很多还是有多层依赖的,这些都需要自己一层一层的下载编译。而且由于C++编译选项千奇百怪,你必须要注意每个库的编译,否则链接错误就是个灾难。而且由于都是自己编译的,拿到别人的电脑上也没法用,别人也需要重新编译,甚至还要修改一些头文件的引用!面对一堆不是你写的,一坨宏和依赖项的C++头文件,去修改,画面真美。而且每换一个地方就要编译20分钟,那酸爽也是绝了。而且你想写原生的windows窗口,使用Windows Message Loop,而不是用glut的玩具一样的功能,由于没有Help Templates,我当时为了写一个支持多重采样的窗体,看了十几个OpenGL的英文(中文几乎没有开发者!呵呵)wiki和网上教程,才理解了gl绘图上下文的“二次创建”还有颜色模式。最后写出了一个好几百行、N多函数满地宏的main.cpp。当我给别人讲这些的时候,别人都觉得是天书。而一年之后,我也忘了。而DX3D我下载了Sample之后,由于有Templates、Help Tools,我根本不操心窗体创建、Message Loop,可以直奔主题编辑图形,感觉直接到了天堂。此外,OpenGL里面各种绑定,API接口,让人头晕目眩,一个函数N个参数(而且参数名字长相还特别像,还都是宏,酸爽你懂得),还由于开发者少,生态差,没有一份清晰的文档,也没有特别好的教程。当时为了学习OpenGL,我买了一本红宝书,简直是API Reference + 计算机图形学导论啊,就觉得100块钱买了个砖,根本看不下去。顺带一提,这个绑定机制极其反人类,当时一不小心绑定错了一个ID,各种诡异的现象都出现了,因为模型库都来自于修改第三方,debug用了一天,顺便读了一次3000多行的3D图形导入库,对这一坨坨的递归找BUG,学到的知识简直丰富无比,DEBUG技能点不知道增长了多少。同样是由于生态差,目前本应该主流使用的GLSL也很难找到资料学习,所以只能用1.1版本的API。然而放弃GLSL就等于回到了那个固定流水的老GPU时代,现代GPU的高效运算、多线程根本用不到了,又回到那个CPU运算为主,命令列表渲染的低效率时代。老师讲解的模型视点变换、透视变换,本来都应该是自己用GLSL实现的,结果都变成了调用现成API,学的东西和练习的东西完全脱节,导致课程实验效果很差,学生们做起来都是十分痛苦。最后图形学的知识几乎成了死记硬背来考试的,学生也没有在实验中获得多少快乐(个别如我这种喜欢自虐的除外。当然,最大的问题是难以调试!纯C++的OpenGL出BUG时尽管看不到调试的图形反应,但是起码能看到数据反映。但是加入了着色器以后的,如果C++部分编译、运行全部正常,然而却没有任何图像或者不尽如人意的话,恭喜你,锅都在GLSL的部分,而这一部分根本你不能调试,只能对着黑屏发呆思考哪个公式不对,那个数据传递有问题,可能一折腾几个小时就过去了。后来尽管有nSight,但是笔记本双显卡还不能用(默哀~,不知道现在改进了吗?)。这样的调试支持,可以说是要把开发者逼上梁山,不能Debug还玩毛线啊。网上有人评论,OpenGL你看一本红宝书下去,写出的代码都未必能运行;但是你用DX3D,HelloWorld Sample能跑,基本就可以出程序了。看我想他们易用性差距也就这么大吧。最后,因为OpenGL的一坨坑,我差点放弃学习计算机图形学,幸好我凭借“毅力”挺了过来,还做出了一个有天空盒、地形、模型导入、粒子系统、反狗牙的小图形引擎,拿了很高的分数。尽管如此,这两天搞毕设,我宁愿用从来没有接触过的DX3D做,也不愿意再碰OpenGL了,毕竟少生点气,多活两年比啥也重要。我大学的图形学课程教了我OpenGL入门。如果改成DirectX入门我估计要挂到天荒地老...OpenGL上手容易:强大的glut封装了很多诸如创建窗口之类的繁琐工作,而且一开始你根本不需要接触复杂的顶点缓冲之类的复杂概念,挨着调用glVertex(),glColor()之类的函数就可以一个一个的将顶点画上去。反观DX,除了从一开始你就得掌握一些windows编程知识用于基本的创建窗口之外,你还必须掌握定点缓冲,一次性传输所有顶点进去才可以让DX进行绘制。作为新手,用OpenGL画一个正方体比DX容易太多... 也更容易建立初始的成就感和兴趣...事实上老师根本没有讲到顶点缓冲以后的知识。毕竟是计算机图形学,不是OpenGL课... 这些都是我后来自学的。不过还好我学了,DX才能入门..作为一个两边都接触过的码农来回这个帖子。因为太久没碰GL,可能有误,欢迎指出。代码我就不贴了。

 

 

 

 

 

Estereo是一个开源的双目或者三目立体视觉重建程序

编译需要安装vc.net和directx9.0 sdk,编译时可能需要修改几处地方
1.很多显卡不支持硬件VB,所以修改这里

hr = m_pD3D->CreateDevice(
    D3DADAPTER_DEFAULT,
    D3DDEVTYPE_HAL,
    m_hWnd,
    D3DCREATE_SOFTWARE_VERTEXPROCESSING,//D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
    &m_d3dpp, 
    &m_pD3DDevice);

2.有些电脑不能显示三维重建结果,需要修改这里将这些代码移出OnInitdialog

CWnd* pParent = GetParent();
  CRect rcParent;
  pParent->GetWindowRect(&rcParent);
  MoveWindow(&rcParent);
  C3DWindow* p3DWindow= (C3DWindow*)GetDlgItem(IDC_3D_CONTROL);
  if(p3DWindow)
  
{
   CRect rcControl; 
   GetClientRect(&rcControl);
   rcControl.DeflateRect(10,10,10,10);
   p3DWindow->MoveWindow(&rcControl);
   
   if(((CButton*)GetDlgItem(IDC_CHECK_INITPOS))->GetCheck())
    p3DWindow->SetRegistryKey("3D Reconstruction");//arcball params should be kept separate 
   p3DWindow->Start(false);
   p3DWindow->CreateVB(m_nPoints,m_pX,m_pY,m_pZ,m_pC,m_pS);
 }

可以自己加上一个按钮,将这些代码加入按钮的响应函数中

 
 
 
 
 
 
 

 

//#include <GL/gl.h>

#include <GL/glaux.h> 
#include <glut.h>

//glaux.lib glut32.lib

namespace Test9

{
#include <windows.h> // Header File For Windows
#include <math.h> // Math Library Header File
#include <stdio.h> // Header File For Standard Input/Output
#include <glgl.h> // Header File For The OpenGL32 Library
#include <glglu.h> // Header File For The GLu32 Library
#include <glglaux.h> // Header File For The Glaux Library

HDC hDC=NULL; // Private GDI Device Context

HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application

bool keys[256]; // Array Used For The Keyboard Routine

bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
bool blend; // Blending ON/OFF
bool bp; // B Pressed?
bool fp; // F Pressed?

const float piover180 = 0.0174532925f;

GLfloat walkbias = 0;

GLfloat walkbiasangle = 0;
GLfloat rot_x = 0.0f;
GLfloat rot_y=0; // Y Rotation
GLfloat rot_z=0; 
GLfloat g_z=-5.0f; // Depth Into The Screen
GLfloat x=0.0f; // Depth Into The Screen
GLfloat y=0.0f; // Depth Into The Screen

GLuint filter; // Which Filter To Use

GLuint texture[3]; // Storage For 3 Textures

typedef struct tagVERTEX

{
float x, y, z;//3D坐标
float u, v;//纹理坐标
} VERTEX;

typedef struct tagTRIANGLE

{//Triangle三角形结构
VERTEX vertex[3];
} TRIANGLE;

typedef struct tagSECTOR

{
int numtriangles;// Sector中的三角形个数
TRIANGLE* triangle;// 指向三角数组的指针
} SECTOR;

SECTOR sector1; // Our Model Goes Here:

typedef struct{

int numPoints;
VERTEX *vertex;
}MYPOINTS;

MYPOINTS g_pts;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc

void readstr(FILE *f,char *string)

{// 读入一个字符串
do
{
fgets(string, 255, f);

int i1=0,i2=strlen(string),i;

while (string[i1] && (string[i1]==' ' || string[i1]==' '))i1++;
// printf("i1=%d ",i1);
// printf(string);
// while (string[i2]==' ' || string[i2]==' ')i1--;
if(i1>=i2)
continue;
else if(i1>0)
{
for (i=i1;i<i2;i++)
{
string[i-i1]=string[i];
}
string[i2-i1]=0;
// printf(string);
}
} while ((string[0] == '/') || (string[0] == ' '));
return;
}

void SetupWorld()

{// 设置我们的世界
float x, y, z, u, v;
int numtriangles;
FILE *filein;
char oneline[255];
filein = fopen("world.txt", "rt"); // File To Load World Data From
CHECK(filein);

readstr(filein,oneline);

//printf(oneline);
sscanf(oneline, "NUMPOLLIES %d ", &numtriangles);
CHECK(numtriangles>0);
sector1.triangle = new TRIANGLE[numtriangles];
sector1.numtriangles = numtriangles;
for (int loop = 0; loop < numtriangles; loop++)
{
for (int vert = 0; vert < 3; vert++)
{
readstr(filein,oneline);
sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v);
sector1.triangle[loop].vertex[vert].x = x;
sector1.triangle[loop].vertex[vert].y = y;
sector1.triangle[loop].vertex[vert].z = z;
sector1.triangle[loop].vertex[vert].u = u;
sector1.triangle[loop].vertex[vert].v = v;
}
}
fclose(filein);
return;
}

//支持定义点和面(三角和四边形)

void SetupWorld2()
{// 设置我们的世界
float x, y, z, u, v;
int numpoints;
FILE *filein;
char oneline[255];
filein = fopen("world2.txt", "rt"); // File To Load World Data From
CHECK(filein);

//读入点

readstr(filein,oneline);
CHECK(1==sscanf(oneline, "NUMPOINTS %d ", &numpoints));
CHECK(numpoints>0);
g_pts.numPoints=numpoints;
g_pts.vertex=new VERTEX[numpoints];
for (int loop = 0; loop < numpoints; loop++)
{
readstr(filein,oneline);
CHECK(5==sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v));
g_pts.vertex[loop].x=x;
g_pts.vertex[loop].y=y;
g_pts.vertex[loop].z=z;
g_pts.vertex[loop].u=u;
g_pts.vertex[loop].v=v;
}

//读入面

int numtriangles=0;
readstr(filein,oneline);
CHECK(1==sscanf(oneline, "NUMPTRIANGLES %d ", &numtriangles));
CHECK(numtriangles>0);
sector1.triangle = new TRIANGLE[numtriangles];
sector1.numtriangles = numtriangles;
for ( loop = 0; loop < numtriangles; loop++)
{
int index[3];
readstr(filein,oneline);
CHECK(3==sscanf(oneline, "%d %d %d",index,index+1,index+2));
CHECK(index[0]>=0 && index[0]<g_pts.numPoints);
CHECK(index[1]>=0 && index[1]<g_pts.numPoints);
CHECK(index[2]>=0 && index[2]<g_pts.numPoints);
for (int vert = 0; vert < 3; vert++)
{
sector1.triangle[loop].vertex[vert]= g_pts.vertex[index[vert]];
}
}
fclose(filein);
return;
}

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image

{
FILE *File=NULL; // File Handle

if (!Filename) // Make Sure A Filename Was Given

{
return NULL; // If Not Return NULL
}

File=fopen(Filename,"r"); // Check To See If The File Exists

if (File) // Does The File Exist?

{
fclose(File); // Close The Handle
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}
return NULL; // If Load Failed Return NULL
}

int LoadGLTextures() // Load Bitmaps And Convert To Textures

{
int Status=FALSE; // Status Indicator

AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture

memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit

if (TextureImage[0]=LoadBMP("1.bmp"))
{
Status=TRUE; // Set The Status To TRUE

glGenTextures(3, &texture[0]); // Create Three Textures

// Create Nearest Filtered Texture

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);

// Create Linear Filtered Texture

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);

// Create MipMapped Texture

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 Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data); // Free The Texture Image Memory
}

free(TextureImage[0]); // Free The Image Structure

}

return Status; // Return The Status

}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window

{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}

glViewport(0,0,width,height); // Reset The Current Viewport

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix

glLoadIdentity(); // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix

glLoadIdentity(); // Reset The Modelview Matrix
}

int InitGL(GLvoid) // All Setup For OpenGL Goes Here

{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return FALSE; // If Texture Didn't Load Return FALSE
}

glEnable(GL_TEXTURE_2D); // Enable Texture Mapping

glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

SetupWorld2();//建立世界

return TRUE; // Initialization Went OK

}

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing

{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View

GLfloat x_m, y_m, z_m, u_m, v_m;

static DWORD tickCnt=GetTickCount();
int numtriangles;

glTranslatef(x, y, g_z);

#if 1

glRotatef(rot_x,1.0f,0,0);
glRotatef(rot_y,0,1.0f,0);
glRotatef(rot_z,0,0,1.0f);
#else
int norm=sqrt(rot_x*rot_x+rot_y*rot_y+rot_z*rot_z);
int ang_x=0;
int ang_y=0;
int ang_z=0;

if(norm>10)

{
ang_x=rot_x/norm;
ang_y=rot_y/norm;
ang_z=rot_z/norm;
}
else
norm=0;
glRotatef(norm,rot_x,rot_y,rot_z);
#endif

if(GetTickCount()-tickCnt>1000)

{
printf("Trans %8g %8g %8g ",x,y,g_z);
printf("Rot %8g %8g %8g ",rot_x,rot_y,rot_z);
tickCnt=GetTickCount();
}
glBindTexture(GL_TEXTURE_2D, texture[filter]);
numtriangles = sector1.numtriangles;
// Process Each Triangle
for (int loop_m = 0; loop_m < numtriangles; loop_m++)
{
glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
x_m = sector1.triangle[loop_m].vertex[0].x;
y_m = sector1.triangle[loop_m].vertex[0].y;
z_m = sector1.triangle[loop_m].vertex[0].z;
u_m = sector1.triangle[loop_m].vertex[0].u;
v_m = sector1.triangle[loop_m].vertex[0].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
x_m = sector1.triangle[loop_m].vertex[1].x;
y_m = sector1.triangle[loop_m].vertex[1].y;
z_m = sector1.triangle[loop_m].vertex[1].z;
u_m = sector1.triangle[loop_m].vertex[1].u;
v_m = sector1.triangle[loop_m].vertex[1].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
x_m = sector1.triangle[loop_m].vertex[2].x;
y_m = sector1.triangle[loop_m].vertex[2].y;
z_m = sector1.triangle[loop_m].vertex[2].z;
u_m = sector1.triangle[loop_m].vertex[2].u;
v_m = sector1.triangle[loop_m].vertex[2].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
glEnd();
}
return TRUE; // Everything Went OK
}

GLvoid KillGLWindow(GLvoid) // Properly Kill The Window

{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}

if (hRC) // Do We Have A Rendering Context?

{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}

if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?

{
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // Set RC To NULL
}

if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC

{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // Set DC To NULL
}

if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?

{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}

if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class

{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
}

/* This Code Creates Our OpenGL Window. Parameters Are: *

* title - Title To Appear At The Top Of The Window *
* width - Width Of The GL Window Or Fullscreen Mode *
* height - Height Of The GL Window Or Fullscreen Mode *
* bits - Number Of Bits To Use For Color (8/16/24/32) *
* fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height

fullscreen=fullscreenflag; // Set The Global Fullscreen Flag

hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "OpenGL"; // Set The Class Name

if (!RegisterClass(&wc)) // Attempt To Register The Window Class

{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (fullscreen) // Attempt Fullscreen Mode?
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.

if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By Your Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE; // Return FALSE
}
}
}

if (fullscreen) // Are We Still In Fullscreen Mode?

{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}

AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size

// Create The Window

if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name
title, // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be

{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer) 
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?

{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?

{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?

{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context

{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

ShowWindow(hWnd,SW_SHOW); // Show The Window

SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen

if (!InitGL()) // Initialize Our Newly Created GL Window

{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

return TRUE; // Success

}

LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window

UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active=TRUE; // Program Is Active
}
else
{
active=FALSE; // Program Is No Longer Active
}

return 0; // Return To The Message Loop

}

case WM_SYSCOMMAND: // Intercept System Commands

{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}

case WM_CLOSE: // Did We Receive A Close Message?

{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}

case WM_KEYDOWN: // Is A Key Being Held Down?

{
keys[wParam] = TRUE; // If So, Mark It As TRUE
return 0; // Jump Back
}

case WM_KEYUP: // Has A Key Been Released?

{
keys[wParam] = FALSE; // If So, Mark It As FALSE
return 0; // Jump Back
}

case WM_SIZE: // Resize The OpenGL Window

{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}

// Pass All Unhandled Messages To DefWindowProc

return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

int WINAPI WinMain( HINSTANCE hInstance, // Instance

HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
MSG msg; // Windows Message Structure
BOOL done=FALSE; // Bool Variable To Exit Loop

// Ask The User Which Screen Mode They Prefer

if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
fullscreen=FALSE; // Windowed Mode
}

// Create Our OpenGL Window

if (!CreateGLWindow("Lionel Brits & NeHe's 3D World Tutorial",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}

while(!done) // Loop That Runs While done=FALSE

{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message==WM_QUIT) // Have We Received A Quit Message?
{
done=TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received?
{
done=TRUE; // ESC or DrawGLScene Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
if (keys['B'] && !bp)
{
bp=TRUE;
blend=!blend;
if (!blend)
{
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
else
{
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
}
}
if (!keys['B'])
{
bp=FALSE;
}

if (keys['F'] && !fp)

{
fp=TRUE;
filter+=1;
if (filter>2)
{
filter=0;
}
}
if (!keys['F'])
{
fp=FALSE;
}
if (keys['R'])//Reset totation matrix
{
rot_x=rot_y=rot_z=0;
}
if (keys['T'])//Reset totation matrix
{
x=y=0;
g_z=-5;
}

if (keys[VK_F1])//pgup

{
x-=0.01f;
}

if (keys[VK_F2])

{
x+=0.01f;
}

if (keys[VK_F3])//pgup

{
y-=0.01f;
}

if (keys[VK_F4])

{
y+=0.01f;
}

if (keys[VK_F5])//pgup

{
g_z-=0.01f;
}

if (keys[VK_F6])

{
g_z+=0.01f;
}

if (keys[VK_PRIOR])//pgup
{
rot_z-=1.0f;
}

if (keys[VK_NEXT])

{
rot_z+=1.0f;
}

if (keys[VK_RIGHT])
{
rot_y -= 1.0f;
}

if (keys[VK_LEFT])

{
rot_y += 1.0f;
}

if (keys[VK_UP])

{
rot_x-= 1.0f;
}

if (keys[VK_DOWN])

{
rot_x+= 1.0f;
}

// if (keys[VK_ESCAPE]) // Is F1 Being Pressed?

// {
// keys[VK_F1]=FALSE; // If So Make Key FALSE
// KillGLWindow(); // Kill Our Current Window
// fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode
// // Recreate Our OpenGL Window
// if (!CreateGLWindow("Lionel Brits & NeHe's 3D World Tutorial",640,480,16,fullscreen))
// {
// return 0; // Quit If Window Was Not Created
// }
// }
}
}
}

// Shutdown

KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
CString strHello;
strHello.LoadString(IDS_HELLO);
cout << (LPCTSTR)strHello << endl;
}
//Test1::main2();
Test9::WinMain(0,0,0,SW_SHOWNORMAL);
return nRetCode;
}

 

附上测试使用的world2.txt

NUMPOINTS 8
0  0  0  0  1
1  0  0   0.25  1
1  0  1   0.75  1
0  0  1 1  1
0  1  0  0 0
1  1  0  0.25 0
1  1  1  0.75 0
0  1  1 1  0
NUMPTRIANGLES 8
0 1 4
4 1 5
1 2 5
2 5 6
2 3 6
3 6 7
0 3 7
0 7 4

mud.bmp

转载地址:http://snedx.baihongyu.com/

你可能感兴趣的文章
携手8Manage CRM建设企业数字化营销之路
查看>>
深度学习遇上基因组,诊断疾病或迎来突破
查看>>
机器换人潮: 前5月工业机器人产量增长50.4%
查看>>
Windows Vista for Developers——第四部分:用户帐号控制(User Account Control,UAC)
查看>>
方格填数
查看>>
VR MR技术加持,数据可视化处理将成下一个风口
查看>>
常用网址
查看>>
PowerDesigner添加表注释
查看>>
写得蛮好的linux学习笔记六-帐号管理(收藏)
查看>>
实战:阿里巴巴 DevOps 转型后的运维平台建设
查看>>
霍金再发声:人工智能的下一步或是摧毁中产阶级
查看>>
jQuery中的Sizzle引擎分析
查看>>
Kali Linux更新源以及设置中文
查看>>
mysql 5.6主从同步
查看>>
PHP使用DOMDocument采集
查看>>
生产环境常见的HTTP状态码列表
查看>>
Buffer源码深入分析
查看>>
jQuery的扩展方法写法
查看>>
etcd raft library设计原理和使用
查看>>
计算斐波那契数列的前N项和;
查看>>