OpenGL基本图元练习

该案例主要是对常见的图元连接方式的运用,常见的图元在该链接中已经讲过,各图元的效果图如下:

image.png

在之前的博客里面有完成一个简单的三角形案例,在该案例中使用三个顶点绘制了一个三角形。
在该案例中,主要使用到几个函数:

  1. main函数:函数入口;
  2. ChangeSize函数:设置视口大小,也可以该函数中设置投影方式等。
  3. SetupRC函数:设置顶点数据以及图元装配方式。
  4. RenderScene函数:用于图形绘制,可手动触发也由系统触发。
  5. SpecialKeys函数:针对特殊键位处理的回调函数。
  6. KeyPressFunc函数:针对空格处理的回调函数。
  7. DrawWireFrameBatch函数:用于立体图形的填充和边框绘制。

接下来,根据我们所需要绘制的图形,对各函数进行讲解。

1. 点、线段、线环

绘制点、线段、线环这三种方式都较为简单。

  1. 在SetupRC函数里面设置顶点数据,图元装配方式等,并将数据copy到着色器。
//顶点数据
GLfloat vCoast[9] = {
        3,3,0,0,3,0,3,0,0
    };
    //图元装配选择点
    pointBatch.Begin(GL_POINTS, 3);
    pointBatch.CopyVertexData3f(vCoast);
    pointBatch.End();

    //图元装配选择线
    lineBatch.Begin(GL_LINES, 3);
    lineBatch.CopyVertexData3f(vCoast);
    lineBatch.End();

    //图元装配选择线段
    lineStripBatch.Begin(GL_LINE_STRIP, 3);
    lineStripBatch.CopyVertexData3f(vCoast);
    lineStripBatch.End();

    //图元装配选择线环
    lineLoopBatch.Begin(GL_LINE_LOOP, 3);
    lineLoopBatch.CopyVertexData3f(vCoast);
    lineLoopBatch.End();
  1. 在RenderScene函数里面进行绘制
    //点
    glPointSize(4.0f);
    pointBatch.Draw();
    glPointSize(1.0f);

    //线
    glPointSize(4.0f);
    lineBatch.Draw();
    glPointSize(1.0f);

    //线段
    glPointSize(4.0f);
    lineStripBatch.Draw();
    glPointSize(1.0f);

    //线环
    glPointSize(4.0f);
    lineLoopBatch.Draw();
    glPointSize(1.0f);

2. 绘制金字塔、六边形、圆环

  1. changeSize函数
    在前面的案例里面,changeSize主要用来设置视口大小,而在本案例中,还需要设置投影方式。
    由于后面需要获取模型视图投影矩阵,因此,先在这个函数里面初始化模型视图矩阵堆栈,并往栈里面写入一个单元矩阵。
    viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 500.0f);
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    modelViewMatrix.LoadIdentity();
  1. SetupRC函数
    1. 将模型视图矩阵和投影矩阵放到变换管道中,变换管道的作用是能帮助快速进行矩阵相乘,在RenderScene函数中可以直接通过变换管道的Get方法得到相应的矩阵。
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
2. 设置观察者的位置
cameraFrame.MoveForward(-30.0f);
  1. RenderScene函数
    1. RenderScene函数中,可以对模型视图矩阵堆栈中再添加一个单元矩阵,这主要是为了绘制完成后,矩阵可以恢复至最开始的样子。
modelViewMatrix.PushMatrix();
  • 2.将cameraFrame构建为观察者矩阵,并将它与模型视图矩阵堆栈的栈顶相乘,得到的结果再压入模型视图矩阵堆栈。
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
    1. 将objectFrame构建为物体矩阵,并将它与模型视图矩阵堆栈的栈顶相乘,得到的结果再压入模型视图矩阵堆栈。
M3DMatrix44f mObject;
objectFrame.GetMatrix(mObject);
modelViewMatrix.MultMatrix(mObject);
    1. 然后利用固定管线渲染图形,在图像渲染完成后,将栈中模型视图矩阵pop,恢复其初始状态。
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
modelViewMatrix.PopMatrix();

3. 给金字塔增加边框

在步骤二的时候,已经将金字塔绘制到屏幕上,但是有个问题,由于没有边框,所以并不能通过屏幕直接看出来那是金字塔,这个时候就得给金字塔加上边框,才能显得图形更加立体。

    1. 开启多边形绘制,设置偏移量
glPolygonOffset(-1.0f, -1.0f);
glEnable(GL_POLYGON_OFFSET_LINE);
    1. 开启抗锯齿功能,使得线条更加平滑
glEnable(GL_LINE_SMOOTH);
    1. 开启颜色混合
glEnable(GL_BLEND);
    1. 绘制边框、设置线条宽度
    //绘制线框几何黑色版 三种模式,实心,边框,点,可以作用在正面,背面,或者两面
    //通过调用glPolygonMode将多边形正面或者背面设为线框模式,实现线框渲染
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //设置线条宽度
    glLineWidth(2.5f);

    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    pBatch->Draw();
    1. 还原设置属性
    //通过调用glPolygonMode将多边形正面或者背面设为全部填充模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_POLYGON_OFFSET_LINE);
    glLineWidth(1.0f);
    glDisable(GL_BLEND);
    glDisable(GL_LINE_SMOOTH);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352