OpenGL入门(二)-基本图元绘制

OpenGL与着色器

在OpenGL 3.0之前,OpenGL包含一个固定功能的管线,它可以在不使用着色器的情况下处理几何与像素数据。从3.1版本开始,固定管线从核心模式去掉。因此现在需要使用着色器来完成工作.
我们会使用GLSL,(OpenGL Shading Language,它是在OpenGL 2.0版本发布的)。 语法与“C、C++”类似。

基础图形管线

OpenGL中的图元只不过是顶点的集合以预定义的方式结合在一起。
管线分为:2个部分,上半部分是 客户机端,下半部分是服务器端。
服务器 和 客户端 在功能和运行上都是异步的。它们是各自独立的软件块或硬件块。


OpenGL入门(二)-基本图元绘制_第1张图片
image.png

三种向OpenGL 着色器传递渲染数据的方法:

  • 属性:

就是对一个顶点都要作改变的数据元素。实际上,顶点位置本身就是一个属性。属性可以是浮点类型、整型、布尔类型.

  • Uniform:

通过设置Uniform 变量发送一个图元批次命令。Uniform 变量实际上可以无限次限制地使用,比如设置一个应用于整个表面的单个颜色值。还可以设置一个时间值

  • 纹理

基本图元类型

OpenGL入门(二)-基本图元绘制_第2张图片
image.png

OpenGL入门(二)-基本图元绘制_第3张图片
image.png
  • 注意着重区分以下三种绘制方式的区别


    OpenGL入门(二)-基本图元绘制_第4张图片
    image.png

    OpenGL入门(二)-基本图元绘制_第5张图片
    image.png
OpenGL入门(二)-基本图元绘制_第6张图片
image.png

OpenGL入门(二)-基本图元绘制_第7张图片
image.png

存储着色器的使用

着色器有以下分类:
• 单位着色器
• 平面着色器
• 上色着色器
• 默认光源着色器
• 点光源着色器
• 纹理替换矩阵
• 纹理调整着色器
• 纹理光源着色器

//定义着色器
GLShaderMananger shaderManager;
//初始化着色器 
shaderManager.InitalizeStockShaders()
//使用
shaderManager userStockManager(参数列表)
单位着色器

GLShaderManager::UserStockShader(GLT_ATTRIBUTE_VERTEX,GLfloat vColor[4]);

平面着色器

GLShaderManager::UserStockShader(GLT_SHADER_FLAT,GLfloat mvp[16],GLfloat vColor[4]);

上色着色器

GLShaderManager::UserStockShader(GLT_SHADER_SHADED,GLfloat mvp[16]);

默认光源着色器

GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vColor[4]);

点光源着色器

GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vColor[4]);

纹理替换矩阵着色器

GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat mvMatrix[16],GLint nTextureUnit);

纹理调整着色器

GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);

纹理光源着色器

GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vBaseColor[4],GLint nTextureUnit);

绘制不同类型的图元

// 各种需要的类
GLShaderManager     shaderManager;
GLMatrixStack       modelViewMatrix;
GLMatrixStack       projectionMatrix;
GLFrame             cameraFrame;
GLFrame             objectFrame;
//投影矩阵
GLFrustum           viewFrustum;

//容器类(7种不同的图元对应7种容器对象)
GLBatch             pointBatch;
GLBatch             lineBatch;
GLBatch             lineStripBatch;
GLBatch             lineLoopBatch;
GLBatch             triangleBatch;
GLBatch             triangleStripBatch;
GLBatch             triangleFanBatch;

//几何变换的管道
GLGeometryTransform transformPipeline;
M3DMatrix44f        shadowMatrix;
点/线/线段/线环绘制
// 准备一些随机点数据
    GLfloat vCoast[24][3] = {
        {2.80, 1.20, 0.0 }, {2.0,  1.20, 0.0 },
        {2.0,  1.08, 0.0 },  {2.0,  1.08, 0.0 },
        {0.0,  0.80, 0.0 },  {-.32, 0.40, 0.0 },
        {-.48, 0.2, 0.0 },   {-.40, 0.0, 0.0 },
        {-.60, -.40, 0.0 },  {-.80, -.80, 0.0 },
        {-.80, -1.4, 0.0 },  {-.40, -1.60, 0.0 },
        {0.0, -1.20, 0.0 },  { .2, -.80, 0.0 },
        {.48, -.40, 0.0 },   {.52, -.20, 0.0 },
        {.48,  .20, 0.0 },   {.80,  .40, 0.0 },
        {1.20, .80, 0.0 },   {1.60, .60, 0.0 },
        {2.0, .60, 0.0 },    {2.2, .80, 0.0 },
        {2.40, 1.0, 0.0 },   {2.80, 1.0, 0.0 }};
    
    //用点的形式绘制(GL_POINTS)
    pointBatch.Begin(GL_POINTS, 24);
    pointBatch.CopyVertexData3f(vCoast);
    pointBatch.End();
    
    //通过线的形式绘制(GL_LINES)
    lineBatch.Begin(GL_LINES, 24);
    lineBatch.CopyVertexData3f(vCoast);
    lineBatch.End();
    
    //通过线段的形式绘制(GL_LINE_STRIP)
    lineStripBatch.Begin(GL_LINE_STRIP, 24);
    lineStripBatch.CopyVertexData3f(vCoast);
    lineStripBatch.End();
    
    //通过线环的形式绘制(GL_LINE_LOOP)
    lineLoopBatch.Begin(GL_LINE_LOOP, 24);
    lineLoopBatch.CopyVertexData3f(vCoast);
    lineLoopBatch.End();
  • 效果如下:


    OpenGL入门(二)-基本图元绘制_第8张图片
    点.png

    OpenGL入门(二)-基本图元绘制_第9张图片
    线.png

    OpenGL入门(二)-基本图元绘制_第10张图片
    线段.png

    OpenGL入门(二)-基本图元绘制_第11张图片
    线环.png
三角形绘制方式 - GL_TRIANGLES
    //通过三角形绘制(GL_TRIANGLES) -- 生成一个金字塔的形状
    GLfloat vPyramid[12][3] = {
        -2.0f, 0.0f, -2.0f,
        2.0f, 0.0f, -2.0f,
        0.0f, 4.0f, 0.0f,
        
        2.0f, 0.0f, -2.0f,
        2.0f, 0.0f, 2.0f,
        0.0f, 4.0f, 0.0f,
        
        2.0f, 0.0f, 2.0f,
        -2.0f, 0.0f, 2.0f,
        0.0f, 4.0f, 0.0f,
        
        -2.0f, 0.0f, 2.0f,
        -2.0f, 0.0f, -2.0f,
        0.0f, 4.0f, 0.0f};
    
    //GL_TRIANGLES 每3个顶点定义一个新的三角形
    triangleBatch.Begin(GL_TRIANGLES, 12);
    triangleBatch.CopyVertexData3f(vPyramid);
    triangleBatch.End();
  • 效果图:


    OpenGL入门(二)-基本图元绘制_第12张图片
    GL_TRIANGLES.png
三角形扇绘制方式 - GL_TRIANGLE_FAN
    // 三角形扇绘制(GL_TRIANGLE_FAN) -- 生成一个六边形
    GLfloat vPoints[100][3];    //超过我们需要的数组
    int nVerts = 0;
    //半径
    GLfloat r = 3.0f;
    
    //原点(x,y,z) = (0,0,0);
    vPoints[nVerts][0] = 0.0f;
    vPoints[nVerts][1] = 0.0f;
    vPoints[nVerts][2] = 0.0f;
    
    //M3D_2PI 就是2Pi 的意思,就一个圆的意思。 绘制圆形
    
    for(GLfloat angle = 0; angle < M3D_2PI; angle += M3D_2PI / 6.0f) {
        
        //数组下标自增(每自增1次就表示一个顶点)
        nVerts++;
        /*
         弧长=半径*角度,这里的角度是弧度制,不是平时的角度制
         既然知道了cos值,那么角度=arccos,求一个反三角函数就行了
         */
        //x点坐标 cos(angle) * 半径
        vPoints[nVerts][0] = float(cos(angle)) * r;
        //y点坐标 sin(angle) * 半径
        vPoints[nVerts][1] = float(sin(angle)) * r;
        //z点的坐标
        vPoints[nVerts][2] = -0.5f;
    }
    
    // 结束扇形 : 前面一共绘制7个顶点(包括圆心)
    printf("三角形扇形顶点数:%d\n",nVerts);
    //添加闭合的终点, 若不添加, 则三角形扇形是无法闭合的。
    nVerts++;
    vPoints[nVerts][0] = r;
    vPoints[nVerts][1] = 0;
    vPoints[nVerts][2] = 0.0f;
    
    //GL_TRIANGLE_FAN 以一个圆心为中心呈扇形排列,共用相邻顶点的一组三角形
    triangleFanBatch.Begin(GL_TRIANGLE_FAN, 8);
    triangleFanBatch.CopyVertexData3f(vPoints);
    triangleFanBatch.End();
  • 效果图:


    OpenGL入门(二)-基本图元绘制_第13张图片
    GL_TRIANGLE_FAN.png
三角形条带绘制方式 - GL_TRIANGLE_STRIP
    //三角形条带绘制(GL_TRIANGLE_STRIP) -- 生成一个小环或圆柱段
    //顶点下标
    int iCounter = 0;
    //半径
    GLfloat radius = 3.0f;
    //从0度~360度,以0.3弧度为步长
    for(GLfloat angle = 0.0f; angle <= (2.0f*M3D_PI); angle += 0.3f)
    {
        //或许圆形的顶点的X,Y
        GLfloat x = radius * sin(angle);
        GLfloat y = radius * cos(angle);
        
        //绘制2个三角形(他们的x,y顶点一样,只是z点不一样)
        vPoints[iCounter][0] = x;
        vPoints[iCounter][1] = y;
        vPoints[iCounter][2] = -0.5;
        iCounter++;
        
        vPoints[iCounter][0] = x;
        vPoints[iCounter][1] = y;
        vPoints[iCounter][2] = 0.5;
        iCounter++;
    }
    
    // 关闭循环
    printf("三角形带的顶点数:%d\n",iCounter);
    //结束循环,在循环位置生成2个三角形
    vPoints[iCounter][0] = vPoints[0][0];
    vPoints[iCounter][1] = vPoints[0][1];
    vPoints[iCounter][2] = -0.5;
    iCounter++;
    
    vPoints[iCounter][0] = vPoints[1][0];
    vPoints[iCounter][1] = vPoints[1][1];
    vPoints[iCounter][2] = 0.5;
    iCounter++;
    
    // GL_TRIANGLE_STRIP 共用一个条带(strip)上的顶点的一组三角形
    triangleStripBatch.Begin(GL_TRIANGLE_STRIP, iCounter);
    triangleStripBatch.CopyVertexData3f(vPoints);
    triangleStripBatch.End();
  • 效果图:


    OpenGL入门(二)-基本图元绘制_第14张图片
    GL_TRIANGLE_STRIP.png

你可能感兴趣的:(OpenGL入门(二)-基本图元绘制)