本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用。

顶点数组对象

  顶点数组对象负责管理一组顶点属性,顶点属性包括位置、法线、纹理坐标等。

OpenGL缓存

  OpenGL缓存实质上是OpenGL服务端的一块内存区域,用于存储数据。OpenGL的所有数据都是存储在缓存对象中的。

  在本次实践的思路是创建一个顶点数组对象来管理所绘制的三角性的顶点数据,数据存储在缓存对象中,然后使用绘制API绘制三角形。

  首先,创建顶点数组对象,函数原型:void genVertexArrays(GLsizei n, GLuint *arrays);其中n表示数量,结果保存在arrays中。

  然后使用glBindVertexArray绑定数组对象,那为什么需要绑定数组对象了?在使用OpenGL的过程中会生成的非常多的对象,每一种对象都会有许多的操作,如使用glVertexAttribPointer设置顶点数组对象的属性,在进行这些操作之前需要明确是对哪个对象进行操作,而绑定机制就是做这件事的。OpenGL绑定对象后,接下来的操作就表示作用于这个对象。示例如下:

    glGenVertexArrays(NumVAOs,VAOs);

    glBindVertexArray(VAOs[Triangles]);

  绑定好对象后我们就需要设置这个顶点数组对象所管理的顶点数据,这个时候就需要缓存了。创建和绑定类似顶点数组对象,但最后需要glBufferData来输入数据,示例如下:

         glGenBuffers(NumBuffers,Buffers);
glBindBuffer(GL_ARRAY_BUFFER,Buffers[ArrayBuffer]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

创建缓存

  glGenBuffers(GLsizei n, GLuint* buffers);//创建n个缓存对象,保存在buffers数组中

向缓存中输入或输出数据

  glBindBuffer(GLenum target, GLuint buffer); //绑定缓存到target指定的缓存结合点

  glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); //为绑定到target的缓存对象分配size大小的存储空间,如果data不为NULL,则使用data初始化所为配的存储空间。usage指示缓存中的数据可能具备的一些特定的用途。

  glBufferSubData(GLenum target, GLsizeiptr offset, GLsizeiptr size, const GLvoid* data);//使用新数据替换缓存中的部分数据

清除数据

  glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const GLvoid* data);  //使用data填充缓存存储空间,format和type指定data的数据格式和类型,填充前需要把data转化为internalformat

  glClearSubBufferData(GLenum target, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const GLvoid* data); //同上,区别是这个方法只填充offset和size指定的区域;

  

  接着我们需要设置顶点属性,使用glVertexAttribPointer.示例如下:

  glVertexAttribPointer(vPosition,2,GL_FLOAT,GL_FALSE,0,BUFFER_OFFSET(0));

设置顶点属性

  glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);

  

  这些都做好了之后,我们就可以使用顶点数组对象来绘制我们的三角形了。

    glBindVertexArray(VAOs[Triangles]);

    glDrawArrays(GL_TRIANGLES,0,NumVertices);

  使用顶点数据之前需要先绑定,表示当前绘制使用该对象。

绘制命令

  glDrawArrays(GLenum mode, GLint first, GLsizei count);//直接读取顶点数据绘制

  glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);基于索引绘制(即所有的顶点在一个数组中,使用索引来引用顶点数据)

具体的示例代码如下:

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "ShaderHelper.h" #define BUFFER_OFFSET(n) ((GLvoid*)n)
enum VAO_IDs { Triangles,NumVAOs};
enum Buffers_IDs { ArrayBuffer, NumBuffers }; enum Attrib_IDs { vPosition=0 }; GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers]; const GLuint NumVertices=6; void init();
void display(); int main(int argc,char* argv[])
{
glutInit(&argc,argv);
glutInitContextVersion(3,3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0,0);
glutInitWindowSize(300,300);
glutCreateWindow("Frame Buffer"); /* const GLubyte* name = glGetString(GL_VENDOR); //返回负责当前OpenGL实现厂商的名字
const GLubyte* biaoshifu = glGetString(GL_RENDERER); //返回一个渲染器标识符,通常是个硬>
件平台
const GLubyte* OpenGLVersion =glGetString(GL_VERSION); //返回当前OpenGL实现的版本号
const GLubyte* gluVersion= gluGetString(GLU_VERSION); //返回当前GLU工具库版本
printf("OpenGL实现厂商的名字:%s\n", name);
printf("渲染器标识符:%s\n", biaoshifu);
printf("OOpenGL实现的版本号:%s\n",OpenGLVersion );
printf("OGLU工具库版本:%s\n", gluVersion);*/
glewExperimental=GL_TRUE;
glewInit();
init();
glutDisplayFunc(display); glutMainLoop();
return 0;
} void init()
{
glClearColor(0.0,0.0,0.0,1.0);
glMatrixMode(GL_PROJECTION);
glOrtho(-5,5,-5,5,5,15);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0,0,10,0,0,0,0,1,0); glGenVertexArrays(NumVAOs,VAOs);
glBindVertexArray(VAOs[Triangles]); GLfloat vertices[NumVertices][2]={
{-0.90,-0.90},
{0.85, -0.90},
{ -0.90, 0.85 },
{ 0.90, -0.85 },
{ 0.90, 0.90 },
{-0.85, 0.90 },
}; glGenBuffers(NumBuffers,Buffers);
glBindBuffer(GL_ARRAY_BUFFER,Buffers[ArrayBuffer]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW); ShaderInfo shaders[] = {
{GL_VERTEX_SHADER,"triangles.vert"},
{GL_FRAGMENT_SHADER,"triangles.frag"},
{GL_NONE,NULL},
}; GLuint program = LoadShaders(shaders);
glUseProgram(program); glVertexAttribPointer(vPosition,2,GL_FLOAT,GL_FALSE,0,BUFFER_OFFSET(0)); glEnableVertexAttribArray(vPosition);
} void display()
{
glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(VAOs[Triangles]);
glDrawArrays(GL_TRIANGLES,0,NumVertices); glFlush();
}

注意:代码根据红宝书编写,一些辅助性代码(如LoadShader)并未贴出,详情请参照www.opengl-readbook.com。

GLEW说明

  GLEW(OpenGL Extension Wrangler) 是OpenGL的另一个辅助库,主要封装了从OpenGL库中获取函数地址的过程,还包含了一些可以跨平台使用的OpenGL编程方法。

最终的效果如下:

Linux OpenGL 实践篇-3 绘制三角形的更多相关文章

  1. iOS OpenGL ES简单绘制三角形

    OpenGL 是用于2D/3D图形编程的一套基于C语言的统一接口. windows,Linux,Unix上均可兼容. OpenGL ES 是在OpenGL嵌入式设备上的版本, android/iOS ...

  2. Android OpenGL 入门示例----绘制三角形和正方形

    Android上对OpenGl的支持是无缝的,所以才有众多3D效果如此逼真的游戏,在Camera的一些流程中也有用到GLSurfaceView的情况.本文记录OpenGL在Android上的入门级示例 ...

  3. Linux OpenGL 实践篇-4 坐标系统

    OpenGL中顶点经过顶点着色器后会变为标准设备坐标系.标准设备坐标系的各坐标的取值范围是[-1,1],超过这个范围的点将会被剔除.而这个变换的过程可描述为顶点在几个坐标系统的变换,这几个坐标系统为: ...

  4. Linux OpenGL 实践篇-16 文本绘制

    文本绘制 本文主要射击Freetype的入门理解和在OpenGL中实现文字的渲染. freetype freetype的官网,本文大部分内容参考https://www.freetype.org/fre ...

  5. Linux OpenGL 实践篇-14-多实例渲染

    多实例渲染 OpenGL的多实例渲染是一种连续执行多条相同的渲染命令的方法,并且每条命令产生的结果都有轻微的差异,通常用于渲染大量的几何物体. 设想一个场景,比如太空,我们需要渲染数以万记的星球,如果 ...

  6. Linux OpenGL 实践篇-13-geometryshader

    几何着色器 几何着色器是位于图元装配和片元着色器之前的一个着色器阶段,是一个可选阶段.它的输入是一个图元的完整的顶点信息,通常来自于顶点着色器,但如果细分计算着色器启用的话,那输入则是细分计算着色器的 ...

  7. Linux OpenGL 实践篇-5 纹理

    纹理 在之前的实践中,我们所渲染的物体的表面颜色都是纯色或者根据顶点位置计算出的一个颜色,这种方式在表现物体细节方面是比较吃资源的,因为我们每增加一个细节,我们就需要定义更多的顶点及其属性.所以美术人 ...

  8. Linux OpenGL 实践篇-2 创建一个窗口

    OpenGL 作为一个图形接口,并没有包含窗口的相关内容,但OpenGL使用必须依赖窗口,即必须在窗口中绘制.这就要求我们必须了解一种窗口系统,但不同的操作系统提供的创建窗口的API都不相同,如果我们 ...

  9. Linux OpenGL 实践篇-11-shadow

    OpenGL 阴影 在三维场景中,为了使场景看起来更加的真实,通常需要为其添加阴影,OpenGL可以使用很多种技术实现阴影,其中有一种非常经典的实现是使用一种叫阴影贴图的实现,在本节中我们将使用阴影贴 ...

随机推荐

  1. zabbix的各种键值

    zabbix服务器端通过与zabbix agent通信来获取客户端服务器的数据,agent分为两个版本,在配置主机我们可以看到一个是agent,另一个是agent(active). agent:zab ...

  2. 关于bootstrap的form表单的输入框间距样式

    <!-- 模态弹出窗内容 --> <div class="modal" tabindex="-1" role="dialog&quo ...

  3. STL --> string类字符串

    基本使用方法 一.输入 string s: cin >> s; getline(cin, s) ; //使用默认的'\n'作为终止符 getline(cin, s, '!') ; //以' ...

  4. SQL语法语句总结

    一.SQL语句语法 ALTER TABLE ALTER TABLE 用来更新已存在表的结构. ALTER TABLE tablename (ADD|DROP column datatype [NULL ...

  5. 用SQL语言操作数据

     使用T-SQL插入数据(一)SQL是什么?Structured   Query   Language  :结构化查询语言T-SQL:Transact-SQLT-SQL是SQL的增强版对功能进行了扩充 ...

  6. hibernate框架学习笔记7:HQL查询、Criteria查询简介

    HQL查询:hibernate独有的查询语言 适用于不复杂的多表查询 示例: 实体类: package domain; public class Customer { private Long cus ...

  7. Alpha冲刺No.10

    一.站立式会议 我们的阿尔法冲刺也基本宣告血崩,虽然很多功能已经实现,但是并没有串联在一起,好在这周不需要上课,我们也能好好睡一觉 实现手机的定位系统 细化界面设计 解决数据库和软件交互的一些问题 二 ...

  8. Beta冲刺NO.7

    Beta冲刺 第七天 昨天的困难 昨天的困难在一些多表查询上,不熟悉hibernate的套路,走了很多弯路. 第一次使用图表插件,在图表的显示问题上花了一定的时间. 对于页面绑定和后台数据自动填充的理 ...

  9. 2017-2018-1 我爱学Java 第六七周 作业

    团队六七周作业 完善版需求规格说明书 制定团队编码规范 数据库设计 后端架构设计 TODOList 参考资料 完善版需求规格说明书 <需求规格说明书>初稿不足之处: 1.开发工具写错 2. ...

  10. iOS开发点滴-添加阴影效果

    UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:_backView.bounds]; _backView.layer.masks ...