OpenGL学习日志12——抽象顶点索引缓冲区成类

        为了使得复杂的问题简单化,以便之后解决更加复杂的着色器,渲染器等问题,需要把顶点缓冲区和索引缓冲区抽象为类;

        这样做可以提高代码的可读性,同时便于调试(类似于嵌入式的库函数文件);

        目前可以抽象的类别有顶点缓冲区,索引缓冲区,顶点数组和着色器四个部分(目前还没使用纹理);

        整体来说就是一个渲染器;

        顶点缓冲区

 float positions[] = {
        -0.5f , -0.5f,
         0.5f , -0.5f,
         0.5f ,  0.5f,
        -0.5f ,  0.5f
    };
    
    //-----顶点缓冲区------
    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 4 * 2 * sizeof(float),positions,GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

      索引缓冲区

glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(unsigned int), indices, GL_STATIC_DRAW);

首先创建一个渲染器的头文件和CPP文件用以将所有类统一起来,这些步骤与嵌入式相似,但有所区别(因为cpp文件有类)

Render.h

#pragma once
#include <Gl/glew.h>
#include <GLFW/glfw3.h>

#define ASSERT(x) if(!x) __debugbreak();
#define GLCall(x) GLClearError();\
    x;\
    ASSERT(GLLogError(#x,__FILE__,__LINE__))//这里的后续不需要加封号,#x代表着转化成字符串,之后为所有单独的gl方程添加上这个宏


//获取错误类型,这种方式有点笨
void GLClearError();
bool GLLogError(const char* function, const char* file, int line);

Render.cpp

#include "Render.h"
#include <iostream>

void GLClearError()
{
    while (glGetError() != GL_NO_ERROR);
}
bool GLLogError(const char* function, const char* file, int line)
{
    while (GLenum error = glGetError())
    {
        std::cout << "[OpenGL_Error](" << error << ")" << function << " " << file << ":" << line << std::endl;
        return false;
    }
    return true;
}

创建好之后,分别创建顶点缓冲区和索引缓冲区的cpp文件和头文件,暂时类里面只包含构造函数,析构函数和绑定与解除绑定的函数

VertexBuffer.h

#pragma once

class VertexBuffer
{
private:
	unsigned int m_RendererID;
public:
	VertexBuffer(const void* data, unsigned int size);
	~VertexBuffer();

	void Bind();
	void Unbind();
};

VertexBuffer.cpp

#include "VertexBuffer.h"

#include "Render.h"

VertexBuffer::VertexBuffer(const void* data, unsigned int size)
{
    GLCall(glGenBuffers(1, &m_RendererID));
    GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID));
    GLCall(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
}

VertexBuffer::~VertexBuffer()
{
    GLCall(glDeleteBuffers(1, &m_RendererID));
}

void VertexBuffer::Bind()
{
    GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID));
}

void VertexBuffer::Unbind()
{
    GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0));
}

IndexBuffer.h 相比于顶点缓冲区,我需要一个顶点的数量 以及获取返回数量的函数

#pragma once

class IndexBuffer
{
private:
	unsigned int m_RendererID;
	unsigned int m_Count;
public:
	IndexBuffer(const unsigned int* data, unsigned int count);
	~IndexBuffer();

	void Bind() const;
	void Unbind() const;

	inline unsigned int GetCount() const { return m_Count; }
};

IndexBuffer.cpp

#include  "IndexBuffer.h"

#include "Render.h"

IndexBuffer::IndexBuffer(const unsigned int* data, unsigned int count)
    :m_Count(count)
{
    ASSERT(sizeof(unsigned int) == sizeof(GLuint));

    GLCall(glGenBuffers(1, &m_RendererID));
    GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID));
    GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW));
}

IndexBuffer::~IndexBuffer()
{
    GLCall(glDeleteBuffers(1, &m_RendererID));
}
void IndexBuffer::Bind() const
{
    GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID));
}

void IndexBuffer::Unbind() const
{
    GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}

 全部文件构建好之后,在主文件开头申明头文件,就可以使用这些类来创建和绑定缓冲区了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值