区别般流程我们从个3D坐标轴开始进入3D世界主要是为了将来和3D线框模型做对比用
3D和以前学过2D最大区别就是我们需要考虑物体Z轴坐标而不再是假设任何物体Z轴都是0.0首先看我们绘制个3D空间坐标轴情况为了形象我将其旋转了定角度以下是源代码:
void DrawCoordinate
{
GLfloat fCoorDatas = { 0.0, 0.0, 0.0, // Origin
1.0, 0.0, 0.0, // X Dir
0.0, 1.0, 0.0, // Y Dir
0.0, 0.0, 1.0}; // Z Dir
GLu ubyIndices = { 0, 1, // X Axis
0, 2, // Y Axis
0, 3}; // Z Axis
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPoer(3, GL_FLOAT, 0, fCoorDatas);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices+2);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices+4);
}
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT); // 清空颜色缓冲区
glColor3f(1.0, 0.0, 0.0);
glPushMatrix;
glRotatef(30, 1.0, -1.0, 0.0);
DrawCoordinate;
glPopMatrix;
glFlush;
}
为节省篇幅仅贴出关键片段完整源代码见我博客源代码2009-10-21\gl3DCoordinate\目录获取方式见文章最后有关获取博客完整源代码介绍说明
和以前代码主要区别是我们开始考虑Z轴坐标了这里以(0.0, 0.0, 1.0)来表示Z轴方向假如不经过旋转Z轴是正对着我们投影到屏幕上是个点我们看不到所以这里做了点旋转将Z轴调整到左下方这样角度符合我们平时习惯绘制3D坐标具体实现工程利用了顶点顶点相关知识参看本OpenGL系列文章5(以下简称XO5)效果如下图:
这样3D坐标图中会看到Z轴实际上没有伸出窗口以外而是被截断了具体原因在以后说视景体裁剪时候会介绍说明但是现在可以理解为在OpenGL中整个3D空间Z轴也不是无限而是和窗口大小样形成个3D立方体空间如同2D平面中超出窗口部分会看不见超出Z轴空间部分也会看不见此处Z轴被截断就是如此并且我们可以通过源码定位Z轴正方向(0.0, 0.0, 1.0)和图形中现实看出来在OpenGL3D坐标系中Z轴正方向是指向屏幕外这点在XO3中讲过了我们在这里通过坐标轴图再次理解下理解了3D坐标系那么所有3D图形也就是如同2D图形样定坐标而已了
3角锥(即 4面体或金字塔形)线框模型
下面我们开始在上述3D坐标体系中绘制个 3角锥这里还是先用线框模型来绘制其实没有任何3D知识仅仅靠凭空想象也能定下个这样简单 3角锥空间坐标以下如是其实没有什么技术难度仅仅加入Z轴考虑下列将 3角锥不停围绕其自身Z轴自转为了形象同时绘制上面讲 3维立体坐标轴格式有点混乱是Live WriterCode Snippet自动format不太好用-_-!完整源代码排版是缩进较为对齐
void DrawWirePyramid(GLfloat adSize)
{
GLfloat fPyramidDatas = { 0.0, 1.0, 0.0, // 3角锥上顶点
-1.0, 0.0, 1.0, // 底面左前顶点
1.0, 0.0, 1.0, // 底面右前下顶点
0.0, 0.0, -1.0}; // 底面后下顶点
GLfloat fPyramidSizeDatas[(fPyramidDatas)/(GLfloat)] = {0};
// 计算大小
for( i = 0; i < 12; i)
{
fPyramidSizeDatas[i] = fPyramidDatas[i] * adSize;
}
GLu ubyIndices = { 0, 1, // 以下为 3条侧边
0, 2,
0, 3,
1, 2, // 以下为 3条底边
2, 3,
3, 1};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPoer(3, GL_FLOAT, 0, fPyramidSizeDatas);
for( i = 0; i < 5; i)
{
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices+i*2);
}
}
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPushMatrix;
DrawCoordinate;
DrawWirePyramid(0.5);
glPopMatrix;
glRotatef(1.0, 0.0, 1.0, 0.0);
glFlush;
}
为节省篇幅仅贴出关键片段完整源代码见我博客源代码2009-10-21\glWirePyramid 目录获取方式见文章最后有关获取博客完整源代码介绍说明 显示效果如下图所示
3角锥
以上讲到3D图形都是以线框模型来演示,主要是为了可以纯粹考虑3D坐标问题,下面我们开始加入颜色,看看真正立体模型是如何样^^在上述例子中加入颜色实在再简单不过了已经使用了顶点我们只需要再启用下颜色就好了
如下例所示:
void DrawSmoothColorPyramid(GLfloat adSize)
{
GLfloat fPyramidDatas = { 0.0, 1.0, 0.0, // 3角锥上顶点
-1.0, 0.0, 1.0, // 底面左前顶点
1.0, 0.0, 1.0, // 底面右前下顶点
0.0, 0.0, -1.0}; // 底面后下顶点
GLfloat fPyramidSizeDatas[(fPyramidDatas)/(GLfloat)] = {0};
// 计算大小
for( i = 0; i < 12; i)
{
fPyramidSizeDatas[i] = fPyramidDatas[i] * adSize;
}
GLfloat fPyramidColors = { 0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0};
GLu ubyIndices = { 0, 1, 2, // 正面
0, 1, 3, // 左侧面
0, 2, 3, // 右侧面
1, 2, 3}; // 底面
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPoer(3, GL_FLOAT, 0, fPyramidSizeDatas);
glColorPoer(3, GL_FLOAT, 0, fPyramidColors);
for( i = 0; i < 4; i)
{
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, ubyIndices+i*3);
}
}
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPushMatrix;
DrawSmoothColorPyramid(0.5);
glPopMatrix;
glRotatef(1.0, 0.0, 1.0, 0.0);
glFlush;
}
为节省篇幅仅贴出关键片段完整源代码见我博客源代码2009-10-21\glSmoothColorPyramid\目录获取方式见文章最后有关获取博客完整源代码介绍说明
注意此例和上例中区别要显示完整立体模型就不能再用GL_LINES去画线了我们需要使用GL_TRIANGLES来绘制 3角形平面个 3角锥其实不过就是个 4面体嘛画上4个面切就OK运行效果如下图:
小结
其实看完全文会发现3D世界也没有什么难地方无非就是多了个Z轴需要考虑嘛将整个屏幕想象成个有前面空间后面空间立方体然后想象出3D模型坐标切也就简单了本文主要讲是 3角锥它是最简单大家可以试试立方体以增加难度体会3D坐标系统
最新评论