opengl使用现在比较常用的方法来绘制简单几何图元

版权声明:原创文章,转载请注明出处。本博新地址www.iaccepted.net https://blog.csdn.net/IAccepted/article/details/44195441

上一篇文章中也使用了比较老的方法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,这里存储的就是顶点绘制索引信息。

猜你喜欢

转载自blog.csdn.net/IAccepted/article/details/44195441