ULRE/example/Vulkan/main.cpp
HuYingzhuo e35fbf9a1a 将VertexInput拆分出VertexInputState。
VertexInputState传递给Material,未来可能改由Material创建,提供需要绑定的数据流格式。
VertexInput用于实际的缓冲区绑定
2019-04-25 16:02:13 +08:00

274 lines
5.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include"Window.h"
#include"VKInstance.h"
#include"VKPhysicalDevice.h"
#include"VKDevice.h"
#include"VKBuffer.h"
#include"VKShader.h"
#include"VKImageView.h"
#include"VKVertexInput.h"
#include"VKDescriptorSets.h"
#include"VKRenderPass.h"
#include"VKPipelineLayout.h"
#include"VKPipeline.h"
#include"VKCommandBuffer.h"
#include"VKFormat.h"
#include"VKFramebuffer.h"
#include<hgl/math/Math.h>
#include<fstream>
#ifndef WIN32
#include<unistd.h>
#endif//
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
VkShaderModule vs=nullptr;
VkShaderModule fs=nullptr;
struct
{
Matrix4f mvp;
}ubo_vs;
char *LoadFile(const char *filename,uint32_t &file_length)
{
std::ifstream fs;
fs.open(filename,std::ios_base::binary);
if(!fs.is_open())
return(nullptr);
fs.seekg(0,std::ios_base::end);
file_length=fs.tellg();
char *data=new char[file_length];
fs.seekg(0,std::ios_base::beg);
fs.read(data,file_length);
fs.close();
return data;
}
bool LoadShader(vulkan::Shader *sc,const char *filename,VkShaderStageFlagBits shader_flag)
{
uint32_t size;
char *data=LoadFile(filename,size);
if(!data)
return(false);
if(!sc->Add(shader_flag,data,size))
return(false);
delete[] data;
return(true);
}
vulkan::Shader *LoadShader(VkDevice device)
{
vulkan::Shader *sc=new vulkan::Shader(device);
if(LoadShader(sc,"FlatColor.vert.spv",VK_SHADER_STAGE_VERTEX_BIT))
if(LoadShader(sc,"FlatColor.frag.spv",VK_SHADER_STAGE_FRAGMENT_BIT))
return sc;
delete sc;
return(nullptr);
}
vulkan::Buffer *CreateUBO(vulkan::Device *dev)
{
{
const VkExtent2D extent=dev->GetExtent();
ubo_vs.mvp=ortho(extent.width,extent.height);
}
vulkan::Buffer *ubo=dev->CreateUBO(sizeof(ubo_vs));
uint8_t *p=ubo->Map();
if(p)
{
memcpy(p,&ubo_vs,sizeof(ubo_vs));
ubo->Unmap();
}
return ubo;
}
constexpr uint32_t SHADER_LOCATION_POSITION =0; //对应shader中的layout(locaiton=0暂时这样写
constexpr uint32_t SHADER_LOCATION_COLOR =1;
constexpr float vertex_data[]=
{
SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25,
SCREEN_WIDTH*0.75, SCREEN_HEIGHT*0.75,
SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.75
};
constexpr float color_data[]={1,0,0, 0,1,0, 0,0,1 };
vulkan::VertexInputState *InitVertexInput()
{
vulkan::VertexInputState *vis=new vulkan::VertexInputState();
vis->Add(SHADER_LOCATION_POSITION, FMT_RG32F);
vis->Add(SHADER_LOCATION_COLOR, FMT_RGB32F);
return vis;
}
vulkan::VertexBuffer *vertex_buffer=nullptr;
vulkan::VertexBuffer *color_buffer=nullptr;
vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev,vulkan::VertexInputState *vis)
{
vertex_buffer =dev->CreateVBO(FMT_RG32F, 3,vertex_data);
color_buffer =dev->CreateVBO(FMT_RGB32F, 3,color_data);
vulkan::VertexInput *vi=new vulkan::VertexInput(vis);
vi->Set(SHADER_LOCATION_POSITION, vertex_buffer);
vi->Set(SHADER_LOCATION_COLOR, color_buffer);
return vi;
}
void wait_seconds(int seconds) {
#ifdef WIN32
Sleep(seconds * 1000);
#elif defined(__ANDROID__)
sleep(seconds);
#else
sleep(seconds);
#endif
}
//class ExampleFramework
//{
// Window *win=nullptr;
// vulkan::Instance *inst=nullptr;
// vulkan::Device *device=nullptr;
// vulkan::Shader *shader=nullptr;
// vulkan::Buffer *ubo_mvp=nullptr;
// vulkan::VertexInput *vi=nullptr;
// vulkan::PipelineCreater
//};//
int main(int,char **)
{
#ifdef _DEBUG
if(!vulkan::CheckStrideBytesByFormat())
return 0xff;
#endif//
Window *win=CreateRenderWindow(OS_TEXT("VulkanTest"));
win->Create(SCREEN_WIDTH,SCREEN_HEIGHT);
vulkan::Instance *inst=vulkan::CreateInstance(U8_TEXT("VulkanTest"));
if(!inst)
{
delete win;
return(-1);
}
vulkan::Device *device=inst->CreateRenderDevice(win);
if(!device)
{
delete inst;
delete win;
return(-2);
}
{
const vulkan::PhysicalDevice *render_device=device->GetPhysicalDevice();
std::cout<<"auto select physical device: "<<render_device->GetDeviceName()<<std::endl;
}
vulkan::Shader *shader=LoadShader(device->GetDevice());
if(!shader)
return -3;
vulkan::Buffer *ubo=CreateUBO(device);
vulkan::VertexInputState *vis=InitVertexInput();
vulkan::VertexInput *vi=CreateVertexBuffer(device,vis);
vulkan::PipelineCreater pc(device);
vulkan::DescriptorSetLayoutCreater dslc(device);
const int mvp_binding=0; //shader->GetBinding("MVPMatrix"); 实现从材质shader文件中根据名称获取binding的功能
dslc.BindUBO(mvp_binding,VK_SHADER_STAGE_VERTEX_BIT);
vulkan::DescriptorSetLayout *dsl=dslc.Create();
dsl->UpdateUBO(mvp_binding,*ubo);
vulkan::PipelineLayout *pl=CreatePipelineLayout(*device,dsl);
pc.SetDepthTest(false);
pc.SetDepthWrite(false);
pc.CloseCullFace();
pc.Set(shader);
pc.Set(vis);
pc.Set(PRIM_TRIANGLES);
pc.Set(*pl);
vulkan::Pipeline *pipeline=pc.Create();
if(!pipeline)
return(-4);
device->AcquireNextImage();
vulkan::CommandBuffer *cmd_buf=device->CreateCommandBuffer();
cmd_buf->Begin(device->GetRenderPass(),device->GetFramebuffer(0));
cmd_buf->Bind(pipeline);
cmd_buf->Bind(pl);
cmd_buf->Bind(vi);
cmd_buf->Draw(3);
cmd_buf->End();
device->QueueSubmit(cmd_buf);
device->Wait();
device->QueuePresent();
wait_seconds(3);
delete vertex_buffer;
delete color_buffer;
delete pipeline;
delete pl;
delete dsl;
delete vi;
delete vis;
delete ubo;
delete shader;
delete cmd_buf;
delete device;
delete inst;
delete win;
return 0;
}