bufferlayout solved

main
xszAzy 3 months ago
parent f2e64bc0db
commit 013d2eefb7

@ -99,6 +99,7 @@
47A97AA92E8EB34B00293FA8 /* Renderer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = Renderer.mm; path = src/MEL/Renderer/Renderer.mm; sourceTree = "<group>"; };
47A97AAC2E8EDBAD00293FA8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
47A97AAD2E8EDBAD00293FA8 /* ViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = "<group>"; };
47BB8EEB2E9559770005EA9F /* BufferLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BufferLayout.h; sourceTree = "<group>"; };
47F2B4282E918103005D0A7A /* Shader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = "<group>"; };
47F2B4292E918103005D0A7A /* Shader.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Shader.mm; sourceTree = "<group>"; };
500811C6F3539AF80E246806 /* Core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = "<group>"; };
@ -234,6 +235,7 @@
479A9D0C2E942C4E0019F59F /* IndexBuffer.mm */,
479A9D0E2E942CBD0019F59F /* VertexBuffer.h */,
479A9D0F2E942CBD0019F59F /* VertexBuffer.mm */,
47BB8EEB2E9559770005EA9F /* BufferLayout.h */,
);
name = Buffer;
path = src/MEL/Buffer;

@ -3,7 +3,7 @@ using namespace metal;
struct VertexIn {
float3 position [[attribute(0)]];
float3 color [[attribute(1)]];
float4 color [[attribute(1)]];
};
struct VertexOut{
@ -14,7 +14,7 @@ struct VertexOut{
vertex VertexOut vertexShader(const VertexIn in [[stage_in]]){
VertexOut out;
out.position=float4(in.position,1.0);
out.color=float4(in.color,1.0);
out.color=in.color;
return out;
}

@ -5,6 +5,7 @@
#import "Buffer/VertexBuffer.h"
#import "Buffer/IndexBuffer.h"
#import "Buffer/BufferLayout.h"
#import "VertexArray/VertexArray.h"
namespace MEL{
@ -23,32 +24,42 @@ namespace MEL{
//create vertex array
m_VertexArray=MEL::VertexArray::Create();
//set vertex and index buffer
float vertices[]={
-0.5f,-0.5f,0.0f,
0.4f,0.2f,0.4f,
struct Vertex{
float position[3];
float color[4];
};
Vertex vertices[]={
{{-0.5f,-0.5f,0.0f},
{0.4f,0.2f,0.4f,1.0f}},
0.5f,-0.5f,0.0f,
0.1f,0.7f,0.1f,
{{0.5f,-0.5f,0.0f},
{0.1f,0.7f,0.1f,1.0f}},
0.0f,0.5f,0.0f,
0.1f,0.3f,0.4f
{{0.0f,0.5f,0.0f},
{0.1f,0.3f,0.4f,1.0f}}
};
uint32_t indices[]={0,1,2};
//create bufferlayout
BufferLayout layout={
{ShaderDataType::Float3,"a_Position"},
{ShaderDataType::Float4,"a_Color"}
};
//Set buffers
auto basicVB=VertexBuffer::Create(vertices, sizeof(vertices));
auto basicIB=IndexBuffer::Create(indices, 3);
basicVB->SetSlot(0);
basicVB->SetLayout(layout);
m_VertexArray->AddVertexBuffer(basicVB);
m_VertexArray->SetIndexBuffer(basicIB);
//create shader(this can be done in sandbox)
auto defaultShader=MEL::Shader::CreateFromDefaultLibrary("DefaultShader",
@"vertexShader",@"fragmentShader");
if(defaultShader)
defaultShader->CreatePipelineState();
defaultShader->CreatePipelineState(layout);
m_CurrentShader=defaultShader;
//initialize layers

@ -1,6 +1,7 @@
#pragma once
#include<Metal/Metal.h>
#include "Application.h"
#include "BufferLayout.h"
namespace MEL{
enum class BufferUsage{

@ -0,0 +1,146 @@
#pragma once
#import <Metal/Metal.h>
#include <vector>
#include <cstdint>
namespace MEL {
enum class ShaderDataType{
None=0,
Float,Float2,Float3,Float4,
Mat3,Mat4,
Int,Int2,Int3,Int4,
Bool
};
static uint32_t ShaderDataTypeSize(ShaderDataType type){
switch(type){
case ShaderDataType::Float: return 4; break;
case ShaderDataType::Float2: return 4*2; break;
case ShaderDataType::Float3: return 4*3; break;
case ShaderDataType::Float4: return 4*4; break;
case ShaderDataType::Mat3: return 4*3*3; break;
case ShaderDataType::Mat4: return 4*4*4; break;
case ShaderDataType::Int: return 4; break;
case ShaderDataType::Int2: return 4*2; break;
case ShaderDataType::Int3: return 4*3; break;
case ShaderDataType::Int4: return 4*4; break;
case ShaderDataType::Bool: return true; break;
default: return 0; break;
}
}
static MTLVertexFormat ShaderDataTypeToMetal(ShaderDataType type){
switch(type){
case ShaderDataType::Float: return MTLVertexFormatFloat; break;
case ShaderDataType::Float2: return MTLVertexFormatFloat2; break;
case ShaderDataType::Float3: return MTLVertexFormatFloat3; break;
case ShaderDataType::Float4: return MTLVertexFormatFloat4; break;
case ShaderDataType::Mat3: return MTLVertexFormatFloat3; break;
case ShaderDataType::Mat4: return MTLVertexFormatFloat3; break;
case ShaderDataType::Int: return MTLVertexFormatInt; break;
case ShaderDataType::Int2: return MTLVertexFormatInt2; break;
case ShaderDataType::Int3: return MTLVertexFormatInt3; break;
case ShaderDataType::Int4: return MTLVertexFormatInt4; break;
case ShaderDataType::Bool: return MTLVertexFormatChar; break;
default: return MTLVertexFormatFloat; break;
}
}
struct BufferElement{
std::string Name;
ShaderDataType Type;
uint32_t Size;
uint32_t Offset;
bool Normalized;
BufferElement()=default;
BufferElement(ShaderDataType type,const std::string& name,bool normalized=false)
:Name(name),Type(type),Size(ShaderDataTypeSize(type)),Offset(0),Normalized(normalized){}
uint32_t GetComponentCount()const{
switch (Type){
case ShaderDataType::Float: return 1; break;
case ShaderDataType::Float2: return 2; break;
case ShaderDataType::Float3: return 3; break;
case ShaderDataType::Float4: return 4; break;
case ShaderDataType::Mat3: return 3; break;
case ShaderDataType::Mat4: return 4; break;
case ShaderDataType::Int: return 1; break;
case ShaderDataType::Int2: return 2; break;
case ShaderDataType::Int3: return 3; break;
case ShaderDataType::Int4: return 4; break;
case ShaderDataType::Bool: return 1; break;
default: return 0; break;
}
}
};
class BufferLayout{
public:
BufferLayout()=default;
BufferLayout(const std::initializer_list<BufferElement>& elements)
:m_Elements(elements){
CalculateOffsetAndStride();
}
const std::vector<BufferElement>& GetElements() const{return m_Elements;}
uint32_t GetStride()const {return m_Stride;}
std::vector<BufferElement>::iterator begin(){return m_Elements.begin();}
std::vector<BufferElement>::iterator end(){return m_Elements.end();}
std::vector<BufferElement>::const_iterator begin()const{return m_Elements.begin();}
std::vector<BufferElement>::const_iterator end()const{return m_Elements.end();}
static BufferLayout Default(){
return {
{ShaderDataType::Float3,"a_Position"},
{ShaderDataType::Float4,"a_Color"}
};
}
static BufferLayout SimplePosition(){
return{
{ShaderDataType::Float3,"a_Position"}
};
}
static BufferLayout PositionColor(){
return {
{ShaderDataType::Float3,"a_Position"},
{ShaderDataType::Float4,"a_Color"}
};
}
static BufferLayout PositionTexture(){
return {
{ShaderDataType::Float3,"a_Position"},
{ShaderDataType::Float2,"a_TexCoord"}
};
}
static BufferLayout PositionNormalTexture(){
return {
{ShaderDataType::Float3,"a_Position"},
{ShaderDataType::Float3,"a_Normal"},
{ShaderDataType::Float2,"a_TexCoord"}
};
}
private:
void CalculateOffsetAndStride(){
uint32_t offset=0;
m_Stride=0;
for(auto& element:m_Elements){
element.Offset=offset;
offset+=element.Size;
m_Stride+=element.Size;
}
}
private:
std::vector<BufferElement> m_Elements;
uint32_t m_Stride=0;
};
}

@ -15,7 +15,11 @@ namespace MEL {
void SetSlot(uint32_t slot){m_Slot=slot;}
uint32_t GetSlot()const{return m_Slot;}
void SetLayout(const BufferLayout& layout){m_Layout=layout;}
const BufferLayout& GetLayout()const{return m_Layout;}
private:
uint32_t m_Slot=0;
BufferLayout m_Layout;
};
}

@ -3,6 +3,7 @@
#include "MEL.h"
#include<string>
#include<unordered_map>
#include"Buffer/BufferLayout.h"
namespace MEL{
class Shader{
@ -22,7 +23,8 @@ namespace MEL{
const std::string& GetName(){return m_Name;}
bool CreatePipelineState();
bool CreatePipelineState(const BufferLayout& layout);
MTLVertexDescriptor* CreateVertexDescriptor(const BufferLayout& layout);
id<MTLRenderPipelineState> GetPipelineState()const{return m_PipelineState;}
void Bind();
private:

@ -102,7 +102,7 @@ namespace MEL{
return true;
}
bool Shader::CreatePipelineState(){
bool Shader::CreatePipelineState(const BufferLayout& layout){
auto renderer=Application::Get().GetRenderer();
id<MTLDevice> device=renderer->GetMetalDevice();
@ -116,21 +116,9 @@ namespace MEL{
pipelineDescriptor.fragmentFunction=m_FragmentFunction;
pipelineDescriptor.colorAttachments[0].pixelFormat=MTLPixelFormatBGRA8Unorm;
MTLVertexDescriptor* vertexDescriptor=[[MTLVertexDescriptor alloc]init];
vertexDescriptor.attributes[0].format=MTLVertexFormatFloat3;
vertexDescriptor.attributes[0].offset=0;
vertexDescriptor.attributes[0].bufferIndex=0;
vertexDescriptor.attributes[1].format=MTLVertexFormatFloat3;
vertexDescriptor.attributes[1].offset=12;
vertexDescriptor.attributes[1].bufferIndex=0;
vertexDescriptor.layouts[0].stride=24;
vertexDescriptor.layouts[0].stepFunction=MTLVertexStepFunctionPerVertex;
MTLVertexDescriptor* vertexDescriptor=CreateVertexDescriptor(layout);
pipelineDescriptor.vertexDescriptor=vertexDescriptor;
NSError* error=nil;
m_PipelineState=[device newRenderPipelineStateWithDescriptor:pipelineDescriptor
error:&error];
@ -144,6 +132,32 @@ namespace MEL{
return true;
}
MTLVertexDescriptor* Shader::CreateVertexDescriptor(const BufferLayout &layout){
MTLVertexDescriptor* vertexDescriptor=[MTLVertexDescriptor vertexDescriptor];
uint32_t attributeIndex=0;
uint32_t bufferIndex=0;
for(const auto& element:layout){
MTLVertexAttributeDescriptor* attribute=vertexDescriptor.attributes[attributeIndex];
attribute.format=ShaderDataTypeToMetal(element.Type);
attribute.offset=element.Offset;
attribute.bufferIndex=bufferIndex;
MEL_CORE_INFO("Vertex Attribute[{}]:{} at buffer {},offset {},format {}",
attributeIndex,element.Name,bufferIndex,element.Offset,(int)attribute.format);
attributeIndex++;
}
MTLVertexBufferLayoutDescriptor* bufferLayout=vertexDescriptor.layouts[bufferIndex];
bufferLayout.stride=layout.GetStride();
bufferLayout.stepRate=1;
bufferLayout.stepFunction=MTLVertexStepFunctionPerVertex;
return vertexDescriptor;
}
void Shader::Bind(){
auto renderer=Application::Get().GetRenderer();
renderer->SetCurrentPipelineState(m_PipelineState);

Loading…
Cancel
Save