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

上一篇文章中也使用了比较老的方法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

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

openGl超级宝典学习笔记 (2) 7个基本的几何图元

点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响.即不管与视点的距离如何,它的大小都不改变.为了获得圆点,必须在抗锯齿模式下绘制点. 可以用glPointSize改变点的大小. //点 //建立批次 GLBatch pointBatch; GLfloat vCoast[24][3] = {{2.80, 1.20, 0.0 }, {2.0, 1.20, 0.0 }, {2.0, 1.08, 0.0 }, {2.0, 1.08, 0.0 }, {0.0, 0.80

openGl超级宝典学习笔记 (2) 7个主要的几何图元

点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响. 即无论与视点的距离怎样,它的大小都不改变.为了获得圆点.必须在抗锯齿模式下绘制点. 能够用glPointSize改变点的大小. //点 //建立批次 GLBatch pointBatch; GLfloat vCoast[24][3] = {{2.80, 1.20, 0.0 }, {2.0, 1.20, 0.0 }, {2.0, 1.08, 0.0 }, {2.0, 1.08, 0.0 }, {0.0, 0.8

VC的常用调试方法

前言 VS是非常强大的IDE,所以掌握VSVC的常用方法,将会使得我们找出问题解决问题事半功倍. 目录 VSVC的常用调试方法 前言 1. Watch窗口查看伪变量 2. 查看指针指向的一序列值 3. 内存泄露查找 4. 调试Release版本 5. 远程调试 6. 函数断点 7. 数据断点. 8. 代码执行时间 9. 格式化数据 10. 格式化内存 Watch窗口查看伪变量 按MSDN的介绍,伪变量就是用来查看特定信息的术语.例如当调用的API失败时,可以用GetLastError获取对应的错

NSDictionary的初始化和一些常用的方法总结

NSDictionary //初始化1. NSDictionary *dic11=[[NSDictionary alloc] initWithObjects:@[@"qwe",@"asd",@"zxc",@"qaz",@"wsx"] forKeys:@[@"111",@"222",@"333",@"444",@"555

LINQ常用扩展方法

下面的方法都是IEnumerable<T>的扩展方法: Average计算平均值: Min最小元素:Max最大元素:Sum元素总和: Count元素数量: Concat连接两个序列://Unoin all Contains序列是否包含指定元素: Distinct取得序列中的非重复元素: Except获得两个序列的差集: Intersect获得两个序列的交集: First取得序列第一个元素: Single取得序列的唯一一个元素,如果元素个数不是1个,则报错:!!!严谨的程序. FirstOrDe

黑马程序员_学习IOS之字典常用的方法

字典是无序的 数组是有序的.字典分为:可变字典和不可变字典  不可变字典对象 NSDictionary * dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"one",@"1",@"two",@"2",@"three",@"3",@"four",@"4", nil]; //value = ke

SqlServer 常用分页方法总结

SqlServer 常用分页方法总结 下面示例总结了,SqlServer数据库 常用分页方法,仅供学习参考 A. 使用 RowNumber 和 Between And 组合分页: /********** 使用 RowNumber 和 Between And 组合分页 **********/ CREATE PROC proc_FuzzySearchAndPaging @pageIndex int, --页索引 @pageSize int, --页大小 @SearchKey Nvarchar(10)

Javascript 常用扩展方法

这篇文章纯粹是为了保存这些方法,供以后翻阅,其实一直保存在 evernote 里面,但觉得还是放到对的地方会好点. 现在收录的很少,希望以后会慢慢增多. 数组扩展 contains,remove 扩展 1 function ArrayContains(array, obj) { 2 for (var i = 0; i < array.length; i++) { 3 if (array[i] === obj) { 4 return true ; 5 } 6 } 7 return false ;

SecureCRT是最常用的终端仿真程序,简单的说就是Windows下登录UNIX或Liunx服务器主机的软件,本文主要介绍SecureCRT的使用方法和技巧

VanDyke CRT 和 VanDyke SecureCRT是最常用的终端仿真程序,简单的说就是Windows下登录UNIX或Liunx服务器主机的软件.二者不同的是SecureCRT支持SSH(SSH1和SSH2). 1 #!/usr/bin/perl 2 3 use strict; 4 use warnings; 5 use 5.01; 6 7 8 9 sub license { 10 print "\n". 11 "License:\n\n". 12 &qu