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

来源:互联网 发布:死神vs火影月改优化版 编辑:程序博客网 时间:2024/06/10 21:28

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

两个三角形需要六个顶点, 只要将前面的例子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 buffer107         GLfloat vertices[4][2] = {108         { -0.8, -0.9 },  // correspond to index 0109         { -0.8, 0.9 },   // index 1110         { 0.8, 0.9 },    // index 2111         { 0.8, -0.9 }    // index 3112         };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 buffer119         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();    }
运行此程序即可得到上图所示的矩形。

0 0
原创粉丝点击