阅读《计算机图形学编程(使用OpenGL和C++)》4 - 画立方体

绘制一个对象,它的顶点数据需要发送给顶点着色器。通常会把顶点数据在C++端放入一个缓冲区,并把这个缓冲区和着色器中声明的顶点属性相关联。其步骤如下:

只做一次的步骤,一般放在 init() 中。

1、创建一个缓冲区。

2、将顶点数据复制进缓冲区。

如果是动画场景的话,每帧都要做,一般在 display() 中。

1、启用包含了顶点数据的缓冲区。

2、将这个缓冲区和一个顶点属性相关联。

3、启用这个顶点属性。

4、使用 glDrawArrays() 绘制对象。

在 OpenGL 中,缓冲区被包含在顶点缓冲对象 (Vertex Buffer Object, VBO) 中,通常在程序开始的时候统一创建。

当 glDrawArrays() 执行时,缓冲区中的数据开始流动,从缓冲区的开头开始,按顺序流过顶点着色器。顶点着色器对每个顶点执行一次。3D空间中的顶点需要3个数值,所以着色器中的顶点属性常常会以vec3类型接收到这3个数值。然后,对缓冲区中的每组这3个数值,着色器会被调用。指定 GL_TRIANGLES时,光栅化是逐个三角形完成的。对 glDrawArrays() 的调用通常在其他调整这个模型的渲染设置的命令之前。

OpenGL中还有一种相关结构,叫作顶点数组对象 (Vertex Array Object, VAO),至少创建一个VAO。

下面两个 OpenGL 命令分别创建 VAO 和 VBO,并返回它们的整数型ID。这两个命令各自有两个参数,1、创建多少个ID。2、用来保存返回的 ID 的数组。

glGenVertexArrays(GLsizei n, GLuint* arrays); 
glGenBuffers(GLsizei n, GLuint* buffers);

glBindVertexArray()命令将指定的 VAO 标记为“活跃”,这样生成的缓冲区就会和这个 VAO相关联。

glBindVertexArray(GLuint array)

每个缓冲区需要有在顶点着色器中声明的相应的顶点属性变量。顶点属性通常是着色器中首先被声明的变量。我们在顶点着色器中可以这样声明:

layout (location = 0) in vec3 position;

关键字 "in" 是输入 (input) 的意思,表示这个顶点属性将会从缓冲区中接收数值。

"vec3" 是着色器每次调用会抓到3个浮点类型数值,分别表示x、y、z,它们组成一个顶点数据。

变量名字 "position"。

"layout (location = 0)" 叫作 "layout修饰符",就是我们把顶点属性和特定缓冲区关联起来的方法。这个顶点属性的识别号是0。

现在我们绘制一个立方体。

要渲染一个场景以使它看起来是3D的,需要构建适当的变换矩阵。并将它们应用于模型的每个顶点。在顶点着色器中应用所需的矩阵运算是最有效的,并且习惯上会将这些矩阵从 C++/OpenGL 应用程序发送给着色器中的统一变量。

关键字 "uniform" 在着色器中声明统一变量。

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

关键字 "mat4"表示这些是4×4矩阵。因为3D变换是4×4,因此mat4是GLSL着色器统一中常用的数据类型。

在片段着色器光栅化之前,由顶点定义的图元被转换为片段。光栅化过程会线性插值顶点属性值,以便显示的像素能无缝连接建模的曲面。

统一变量类似初始化过的常量,并且在每次顶点着色器调用(即从缓冲区发送的每个顶点)中保持不变。统一变量本身不是插值的;无论有多少顶点,它始终包含相同的值。

在顶点着色器中看到顶点属性被声明为 "in",表示它们从缓冲区接收值。顶点属性还可以改为声明为 "out",它们会将值发送到管线中的下一个阶段。OpenGL 有一个内置的vec4变量名字叫作 gl_Position 为顶点位置声明的一个 "out" 变量。变换后的顶点将自动输出到光栅着色器,最终将相应的像素位置发送到片段着色器。

可以构建3个矩阵并将它们发送到统一变量:模型矩阵、视图矩阵、透视矩阵。

模型矩阵在世界坐标空间中表示对象的位置和朝向。如果模型移动,需要不断重建该矩阵。

视图矩阵移动并旋转世界中的模型,以模拟相机在所需位置的效果。因为相机可以移动,所以它也需要每帧创建一次。根据所需的摄像机位置和朝向构建。将模型和视图矩阵结合成单个 "MV" 矩阵。

透视矩阵是一种变换,它根据所需的视锥提供3D效果。只需要创建一次,它需要使用屏幕窗口的宽度和高度(以及所需的视锥体参数),除非调整窗口大小,否则通常不变。

将 MV 和投影矩阵发送到相应的着色器统一变量。

main.cpp

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "Utils.h"

using namespace std;

#define numVAOs 1
#define numVBOs 2

float cameraX, cameraY, cameraZ;
float cubeLocX, cubeLocY, cubeLocZ;
GLuint renderingProgram;
GLuint vao[numVAOs]; // OpenGL要求这些数值以数组的形式指定
GLuint vbo[numVBOs];

// 给display()用
GLuint mvLoc, projLoc;
int width, height;
float aspect;
glm::mat4 pMat, vMat, mMat, mvMat;

void setupVertices(void)
{
    float vertexPositions[108] = {
        -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,  1.0f,  1.0f, -1.0f, -1.0f,  1.0f, -1.0f,
         1.0f, -1.0f, -1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  1.0f, -1.0f,
         1.0f, -1.0f,  1.0f,  1.0f,  1.0f,  1.0f,  1.0f,  1.0f, -1.0f,
         1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f,  1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f, -1.0f,
         1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  1.0f,
         1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f, -1.0f,
    };

    glGenVertexArrays(numVAOs, vao); // 创建一个vao,并返回它的整数型ID存进数组vao中
    glBindVertexArray(vao[0]); // 激活vao
    glGenBuffers(numVBOs, vbo);// 创建两个vbo,并返回它们的整数型ID存进数组vbo中

    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // 激活vbo第0个缓冲区
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); // 将包含顶点数据的数组复制进活跃缓冲区(这里是第0个VBO)
}

void init(GLFWwindow* window) {
    renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");
    cameraX = 0.0f;  cameraY = 0.0f;    cameraZ = 8.0f;
    cubeLocX = 0.0f; cubeLocY = -2.0f; cubeLocZ = 0.0f; // 沿Y轴下移以展示透视
    setupVertices();
}

void display(GLFWwindow* window, double currentTime)
{
    glClear(GL_DEPTH_BUFFER_BIT);
    glUseProgram(renderingProgram);

    // 获取MV矩阵和投影矩阵的统一变量的引用
    mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix"); 
    projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");

    // 构建透视矩阵
    glfwGetFramebufferSize(window, &width, &height);
    aspect = (float)width / (float)height;
    pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f); // 1.0472 radians = 60 degrees

    // 构建视图矩阵、模型矩阵和视图-模型矩阵
    vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));
    mMat = glm::translate(glm::mat4(1.0f), glm::vec3(cubeLocX, cubeLocY, cubeLocZ));
    mvMat = vMat * mMat;

    // 将透视矩阵和MV矩阵复制给相应的统一变量
    glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat)); // GLM函数调用value_ptr()返回对矩阵数据的引用
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));

    // 将VBO关联给顶点着色器中相应的顶点属性
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);                  // 标记第0个缓冲区为“活跃”
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);  // 将第0个属性关联到缓冲区
    glEnableVertexAttribArray(0);                           // 启用第0个顶点属性

    // 调整OpenGL设置,绘制模型
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glDrawArrays(GL_TRIANGLES, 0, 36);                      // 执行该语句,第0个VBO中的数据将被传输给拥有位置0的layout修饰符的顶点属性中。这会将立方体的顶点数据发送到着色器。

}

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(400, 300, "Hello World", NULL, NULL); //没用到的参数分别用来允许全屏显示以及资源共享
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    GLenum err = glewInit();
    if (err != GLEW_OK)
    {
        std::cout << "Error: " << glewGetErrorString(err) << std::endl;
    }
    glfwSwapInterval(1); // 交互缓冲区间隔设为1,即每帧更新一次,交换间隔表示交换缓冲区之前等待的帧数,通常称为Vsync垂直同步
    init(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        display(window, glfwGetTime()); // glfwGetTime()返回GLFW初始化之后经过的时间

        /* Swap front and back buffers */
        glfwSwapBuffers(window); // GLFW默认使用两个缓冲区

        /* Poll for and process events */
        glfwPollEvents(); // 处理窗口相关事件(如按键事件)
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

顶点着色器  vertShader.glsl

#version 460
layout (location = 0) in vec3 position;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main(void)
{ 
   gl_Position = proj_matrix * mv_matrix *vec4(position, 1.0);
}

顶点着色器中传入的顶点属性position的位置被指定为"0",因此display()函数可以简单地通过在glVertexAttribPointer()函数调用的第一个参数和glEnableVertexAttribArray()函数调用中使用0来引用此变量。

片段着色器 fragShader.glsl

#version 460
out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
void main(void)
{ 
   color = vec4(1.0, 0.0, 0.0, 1.0);
}

结果如下:

用三角形创建一个立方体,一个面由2个三角形组成,一共六个面,即12个三角形,36个顶点,每个顶点具有3个值(x, y, z),因此数组中有36×3=108个值。

这里建立了两个VBO,但只用了一个,将立方体顶点加载到第0个VBO缓冲区中。

init() 函数还给定了立方体和相机在世界中的位置。

要一个构建透视矩阵的工具函数,GLM已经包含了一个:

// 给定Y轴的指定视场角、屏幕纵横比以及所需的近、远剪裁平面的情况
glm::perspective(<field of view>, <aspect ratio>, <near plane>, <far plane>);

对 translate() 函数的 GLM 调用的形式,构建一个变换矩阵:从单位矩阵和以向量的形式指定变换值。许多 GLM 变换操作使用这种方法。

vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));

注意着色器,它们都包含相同的统一变量声明块。并不总是一定要这样做,但在特定渲染程序中的所有着色器中包含相同的统一变量声明块通常是一种好习惯。

让我们对着色器进行一些轻微的修改。

顶点着色器 vertShader.glsl

#version 460
layout (location = 0) in vec3 position;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

out vec4 varyingColor;

void main(void)
{ 
   gl_Position = proj_matrix * mv_matrix *vec4(position, 1.0);
   varyingColor = vec4(position, 1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);
}

我们根据每个顶点的位置为每个顶点指定一种颜色,并将该颜色放在输出的顶点属性varyingColor中。代码中将位置乘以0.5,然后加0.5,以将取值范围从 [-1...+1] 转换为 [0...1]。

片段着色器 fragShader.glsl

#version 460

in vec4 varyingColor;

out vec4 color;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

void main(void)
{ 
color = varyingColor;
}

接收传入的颜色(由光栅着色器插值)并用它设置输出像素的颜色。

结果可看到整个立方体从一个角到另一个角明显是被插值了。管线处理(顶点着色器、曲面细分着色器、几何着色器、光栅化、片段着色器、像素操作)

 由于main()函数包含一个渲染循环,故我们可以基于时间变化的平移和旋转来构建模型矩阵为立方体设置动画。

在main.cpp 开头定义变量处定义

glm::mat4 tMat, rMat;

在display()函数中修改代码如下:

void display(GLFWwindow* window, double currentTime)
{
    glClear(GL_DEPTH_BUFFER_BIT);
    glClear(GL_COLOR_BUFFER_BIT);
   ...// 使用当前时间来计算x, y和z的不同变换
    tMat = glm::translate(glm::mat4(1.0f),
        glm::vec3(sin(0.35f*currentTime)*2.0f, cos(0.52f*currentTime)*2.0f, sin(0.7f*currentTime)*2.0f));
    // 用1.75来调整旋转速度
    rMat = glm::rotate(glm::mat4(1.0f), 1.75f*(float)currentTime, glm::vec3(0.0f, 1.0f, 0.0f));
    rMat = glm::rotate(rMat, 1.75f*(float)currentTime, glm::vec3(1.0f, 0.0f, 0.0f));
    rMat = glm::rotate(rMat, 1.75f*(float)currentTime, glm::vec3(0.0f, 0.0f, 1.0f));

    mMat = tMat * rMat;

    // 构建视图矩阵、模型矩阵和视图-模型矩阵
    vMat = glm::translate(glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ));
    //mMat = glm::translate(glm::mat4(1.0f), glm::vec3(cubeLocX, cubeLocY, cubeLocZ));
    mvMat = vMat * mMat;
...
}

添加此动画说明了每次通过display()清除深度缓冲区以确保正确进行隐藏面消除的重要性。它还需要清除颜色缓冲区;否则,立方体会在移动时留下痕迹。

 

 注意最后一行中的矩阵乘法——操作中tMat和rMat的顺序很重要。它计算两个变换的结合,平移放在左边,旋转放在右边。当顶点随后乘以此矩阵时,计算从右到左进行,这意味着首先完成旋转,然后才是平移。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1篇 系统开发基础   包括第1章三维图形世界、第2章OpenGL概述和第3章Oracle与 OCI技术及编程基础。   第1章 介绍了计算机三维图形技术的发展、科学计算可视化技术、三维可视化工程设计的基本概念和发展现状。   第2章 主要对OpenGL的基本概念、OpenGL编程基础和在Visual C++环境下OpenGL基本程序框架的建立进行了讲解,并给出了一个简单的旋转立方体程序示例。通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。   第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,介绍了Oracle数据库的安装步骤和Oracle支持的数据类型。在此基础上,介绍了ADO、Pro*C/C++和OCI三个主要Oracle编程接口,对它们的各自功能和特点进行了详细说明,从功能方面、性能方面、开发难度方面进行了详细分析和比较。重点介绍OCI编程基础、OCI的数据结构、OCI程序的基本结构、OCI执行的步骤,最后给出了在Visual C++6.0环境下开发OCI应用程序的示例。   第2篇 大规模地形三维可视化系统设计与实现   包括第4章地形三维可视化系统框架与OCI类模块设计、第5章地形三维可视化系统的地形渲染实现和第6章地形三维可视化系统项目管理与辅助功能设计。   第4章 在第2章的基础上,完成了基于OpenGL的地形三维可视化系统程序框架的建立,为后续的功能模块开发提供了基础平台;在第3章的基础上,设计了OCI公共类,将所有与OCI有关的数据库操作、数据读取等功能函数实现全部封装在该类中,并定义了公共类的全局变量myOci。   第5章 本章对地形三维可视化进行了基本概述,介绍了目前地形三维可视化的主要算法。主要介绍了海量地形与影像纹理数据的常用获取方法,给出了海量地形自分块与影像纹理分块原则和程序实现,以及地形与影像子块调度的程序实现,在此基础上实现了地形的三维可视化;还介绍了真三维立体的实现算法和数学模型,在此基础上给出了基于OpenGL的真三维立体的程序实现。   第6章 主要讲解了新建项目、打开项目、背景天空的绘制、绘图模式控制的实现方法和程序设计。介绍了基于OpenGL深度缓存的二维屏幕坐标向三维空间坐标的转换算法,实现了对三维空间坐标和空间距离查询,以及查询标识设置的程序设计;最后讲解了基于键盘和鼠标联合控制的三维场景照相机程序模块的实现,实现三维场景的前、后、左、右移动和任意方向的旋转。   第3篇 线路三维可视化系统设计与实现   包括第7章三维交互技术与三维线路数据结构、第8章三维线路设计实现、第9章道路整体三维建模和第10章三维漫游的实现。   第7章 主要对三维交互环境进行了介绍,详细讲解了正射投影模式的实现、正射投影模式下场景控制方法和程序设计,以及透视投影模式的实现方法;还讲解了正射投影模式和透视投影模式下三维地面坐标的获取原理、方法,在此基础上,设计了边坡数据结构、桥梁数据结构、隧道数据结构、水沟数据结构及线路数据结构,为实现三维线路设计做好了前期准备。   第8章 主要对线路方案的主要参数设计方法和程序实现、设计交点信息输入实现、线路中心线定位方法、设计方案的保存、平面方案的自动生成和程序设计、纵断面设计模块的实现、边坡模型的生成算法、线路路基三维建模方法和实现、隧道三维建模和参数控制、桥梁三维建模和参数控制的程序设计进行了详细讲解。   第9章 主要讲解了道路整体三维模型实现,对其中的线路封闭区域确定与分割算法、地形块综合数据点计算、分块TIN模型的构网实现、封闭区域内数据点的剔除、整体构网的程序实现都进行了详细说明;在纹理管理部分,详细讲解了边坡纹理、路肩纹理、桥梁护坡面纹理、隧道内墙纹理、隧道洞门纹理的程序设计和实现。   第10章 从多个方面对三维漫游的基本概念、程序实现、参数调整和控制进行了讲解,帮助读者学会在三维可视化系统中三维漫游模块的程序设计方法;对飞行路径的基本概念、设置方法、插值算法、保存和打开的程序设计,沿飞行路径实现三维漫游的程序设计,沿线路方案漫游的固定高度和相对高度两种模式的程序设计,三维漫游控制和调整的程序设计,以及三维漫游的相关计算都进行了详细的讲解,每一部分都给出了完整的程序代码。   第4篇 线路三维可视化系统辅助功能实现   包括第11章显示模式控制及实现、第12章3D模型载入与应用、第13章系统输出接口与动录制实现和第14章系统简介与运行实例。   第11章 本章主要对双目立体方式、正射投影方式和透视投影方式的显示模型模式控制和实现、时钟指北针的程序设计和实现、缩略图的实现方法和程序设计进行了详细的讲解和说明。   第12章 本章主要对目前常用的3DS、AES、OBJ、MD2、MD3、MS3D等3D模型进行了介绍和说明,并给出了每种3D模型的示例,在此基础上,详细介绍了在OpenGL中应用3DS模型的两种主要方法:通过第三方软件对3DS模型进行转换和直接通过程序读取3DS模型;以桥墩3DS模型为例,给出了3DS模型在线路三维场景中的应用方法和程序设计实现。   第13章 介绍了DXF文件格式,详细讲解了DXF输出模块的程序设计,实现了线路三维模型输出到DXF文件,可以在AutoCAD中打开线路三维模型进行观察;设计了动录制类,实现将OpenGL录制到AVI文件中;设计了屏幕图形打印类,实现了对OpenGL屏幕图形的打印,在此基础上,设计录制屏幕图像模块,实现了将OpenGL录制为一系列图像并保存到硬盘中。   第14章 主要对所建立的三维可视化设计系统的主要特点和功能进行了介绍,对线路可视化设计系统加以总结,并对相应的功能模块进行集中说明,使读者能够对整个三维可视化设计有更加清晰的思路和概念,最后给出系统运行实例。   附录   包括附录A:相关数学程序模块;附录B:OpenGL核心函数库和应用函数库;附录C:OpenGL常用编程技巧;附录D:OpenGL资源网站。
第1篇 系统开发基础   包括第1章三维图形世界、第2章OpenGL概述和第3章Oracle与 OCI技术及编程基础。   第1章 介绍了计算机三维图形技术的发展、科学计算可视化技术、三维可视化工程设计的基本概念和发展现状。   第2章 主要对OpenGL的基本概念、OpenGL编程基础和在Visual C++环境下OpenGL基本程序框架的建立进行了讲解,并给出了一个简单的旋转立方体程序示例。通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。   第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,介绍了Oracle数据库的安装步骤和Oracle支持的数据类型。在此基础上,介绍了ADO、Pro*C/C++和OCI三个主要Oracle编程接口,对它们的各自功能和特点进行了详细说明,从功能方面、性能方面、开发难度方面进行了详细分析和比较。重点介绍OCI编程基础、OCI的数据结构、OCI程序的基本结构、OCI执行的步骤,最后给出了在Visual C++6.0环境下开发OCI应用程序的示例。   第2篇 大规模地形三维可视化系统设计与实现   包括第4章地形三维可视化系统框架与OCI类模块设计、第5章地形三维可视化系统的地形渲染实现和第6章地形三维可视化系统项目管理与辅助功能设计。   第4章 在第2章的基础上,完成了基于OpenGL的地形三维可视化系统程序框架的建立,为后续的功能模块开发提供了基础平台;在第3章的基础上,设计了OCI公共类,将所有与OCI有关的数据库操作、数据读取等功能函数实现全部封装在该类中,并定义了公共类的全局变量myOci。   第5章 本章对地形三维可视化进行了基本概述,介绍了目前地形三维可视化的主要算法。主要介绍了海量地形与影像纹理数据的常用获取方法,给出了海量地形自分块与影像纹理分块原则和程序实现,以及地形与影像子块调度的程序实现,在此基础上实现了地形的三维可视化;还介绍了真三维立体的实现算法和数学模型,在此基础上给出了基于OpenGL的真三维立体的程序实现。   第6章 主要讲解了新建项目、打开项目、背景天空的绘制、绘图模式控制的实现方法和程序设计。介绍了基于OpenGL深度缓存的二维屏幕坐标向三维空间坐标的转换算法,实现了对三维空间坐标和空间距离查询,以及查询标识设置的程序设计;最后讲解了基于键盘和鼠标联合控制的三维场景照相机程序模块的实现,实现三维场景的前、后、左、右移动和任意方向的旋转。   第3篇 线路三维可视化系统设计与实现   包括第7章三维交互技术与三维线路数据结构、第8章三维线路设计实现、第9章道路整体三维建模和第10章三维漫游的实现。   第7章 主要对三维交互环境进行了介绍,详细讲解了正射投影模式的实现、正射投影模式下场景控制方法和程序设计,以及透视投影模式的实现方法;还讲解了正射投影模式和透视投影模式下三维地面坐标的获取原理、方法,在此基础上,设计了边坡数据结构、桥梁数据结构、隧道数据结构、水沟数据结构及线路数据结构,为实现三维线路设计做好了前期准备。   第8章 主要对线路方案的主要参数设计方法和程序实现、设计交点信息输入实现、线路中心线定位方法、设计方案的保存、平面方案的自动生成和程序设计、纵断面设计模块的实现、边坡模型的生成算法、线路路基三维建模方法和实现、隧道三维建模和参数控制、桥梁三维建模和参数控制的程序设计进行了详细讲解。   第9章 主要讲解了道路整体三维模型实现,对其中的线路封闭区域确定与分割算法、地形块综合数据点计算、分块TIN模型的构网实现、封闭区域内数据点的剔除、整体构网的程序实现都进行了详细说明;在纹理管理部分,详细讲解了边坡纹理、路肩纹理、桥梁护坡面纹理、隧道内墙纹理、隧道洞门纹理的程序设计和实现。   第10章 从多个方面对三维漫游的基本概念、程序实现、参数调整和控制进行了讲解,帮助读者学会在三维可视化系统中三维漫游模块的程序设计方法;对飞行路径的基本概念、设置方法、插值算法、保存和打开的程序设计,沿飞行路径实现三维漫游的程序设计,沿线路方案漫游的固定高度和相对高度两种模式的程序设计,三维漫游控制和调整的程序设计,以及三维漫游的相关计算都进行了详细的讲解,每一部分都给出了完整的程序代码。   第4篇 线路三维可视化系统辅助功能实现   包括第11章显示模式控制及实现、第12章3D模型载入与应用、第13章系统输出接口与动录制实现和第14章系统简介与运行实例。   第11章 本章主要对双目立体方式、正射投影方式和透视投影方式的显示模型模式控制和实现、时钟指北针的程序设计和实现、缩略图的实现方法和程序设计进行了详细的讲解和说明。   第12章 本章主要对目前常用的3DS、AES、OBJ、MD2、MD3、MS3D等3D模型进行了介绍和说明,并给出了每种3D模型的示例,在此基础上,详细介绍了在OpenGL中应用3DS模型的两种主要方法:通过第三方软件对3DS模型进行转换和直接通过程序读取3DS模型;以桥墩3DS模型为例,给出了3DS模型在线路三维场景中的应用方法和程序设计实现。   第13章 介绍了DXF文件格式,详细讲解了DXF输出模块的程序设计,实现了线路三维模型输出到DXF文件,可以在AutoCAD中打开线路三维模型进行观察;设计了动录制类,实现将OpenGL录制到AVI文件中;设计了屏幕图形打印类,实现了对OpenGL屏幕图形的打印,在此基础上,设计录制屏幕图像模块,实现了将OpenGL录制为一系列图像并保存到硬盘中。   第14章 主要对所建立的三维可视化设计系统的主要特点和功能进行了介绍,对线路可视化设计系统加以总结,并对相应的功能模块进行集中说明,使读者能够对整个三维可视化设计有更加清晰的思路和概念,最后给出系统运行实例。   附录   包括附录A:相关数学程序模块;附录B:OpenGL核心函数库和应用函数库;附录C:OpenGL常用编程技巧;附录D:OpenGL资源网站。
第1篇 系统开发基础   包括第1章三维图形世界、第2章OpenGL概述和第3章Oracle与 OCI技术及编程基础。   第1章 介绍了计算机三维图形技术的发展、科学计算可视化技术、三维可视化工程设计的基本概念和发展现状。   第2章 主要对OpenGL的基本概念、OpenGL编程基础和在Visual C++环境下OpenGL基本程序框架的建立进行了讲解,并给出了一个简单的旋转立方体程序示例。通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。   第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,介绍了Oracle数据库的安装步骤和Oracle支持的数据类型。在此基础上,介绍了ADO、Pro*C/C++和OCI三个主要Oracle编程接口,对它们的各自功能和特点进行了详细说明,从功能方面、性能方面、开发难度方面进行了详细分析和比较。重点介绍OCI编程基础、OCI的数据结构、OCI程序的基本结构、OCI执行的步骤,最后给出了在Visual C++6.0环境下开发OCI应用程序的示例。   第2篇 大规模地形三维可视化系统设计与实现   包括第4章地形三维可视化系统框架与OCI类模块设计、第5章地形三维可视化系统的地形渲染实现和第6章地形三维可视化系统项目管理与辅助功能设计。   第4章 在第2章的基础上,完成了基于OpenGL的地形三维可视化系统程序框架的建立,为后续的功能模块开发提供了基础平台;在第3章的基础上,设计了OCI公共类,将所有与OCI有关的数据库操作、数据读取等功能函数实现全部封装在该类中,并定义了公共类的全局变量myOci。   第5章 本章对地形三维可视化进行了基本概述,介绍了目前地形三维可视化的主要算法。主要介绍了海量地形与影像纹理数据的常用获取方法,给出了海量地形自分块与影像纹理分块原则和程序实现,以及地形与影像子块调度的程序实现,在此基础上实现了地形的三维可视化;还介绍了真三维立体的实现算法和数学模型,在此基础上给出了基于OpenGL的真三维立体的程序实现。   第6章 主要讲解了新建项目、打开项目、背景天空的绘制、绘图模式控制的实现方法和程序设计。介绍了基于OpenGL深度缓存的二维屏幕坐标向三维空间坐标的转换算法,实现了对三维空间坐标和空间距离查询,以及查询标识设置的程序设计;最后讲解了基于键盘和鼠标联合控制的三维场景照相机程序模块的实现,实现三维场景的前、后、左、右移动和任意方向的旋转。   第3篇 线路三维可视化系统设计与实现   包括第7章三维交互技术与三维线路数据结构、第8章三维线路设计实现、第9章道路整体三维建模和第10章三维漫游的实现。   第7章 主要对三维交互环境进行了介绍,详细讲解了正射投影模式的实现、正射投影模式下场景控制方法和程序设计,以及透视投影模式的实现方法;还讲解了正射投影模式和透视投影模式下三维地面坐标的获取原理、方法,在此基础上,设计了边坡数据结构、桥梁数据结构、隧道数据结构、水沟数据结构及线路数据结构,为实现三维线路设计做好了前期准备。   第8章 主要对线路方案的主要参数设计方法和程序实现、设计交点信息输入实现、线路中心线定位方法、设计方案的保存、平面方案的自动生成和程序设计、纵断面设计模块的实现、边坡模型的生成算法、线路路基三维建模方法和实现、隧道三维建模和参数控制、桥梁三维建模和参数控制的程序设计进行了详细讲解。   第9章 主要讲解了道路整体三维模型实现,对其中的线路封闭区域确定与分割算法、地形块综合数据点计算、分块TIN模型的构网实现、封闭区域内数据点的剔除、整体构网的程序实现都进行了详细说明;在纹理管理部分,详细讲解了边坡纹理、路肩纹理、桥梁护坡面纹理、隧道内墙纹理、隧道洞门纹理的程序设计和实现。   第10章 从多个方面对三维漫游的基本概念、程序实现、参数调整和控制进行了讲解,帮助读者学会在三维可视化系统中三维漫游模块的程序设计方法;对飞行路径的基本概念、设置方法、插值算法、保存和打开的程序设计,沿飞行路径实现三维漫游的程序设计,沿线路方案漫游的固定高度和相对高度两种模式的程序设计,三维漫游控制和调整的程序设计,以及三维漫游的相关计算都进行了详细的讲解,每一部分都给出了完整的程序代码。   第4篇 线路三维可视化系统辅助功能实现   包括第11章显示模式控制及实现、第12章3D模型载入与应用、第13章系统输出接口与动录制实现和第14章系统简介与运行实例。   第11章 本章主要对双目立体方式、正射投影方式和透视投影方式的显示模型模式控制和实现、时钟指北针的程序设计和实现、缩略图的实现方法和程序设计进行
第1篇 系统开发基础   包括第1章三维图形世界、第2章OpenGL概述和第3章Oracle与 OCI技术及编程基础。   第1章 介绍了计算机三维图形技术的发展、科学计算可视化技术、三维可视化工程设计的基本概念和发展现状。   第2章 主要对OpenGL的基本概念、OpenGL编程基础和在Visual C++环境下OpenGL基本程序框架的建立进行了讲解,并给出了一个简单的旋转立方体程序示例。通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。   第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,介绍了Oracle数据库的安装步骤和Oracle支持的数据类型。在此基础上,介绍了ADO、Pro*C/C++和OCI三个主要Oracle编程接口,对它们的各自功能和特点进行了详细说明,从功能方面、性能方面、开发难度方面进行了详细分析和比较。重点介绍OCI编程基础、OCI的数据结构、OCI程序的基本结构、OCI执行的步骤,最后给出了在Visual C++6.0环境下开发OCI应用程序的示例。   第2篇 大规模地形三维可视化系统设计与实现   包括第4章地形三维可视化系统框架与OCI类模块设计、第5章地形三维可视化系统的地形渲染实现和第6章地形三维可视化系统项目管理与辅助功能设计。   第4章 在第2章的基础上,完成了基于OpenGL的地形三维可视化系统程序框架的建立,为后续的功能模块开发提供了基础平台;在第3章的基础上,设计了OCI公共类,将所有与OCI有关的数据库操作、数据读取等功能函数实现全部封装在该类中,并定义了公共类的全局变量myOci。   第5章 本章对地形三维可视化进行了基本概述,介绍了目前地形三维可视化的主要算法。主要介绍了海量地形与影像纹理数据的常用获取方法,给出了海量地形自分块与影像纹理分块原则和程序实现,以及地形与影像子块调度的程序实现,在此基础上实现了地形的三维可视化;还介绍了真三维立体的实现算法和数学模型,在此基础上给出了基于OpenGL的真三维立体的程序实现。   第6章 主要讲解了新建项目、打开项目、背景天空的绘制、绘图模式控制的实现方法和程序设计。介绍了基于OpenGL深度缓存的二维屏幕坐标向三维空间坐标的转换算法,实现了对三维空间坐标和空间距离查询,以及查询标识设置的程序设计;最后讲解了基于键盘和鼠标联合控制的三维场景照相机程序模块的实现,实现三维场景的前、后、左、右移动和任意方向的旋转。   第3篇 线路三维可视化系统设计与实现   包括第7章三维交互技术与三维线路数据结构、第8章三维线路设计实现、第9章道路整体三维建模和第10章三维漫游的实现。   第7章 主要对三维交互环境进行了介绍,详细讲解了正射投影模式的实现、正射投影模式下场景控制方法和程序设计,以及透视投影模式的实现方法;还讲解了正射投影模式和透视投影模式下三维地面坐标的获取原理、方法,在此基础上,设计了边坡数据结构、桥梁数据结构、隧道数据结构、水沟数据结构及线路数据结构,为实现三维线路设计做好了前期准备。   第8章 主要对线路方案的主要参数设计方法和程序实现、设计交点信息输入实现、线路中心线定位方法、设计方案的保存、平面方案的自动生成和程序设计、纵断面设计模块的实现、边坡模型的生成算法、线路路基三维建模方法和实现、隧道三维建模和参数控制、桥梁三维建模和参数控制的程序设计进行了详细讲解。   第9章 主要讲解了道路整体三维模型实现,对其中的线路封闭区域确定与分割算法、地形块综合数据点计算、分块TIN模型的构网实现、封闭区域内数据点的剔除、整体构网的程序实现都进行了详细说明;在纹理管理部分,详细讲解了边坡纹理、路肩纹理、桥梁护坡面纹理、隧道内墙纹理、隧道洞门纹理的程序设计和实现。   第10章 从多个方面对三维漫游的基本概念、程序实现、参数调整和控制进行了讲解,帮助读者学会在三维可视化系统中三维漫游模块的程序设计方法;对飞行路径的基本概念、设置方法、插值算法、保存和打开的程序设计,沿飞行路径实现三维漫游的程序设计,沿线路方案漫游的固定高度和相对高度两种模式的程序设计,三维漫游控制和调整的程序设计,以及三维漫游的相关计算都进行了详细的讲解,每一部分都给出了完整的程序代码。   第4篇 线路三维可视化系统辅助功能实现   包括第11章显示模式控制及实现、第12章3D模型载入与应用、第13章系统输出接口与动录制实现和第14章系统简介与运行实例。   第11章 本章主要对双目立体方式、正射投影方式和透视投影方式的显示模型模式控制和实现、时钟指北针的程序设计和实现、缩略图的实现方法和程序设计进行
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值