上一篇文章中也使用了比较老的方法glBegin 和 glEnd的方法来绘制了简单的集合图元,现在使用比较新的而且更高效的方法来绘制简单的集合图元。
这种方法与以前方法的不同点在对数据的处理上,glBegin 和 glEnd是要给出数据,然后直接来进行绘制,然而新的方法是现将数据保存到显存中,然后直接一个绘制命令,就可以直接从显卡内存中直接读取数据进行绘制,效率更高而且更方便。
#include <GL/glew.h> #include <GL/freeglut.h> #include <iostream> #include "rshader.h" using namespace std; GLuint vao; void display() { GLuint vbo; GLuint ebo; GLfloat v_position[] = { 0.0f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, }; GLushort indecise[] = { 0, 1, 1, 2, 2, 0 }; glClear(GL_COLOR_BUFFER_BIT); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(v_position), v_position, GL_STATIC_DRAW); glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indecise), indecise, GL_STATIC_DRAW); const char *vershader = read("vershader.txt"); GLuint vshader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vshader, 1, &vershader, NULL); glCompileShader(vshader); GLint status; glGetShaderiv(vshader, GL_COMPILE_STATUS, &status); const char *fragshader = read("fragshader.txt"); GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fshader, 1, &fragshader, NULL); glCompileShader(fshader); GLuint program = glCreateProgram(); glAttachShader(program, vshader); glAttachShader(program, fshader); glLinkProgram(program); glUseProgram(program); GLint posAttrib = glGetAttribLocation(program, "position"); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(posAttrib); //glDrawArrays(GL_LINE_LOOP, 0, sizeof(v_position) / sizeof(GLfloat) / 2); glDrawElements(GL_LINES, sizeof(indecise) / sizeof(GLushort), GL_UNSIGNED_SHORT, 0); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowPosition(200, 200); glutInitWindowSize(600, 600); glutCreateWindow("opengl"); GLenum err = glewInit(); if (err == GL_TRUE) { cerr << "glew init failed!\n" << endl; exit(-1); } glutDisplayFunc(display); glutMainLoop(); return 0; }
以下为简单的两个shader(只是为了说明原理,所以只有输入输出)
vershader.txt
#version 430 core in vec2 position; void main() { gl_Position = vec4(position, 0.0, 1.0); }
fragshader.txt
#version 430 core out vec4 outColor; void main() { outColor = vec4(1.0, 1.0, 1.0, 1.0); }
此处为读文件操作,将着色器源代码读入内存
#include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; const char *read(char *filename) { FILE *in; in = fopen(filename, "rb"); if (in == NULL) { cerr << "failed to open file!" << endl; exit(-1); } fseek(in, 0, SEEK_END); unsigned int size = ftell(in); fseek(in, 0, SEEK_SET); char *data = new char[size + 1]; fread(data, 1, size, in); data[size] = 0; fclose(in); return const_cast<const char *>(data); }
在绘制处使用两种不同的绘制命令来进行绘制,一种是使用glDrawArrays直接读取显存中的顶点信息进行绘制;另一种是glDrawElements,这种方法需要设置GL_ELEMENT_ARRAY_BUFFER,这里存储的就是顶点绘制索引信息。
时间: 2024-10-01 10:46:25