简介
本人梦想着做一款自己的游戏引擎,万事开头难,但总得有人去做,本序列由 由B站转载学习,非个人研究,鸣谢! B站链接 原作者Github
OpenGL的渲染步骤
-
生成顶点数据,描述需要渲染的一个面,可以有N个顶点组成 在使用Glad之后渲染的坐标体系 -
设置BufferLayout,数据在渲染时候的表示方式 使用Glad之后数据读取布局方式,根据布局,前面3个是pos,后4个是color;总计7个,3组数据输入给顶点渲染器 -
设置IndexBuffer,顶点渲染的顺序 一个三角形的渲染顺序,012
VertexArray
#pragma once
#include <memory>
#include "Aurora/Renderer/Buffer.h"
namespace Aurora
{
class VertexArray
{
public:
virtual ~VertexArray() {}
virtual void Bind() const = 0;
virtual void Unbind() const = 0;
virtual void AddVertexBuffer(const std::shared_ptr<VertexBuffer>& vertexBuffer) = 0;
virtual void SetIndexBuffer(const std::shared_ptr<IndexBuffer>& indexBuffer) = 0;
virtual const std::vector<std::shared_ptr<VertexBuffer>>& GetVertexBuffers() const = 0;
virtual const std::shared_ptr<IndexBuffer>& GetIndexBuffer() const = 0;
static VertexArray* Create();
};
}
#include "aopch.h"
#include "VertexArray.h"
#include "Renderer.h"
#include "Platform/OpenGL/OpenGLVertexArray.h"
namespace Aurora
{
VertexArray* VertexArray::Create()
{
switch (Renderer::GetAPI())
{
case RendererAPI::None: AO_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
case RendererAPI::OpenGL: return new OpenGLVertexArray();
}
AO_CORE_ASSERT(false, "Unknown RendererAPI!");
return nullptr;
}
}
OpenGLVertexArray
#pragma once
#include "Aurora/Renderer/VertexArray.h"
namespace Aurora
{
class OpenGLVertexArray : public VertexArray
{
public:
OpenGLVertexArray();
virtual ~OpenGLVertexArray();
virtual void Bind() const override;
virtual void Unbind() const override;
virtual void AddVertexBuffer(const std::shared_ptr<VertexBuffer>& vertexBuffer) override;
virtual void SetIndexBuffer(const std::shared_ptr<IndexBuffer>& indexBuffer) override;
virtual const std::vector<std::shared_ptr<VertexBuffer>>& GetVertexBuffers() const { return m_VertexBuffers; }
virtual const std::shared_ptr<IndexBuffer>& GetIndexBuffer() const { return m_IndexBuffer; }
private:
uint32_t m_RendererID;
std::vector<std::shared_ptr<VertexBuffer>> m_VertexBuffers;
std::shared_ptr<IndexBuffer> m_IndexBuffer;
};
}
#include "aopch.h"
#include "OpenGLVertexArray.h"
#include <glad/glad.h>
namespace Aurora
{
static GLenum ShaderDataTypeToOpenGLBaseType(ShaderDataType type)
{
switch (type)
{
case Aurora::ShaderDataType::Float: return GL_FLOAT;
case Aurora::ShaderDataType::Float2: return GL_FLOAT;
case Aurora::ShaderDataType::Float3: return GL_FLOAT;
case Aurora::ShaderDataType::Float4: return GL_FLOAT;
case Aurora::ShaderDataType::Mat3: return GL_FLOAT;
case Aurora::ShaderDataType::Mat4: return GL_FLOAT;
case Aurora::ShaderDataType::Int: return GL_INT;
case Aurora::ShaderDataType::Int2: return GL_INT;
case Aurora::ShaderDataType::Int3: return GL_INT;
case Aurora::ShaderDataType::Int4: return GL_INT;
case Aurora::ShaderDataType::Bool: return GL_BOOL;
}
AO_CORE_ASSERT(false, "Unknown ShaderDataType!");
return 0;
}
OpenGLVertexArray::OpenGLVertexArray()
{
glCreateVertexArrays(1, &m_RendererID);
}
OpenGLVertexArray::~OpenGLVertexArray()
{
glDeleteVertexArrays(1, &m_RendererID);
}
void OpenGLVertexArray::Bind() const
{
glBindVertexArray(m_RendererID);
}
void OpenGLVertexArray::Unbind() const
{
glBindVertexArray(0);
}
void OpenGLVertexArray::AddVertexBuffer(const std::shared_ptr<VertexBuffer>& vertexBuffer)
{
AO_CORE_ASSERT(vertexBuffer->GetLayout().GetElements().size(), "Vertex Buffer has no layout!");
glBindVertexArray(m_RendererID);
vertexBuffer->Bind();
uint32_t index = 0;
const auto& layout = vertexBuffer->GetLayout();
for (const auto& element : layout)
{
glEnableVertexAttribArray(index);
glVertexAttribPointer(index,
element.GetComponentCount(),
ShaderDataTypeToOpenGLBaseType(element.Type),
element.Normalized ? GL_TRUE : GL_FALSE,
layout.GetStride(),
(const void*)element.Offset);
index++;
}
m_VertexBuffers.push_back(vertexBuffer);
}
void OpenGLVertexArray::SetIndexBuffer(const std::shared_ptr<IndexBuffer>& indexBuffer)
{
glBindVertexArray(m_RendererID);
indexBuffer->Bind();
m_IndexBuffer = indexBuffer;
}
}
单次渲染流程
m_VertexArray.reset(VertexArray::Create());
float vertices[3 * 7] = {
-0.5f, -0.5f, 0.0f, 0.8f, 0.2f, 0.8f, 1.0f,
0.5f, -0.5f, 0.0f, 0.2f, 0.3f, 0.8f, 1.0f,
0.0f, 0.5f, 0.0f, 0.8f, 0.8f, 0.2f, 1.0f
};
std::shared_ptr<VertexBuffer> vertexBuffer;
vertexBuffer.reset(VertexBuffer::Create(vertices, sizeof(vertices)));
BufferLayout layout = {
{ ShaderDataType::Float3, "a_Position" },
{ ShaderDataType::Float4, "a_Color" }
};
vertexBuffer->SetLayout(layout);
m_VertexArray->AddVertexBuffer(vertexBuffer);
uint32_t indices[3] = { 0, 1, 2 };
std::shared_ptr<IndexBuffer> indexBuffer;
indexBuffer.reset(IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t)));
m_VertexArray->SetIndexBuffer(indexBuffer);
m_SquareVA.reset(VertexArray::Create());
|