【OpenGL】Shader个人学习笔记(5)利用 VertexArray对多个Buffer进行绑定

这篇博客介绍了如何在OpenGL中使用VertexArray来绑定和管理多个Vertex Buffer,包括Vertex Buffer的标识符类型、每个属性的顶点个数、是否归一化等关键概念。通过创建VertexArray类并实现相关函数,可以方便地进行Buffer与Layout的绑定。文章提供了一个模板示例,并给出了main函数的简单实现。此外,作者还分享了个人笔记的GitHub链接。
摘要由CSDN通过智能技术生成

之前已经学习了单个shader的buffer和layout绑定,如果需要对多个vertex buffer进行绑定,则需要声明一个类的容器。

unsigned int ibo; // index buffer object
GLCall(glGenBuffers(1, &ibo));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW)); // indices 里有六个元素,必须是 unsigned 的
//stride 实际上是一个点(比如说一个2维点是两个顶点组成,所以在这里是两个 float 类型长度)
// vertex array 给 buffer 指定 layout 

unsigned int vao;//vertex array object;
GLCall(glGenVertexArrays(1, &vao));
GLCall(glBindVertexArray(vao));

首先要创建一个VertexArray类用来实现绑定buffer和layout的功能,应该包含绑定操作bind和以下代码的实现

GLCall(glEnableVertexAttribArray(0));

/* 执行此句的时候,0表示bind buffer和vao*/
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));

即: (const代表修饰的函数内数值不会被改变)

m_RendererID:返回的用于标识VertexBuffer的ID

#pragma once

#include "VertexBuffer.h"
#include "VertexBufferLayout.h"

//make vertex butter and layout work
class VertexArray
{
private:
	unsigned int m_RendererID;
public:
	VertexArray();
	~VertexArray();

	void AddBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout);
	
	void Bind() const;
	void UnBind() const;
};

 为了方便并提高可读性,将变量写成结构体(声明顺序应与函数调用参数顺序一致)

type: vertex buffer 标识符类型

count:每个属性包含顶点个数,比如说一个position数值中,每两个顶点表明一个二维点,则count是2

normalized:是否使用归一化

struct VertexBufferElement
{
	unsigned int type;
	unsigned int count;//个数 
	unsigned char normalized;
	
	static unsigned int GetSizeOfType(unsigned int type)
	{
		switch (type)
		{
			case GL_FLOAT:			 return 4;
			case GL_UNSIGNED_INT:	 return 4;
			case GL_UNSIGNED_BYTE:	 return 1;
		}
		ASSERT(false);
		return 0;
	}
};

 m_Element:VertexBufferElement类型的vector容器

m_Stride:每个属性包含多长的数据,是一个index

class VertexBufferLayout
{
private:
	std::vector<VertexBufferElement> m_Elements;
	unsigned int m_Stride;
public:
	VertexBufferLayout()
		: m_Stride(0){}

	template<typename T>
	void Push(unsigned int count)
	{
		static_assert(false);
	}

	template<>
	void Push<float>(unsigned int count)
	{
		m_Elements.push_back({ GL_FLOAT, count, GL_FALSE });
		m_Stride += count * VertexBufferElement::GetSizeOfType(GL_FLOAT);
	}

	template<>
	void Push<int>(unsigned int count)
	{
		m_Elements.push_back({ GL_UNSIGNED_INT, count, GL_FALSE });
		m_Stride += count * VertexBufferElement::GetSizeOfType(GL_UNSIGNED_INT);
	}

	template<>
	void Push<unsigned char>(unsigned int count)
	{
		
		m_Elements.push_back({ GL_UNSIGNED_BYTE, count, GL_TRUE });
		m_Stride += count * VertexBufferElement::GetSizeOfType(GL_UNSIGNED_BYTE);
	}

	inline const std::vector<VertexBufferElement>& GetElements() const { return m_Elements; }
	inline unsigned int GetStride() const { return m_Stride; }
};

 模板Templatehttps://blog.csdn.net/qq_34878429/article/details/106919711

 VertexArray.cpp进行Implement

对于主函数

    VertexArray va;
    VertexBuffer vb(positions, 4 * 2 * sizeof(float));
    VertexBufferLayout layout;
    layout.Push<float>(2); //GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, size of(float) * 2, 0));
    va.AddBuffer(vb, layout);

这样就可以实现多个buffer分别和layout绑定了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值