二 OpenGL入门指南
1.OpenGL发展历程和未来趋势
什么是OpenGL呢?
opengl是图形硬件的一种软件接口。本质上说,他是一个3D图形和模型库,具有高度可一致性,并且具有非常快的速度。本质是一个C运行时函数库。
当然最早是没有OpenGL的,从前有个SGI公司的图形工作站做的很牛叉,他们在开发自己产品的同时也形成了自己的一些图形处理的API函数库和一套规范。老大自然在市场上是有话语权的,其他小弟也都愿意向他靠拢,于是OpenGL ARB 体系审查委员会就诞生了(当然都是一些图形显卡厂商了)。林子大了,他一家自然也是管不住了,开源世界的力量也不容小觑,再加之SGI公司自己的跟不上时代,自己的业务也越来越不行,慢慢地也就没有实际的控制权了。opengl真正成了国际开放标准,由各大厂商共同维护,成立了新的Khronos工作组。他们的成员是一些诸如图形硬件公司和大型软件公司如微软,苹果等。
opengl以两种形式存在,第一种形式是opengl规范,第二种是opengl实现,例如在pc上的软件驱动程序和图形卡就共同组成了一个opengl实现。
绝大多数公司认识到从长远来看,竞争对于每家公司都是件好事,因此它们都认可并支持行业标准甚至对行业标准作出贡献。 对于未来,opengl也必定是越来越现代化,越来越好的。
2.扩展机制(Extension Mechanism)如何工作,以及它的重要性
标准的发展总是要经过验证和审核的,发展难免会有滞后性,加之各大硬件厂商存在竞争关系,各自创新发展的新技术和新接口,不一定能很快进入标准,对新硬件的升级也可能会影响老的标准。但是为了满足向下兼容的特性,总是要有所取舍。所以扩展机制,在国际标准和软件一贯性发展上就显得尤为重要。opengl提供了一直扩展机制,让新的API可以做良好的过渡也可以很旧API做好兼容。
3.如何检测OpenGL编程错误
opengl内部保留了一组错误标志,共四个,当一个错误发生时候,与这个错误想对应的标志就会被设置,可以调用GLGetError函数。
4.向OpenGL传递性能提示Hint
在3D图形算法中,为了追求高性能,我们常常需要做一些权衡。或者,如果视觉逼真度是最重要的因素,那么性能就会退二求其次。glhit函数允许我们制定偏重于视觉质量还是速度,以适应各种不同类型的操作需求.
5.GLUT基础编程框架解析
opengl开发需要opengl使用工具库,最早是AUX作为opengl的辅助函数库,后来发展了GLUT,但是由于GLUT最初并不是作为一种开放源代码的软件,因此 一种新的GLUT的实现freeglut已经崛起并取代了它的位置。
opengl api主要通过扩展机制来发展。这种扩展机制能偶用来获得指向任何加入opengl1.0之后任何版本核心的opengl函数的函数指针。有一个实现opengl3.3. api完全存取的简单的方法,就是使用一个自动初始化所有新函数指针并包含所需类型定义、常量和枚举值的扩展加载库,这种加载库有多种选择,其中维护最好的一个就是GLEW ,GLEW被预先封装在GLTools中。
GLTools就是一个工具箱,里面装满了自己喜爱的工具,程序员也是如此。有一些有用并且可重用的函数,所有程序员编写几乎所有opengl都会用到它们。GLTools包含了一个用于操作矩阵和向量的3D数学库,并依靠GLEW获得用来产生和渲染一些简单3D的函数,以及视觉平截头体、相机类和变换矩阵进行管理的函数的充分支持。
包含什么?
GLTools.h
GLShaderManager.h
Glut.h freeeGlut
启动GLUT
glutInit(&argc, argv) // 初始化glut库
glutInitDispalyMode() // 使用的缓冲区窗口
代码就是最好的教程
一个三角形
// Triangle.cpp
// Our first OpenGL program that will just draw a triangle on the screen.
#include <GLTools.h> // OpenGL toolkit
#include <GLShaderManager.h> // Shader Manager Class
#ifdef __APPLE__
#include <glut/glut.h> // OS X version of GLUT
#else
#define FREEGLUT_STATIC
#include <GL/glut.h> // Windows FreeGlut equivalent
#endif
GLBatch triangleBatch;
GLShaderManager shaderManager;
///////////////////////////////////////////////////////////////////////////////
// Window has changed size, or has just been created. In either case, we need
// to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
}
///////////////////////////////////////////////////////////////////////////////
// This function does any needed initialization on the rendering context.
// This is the first opportunity to do any OpenGL related tasks.
void SetupRC()
{
// Blue background
glClearColor(0.0f, 0.0f, 1.0f, 1.0f );
shaderManager.InitializeStockShaders();
// Load up a triangle
GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f };
triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
///////////////////////////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
triangleBatch.Draw();
// Perform the buffer swap to display back buffer
glutSwapBuffers();
}
///////////////////////////////////////////////////////////////////////////////
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
return 0;
}
一个可控制的正方形,带碰撞检测
// Move.cpp
// Move a Block based on arrow key movements
#include <GLTools.h> // OpenGL toolkit
#include <GLShaderManager.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
GLBatch squareBatch;
GLShaderManager shaderManager;
GLfloat blockSize =0.2f;
GLfloat vVerts[] = { -blockSize, -blockSize, 0.0f,
blockSize, -blockSize, 0.0f,
blockSize, blockSize, 0.0f,
-blockSize, blockSize, 0.0f};
///////////////////////////////////////////////////////////////////////////////
// This function does any needed initialization on the rendering context.
// This is the first opportunity to do any OpenGL related tasks.
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 1.0f, 1.0f );
shaderManager.InitializeStockShaders();
// Load up a triangle
squareBatch.Begin(GL_TRIANGLE_FAN, 4);
squareBatch.CopyVertexData3f(vVerts);
squareBatch.End();
}
// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
{
GLfloat stepSize = 0.025f;
GLfloat blockX = vVerts[0]; // Upper left X
GLfloat blockY = vVerts[7]; // Upper left Y
if(key == GLUT_KEY_UP)
blockY += stepSize;
if(key == GLUT_KEY_DOWN)
blockY -= stepSize;
if(key == GLUT_KEY_LEFT)
blockX -= stepSize;
if(key == GLUT_KEY_RIGHT)
blockX += stepSize;
// Collision detection
if(blockX < -1.0f) blockX = -1.0f;
if(blockX > (1.0f - blockSize * 2)) blockX = 1.0f - blockSize * 2;;
if(blockY < -1.0f + blockSize * 2) blockY = -1.0f + blockSize * 2;
if(blockY > 1.0f) blockY = 1.0f;
// Recalculate vertex positions
vVerts[0] = blockX;
vVerts[1] = blockY - blockSize*2;
vVerts[3] = blockX + blockSize*2;
vVerts[4] = blockY - blockSize*2;
vVerts[6] = blockX + blockSize*2;
vVerts[7] = blockY;
vVerts[9] = blockX;
vVerts[10] = blockY;
squareBatch.CopyVertexData3f(vVerts);
glutPostRedisplay();
}
///////////////////////////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
squareBatch.Draw();
// Flush drawing commands
glutSwapBuffers();
}
///////////////////////////////////////////////////////////////////////////////
// Window has changed size, or has just been created. In either case, we need
// to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
}
///////////////////////////////////////////////////////////////////////////////
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Move Block with Arrow Keys");
GLenum err = glewInit();
if (GLEW_OK != err)
{
// Problem: glewInit failed, something is seriously wrong.
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return 1;
}
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
SetupRC();
glutMainLoop();
return 0;
}
一个自由运动的动画,使用动态刷新
// Bounce.cpp
// Bounce a Block around the screen
#include <GLTools.h> // OpenGL toolkit
#include <GLShaderManager.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
GLBatch squareBatch;
GLShaderManager shaderManager;
GLfloat blockSize = 0.1f;
GLfloat vVerts[] = { -blockSize - 0.5f, -blockSize, 0.0f,
blockSize - 0.5f, -blockSize, 0.0f,
blockSize - 0.5f, blockSize, 0.0f,
-blockSize - 0.5f, blockSize, 0.0f};
///////////////////////////////////////////////////////////////////////////////
// This function does any needed initialization on the rendering context.
// This is the first opportunity to do any OpenGL related tasks.
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 1.0f, 1.0f );
shaderManager.InitializeStockShaders();
// Load up a triangle
squareBatch.Begin(GL_TRIANGLE_FAN, 4);
squareBatch.CopyVertexData3f(vVerts);
squareBatch.End();
}
// Respond to arrow keys by moving the camera frame of reference
void BounceFunction(void)
{
static GLfloat xDir = 1.0f;
static GLfloat yDir = 1.0f;
GLfloat stepSize = 0.005f;
GLfloat blockX = vVerts[0]; // Upper left X
GLfloat blockY = vVerts[7]; // Upper left Y
blockY += stepSize * yDir;
blockX += stepSize * xDir;
// Collision detection
if(blockX < -1.0f) { blockX = -1.0f; xDir *= -1.0f; }
if(blockX > (1.0f - blockSize * 2)) { blockX = 1.0f - blockSize * 2; xDir *= -1.0f; }
if(blockY < -1.0f + blockSize * 2) { blockY = -1.0f + blockSize * 2; yDir *= -1.0f; }
if(blockY > 1.0f) { blockY = 1.0f; yDir *= -1.0f; }
// Recalculate vertex positions
vVerts[0] = blockX;
vVerts[1] = blockY - blockSize*2;
vVerts[3] = blockX + blockSize*2;
vVerts[4] = blockY - blockSize*2;
vVerts[6] = blockX + blockSize*2;
vVerts[7] = blockY;
vVerts[9] = blockX;
vVerts[10] = blockY;
squareBatch.CopyVertexData3f(vVerts);
}
///////////////////////////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
squareBatch.Draw();
// Flush drawing commands
glutSwapBuffers();
BounceFunction();
glutPostRedisplay(); // Redraw
}
///////////////////////////////////////////////////////////////////////////////
// Window has changed size, or has just been created. In either case, we need
// to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
}
///////////////////////////////////////////////////////////////////////////////
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Bouncing Block");
GLenum err = glewInit();
if (GLEW_OK != err)
{
// Problem: glewInit failed, something is seriously wrong.
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return 1;
}
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
return 0;
}

浙公网安备 33010602011771号