跟我一起学OpenGL-矩形之index buffer的使用

上一篇文章讲述了如何画一个三角形, 这篇文章讲如何画一个矩形。 大家肯定会想到两个三角形拼起来以后不就是个矩形吗, 思路就是这样的。

两个三角形需要六个顶点, 只要将前面的例子init_data部分做下修改,传进去6个顶点即可,代码如下:

void init_data()
{
    ...
/*      
 97         GLfloat vertices[3][2] = {
 98         { -0.8, -0.9 },
 99         { 0.8, -0.9 },
100         { 0, 0.9 },
101         };
102 */
103         GLfloat vertices[6][2] = {                                                                                                                                                                       
104         { -0.8, -0.9 },
105         { -0.8, 0.9 },
106         { 0.8, -0.9 },
107         { 0.8, -0.9 },
108         { -0.8, 0.9 },
109         { 0.8, 0.9 }
110         };
    ...
 }
在Draw的时候改变图形个数
glDrawArrays(GL_TRIANGLES, 0, 6);
即可绘制矩形, 效果如下:


但是从上面可以看出使用glDrawArrays画矩形需要六个顶点, 有的顶点重复定义了两次,这样浪费了资源。实际上矩形只需要定义4个顶点就可以了,下面就是index buffer的使用

使用glDrawElements来画矩形。 代码如下:

  1 #include <GL/glew.h> 
  2 #include <GL/freeglut.h>
  3 #include <iostream>
  4 #define BUFFER_OFFSET(x) ((const void*) (x))
  5 
  6 enum VAO_IDs {Triangles, NumVAOs};
  7 enum Buffer_IDs {ArrayBuffer, NumBuffers};
  8 enum Attrib_IDs {vPosition = 0};
  9 
 10 GLuint VAOs[NumVAOs];
 11 GLuint Buffers[NumBuffers];
 12 GLuint program;
 13 
 14 // index number
 15 GLuint indices[] = {
 16         0, 1, 3,
 17         1, 2, 3
 18 };
 19 
 20 const GLchar* vertex_shader = "#version 430 core \n"
 21                                 "layout(location = 0)\n"
 22                                 "in vec4 vPosition;\n"
 23                                 "void main()\n"
 24                                 "{\n"
 25                                 "gl_Position = vPosition;\n"
 26                                 "}\n";
 27 
 28 const GLchar* fragment_shader = "#version 430 core \n"
 29                                 "uniform vec4 color;\n"
 30                                 "out vec4 fColor;\n"
 31                                 "void main()\n"
 32                                 "{\n"
 33                                 "fColor = color;\n"
 34                                 "}\n";
 35 
 36 void init_shader()
 37 {
 38         // vertex shader
 39         GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
 40         glShaderSource(vertexShader, 1, &vertex_shader, NULL);
 41         glCompileShader(vertexShader);
 42         // check vertex shader compiling status
 43         GLint compiled;
 44         GLchar log[256];
 45         glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled);
 46         if (!compiled)
 47         {
 48                 glGetShaderInfoLog(vertexShader, 256, NULL, log);
 49                 std::cerr << "vertex shader compile failed" << log << std::endl;
 50         }
 51 
 52         // fragment shader
 53         GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
 54         glShaderSource(fragmentShader, 1, &fragment_shader, NULL);
 55         glCompileShader(fragmentShader);
             // check fragment shader compiling status
 57         glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled);
 58         if (!compiled)
 59         {
 60                 glGetShaderInfoLog(fragmentShader, 256, NULL, log);
 61                 std::cerr << "fragment shader compile failed" << log << std::endl;
 62         }
 63         
 64         // link shaders
 65         program = glCreateProgram();
 66         glAttachShader(program, vertexShader);
 67         glAttachShader(program, fragmentShader);
 68         glLinkProgram(program);
 69         //check link status
 70         GLint linked;
 71         glGetProgramiv(program, GL_LINK_STATUS, &linked);
 72         if (!linked)
 73         {
 74                 glGetProgramInfoLog(program, 256, NULL, log);
 75                 std::cerr << "shader linking failed" << log << std::endl;
 76         }
 77         // delete shader
 78         glDeleteShader(vertexShader);
 79         glDeleteShader(fragmentShader);
 80 }
 81 
 82 void init_data()
 83 {
 84         glClearColor(1, 1, 1, 0);
 85         glClear(GL_COLOR_BUFFER_BIT);
 86         
 87         glGenVertexArrays(NumVAOs, VAOs);
 88         glBindVertexArray(VAOs[Triangles]);
 89         
 90 /*      
 91         GLfloat vertices[3][2] = {
 92         { -0.8, -0.9 },
 93         { 0.8, -0.9 },
 94         { 0, 0.9 },
 95         };
 96 
 97         GLfloat vertices[6][2] = {
 98         { -0.8, -0.9 },
 99         { -0.8, 0.9 },
100         { 0.8, -0.9},
101         { 0.8, -0.9 },
102         { -0.8, 0.9},
103         { 0.8, 0.9}
       };
105 */      
106         // only use four vertices when use index buffer
107         GLfloat vertices[4][2] = {
108         { -0.8, -0.9 },  // correspond to index 0
109         { -0.8, 0.9 },   // index 1
110         { 0.8, 0.9 },    // index 2
111         { 0.8, -0.9 }    // index 3
112         };
113         
114         glGenBuffers(NumBuffers, Buffers);
115         glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
116         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
117         
118         // use element array buffer
119         GLuint ebo;             
120         glGenBuffers(1, &ebo);
121         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
122         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
123         
124         glUseProgram(program);
125         GLint loc = glGetUniformLocation(program, "color");
126         glUniform4f(loc, 1.0f, 0.0f, 0.0f, 1.0f);
127         glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
128         glEnableVertexAttribArray(vPosition);
129 }
130 
131 void display()
132 {
133         glClear(GL_COLOR_BUFFER_BIT);
134 
135         glBindVertexArray(VAOs[Triangles]);
136 //      glDrawArrays(GL_TRIANGLES, 0, 6);
137         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
138         glFlush();
139 }
140 
141 int main(int argc, char* argv[])
142 {
143         glutInit(&argc, argv);
144         glutInitDisplayMode(GLUT_RGBA);
145         glutInitWindowSize(300 ,300);
146         glutInitWindowPosition(100, 100);
147         glutCreateWindow("Learn opengl: draw quad");
148         
149         glewExperimental = GL_TRUE;
150         if(glewInit())
151         {
152                 std::cout << "Unable to Initialize" << std::endl;
153                 exit(1);
154         }
155         init_shader();
156         init_data();
157         glutDisplayFunc(display);   
158         glutMainLoop();    
}
运行此程序即可得到上图所示的矩形。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值