#include <iostream>
#include <vsg/all.h>
int main(int argc, char** argv)
{
// set up defaults and read command line arguments to override them
vsg::CommandLine arguments(&argc, argv);
auto windowTraits = vsg::WindowTraits::create();
windowTraits->debugLayer = arguments.read({"--debug", "-d"});
windowTraits->apiDumpLayer = arguments.read({"--api", "-a"});
arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height);
if (arguments.errors()) return arguments.writeErrorMessages(std::cerr);
// set up search paths to SPIRV shaders and textures
vsg::Paths searchPaths = vsg::getEnvPaths("C:/vsg/vsgExamples/data/shaders");
// load shaders
vsg::ref_ptr<vsg::ShaderStage> vertexShader = vsg::ShaderStage::read(VK_SHADER_STAGE_VERTEX_BIT, "main", "C:/vsg/vsgExamples/data/shaders/vert_PushConstants.spv");
vsg::ref_ptr<vsg::ShaderStage> fragmentShader = vsg::ShaderStage::read(VK_SHADER_STAGE_FRAGMENT_BIT, "main", "C:/vsg/vsgExamples/data/shaders/frag_PushConstants.spv");
// read texture image
auto textureData = vsg::read_cast<vsg::Data>("C:/vsg/vsgExamples/data/textures/lz.vsgb");
// set up graphics pipeline
vsg::DescriptorSetLayoutBindings descriptorBindings{
{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr} // { binding, descriptorType, descriptorCount, stageFlags, pImmutableSamplers}
};
auto descriptorSetLayout = vsg::DescriptorSetLayout::create(descriptorBindings);
vsg::PushConstantRanges pushConstantRanges{
{VK_SHADER_STAGE_VERTEX_BIT, 0, 128} // projection, view, and model matrices, actual push constant calls automatically provided by the VSG's RecordTraversal
};
vsg::VertexInputState::Bindings vertexBindingsDescriptions{
VkVertexInputBindingDescription{0, sizeof(vsg::vec3), VK_VERTEX_INPUT_RATE_VERTEX}, // vertex data
VkVertexInputBindingDescription{1, sizeof(vsg::vec3), VK_VERTEX_INPUT_RATE_VERTEX}, // colour data
VkVertexInputBindingDescription{2, sizeof(vsg::vec2), VK_VERTEX_INPUT_RATE_VERTEX} // tex coord data
};
vsg::VertexInputState::Attributes vertexAttributeDescriptions{
VkVertexInputAttributeDescription{0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0}, // vertex data
VkVertexInputAttributeDescription{1, 1, VK_FORMAT_R32G32B32_SFLOAT, 0}, // colour data
VkVertexInputAttributeDescription{2, 2, VK_FORMAT_R32G32_SFLOAT, 0} // tex coord data
};
auto x = vsg::RasterizationState::create();
//x->polygonMode = VK_POLYGON_MODE_LINE;//线
x->cullMode = VK_CULL_MODE_NONE;//双面显示
vsg::GraphicsPipelineStates pipelineStates{
vsg::VertexInputState::create(vertexBindingsDescriptions, vertexAttributeDescriptions),
vsg::InputAssemblyState::create(),
x,
vsg::MultisampleState::create(),
vsg::ColorBlendState::create(),
vsg::DepthStencilState::create()
};
auto pipelineLayout = vsg::PipelineLayout::create(vsg::DescriptorSetLayouts{descriptorSetLayout}, pushConstantRanges);
auto graphicsPipeline = vsg::GraphicsPipeline::create(pipelineLayout, vsg::ShaderStages{vertexShader, fragmentShader}, pipelineStates);
auto bindGraphicsPipeline = vsg::BindGraphicsPipeline::create(graphicsPipeline);
// create texture image and associated DescriptorSets and binding
auto texture = vsg::DescriptorImage::create(vsg::Sampler::create(), textureData, 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
auto descriptorSet = vsg::DescriptorSet::create(descriptorSetLayout, vsg::Descriptors{texture});
auto bindDescriptorSet = vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, descriptorSet);
// create StateGroup as the root of the scene/command graph to hold the GraphicsPipeline, and binding of Descriptors to decorate the whole graph
auto scenegraph = vsg::StateGroup::create();
scenegraph->add(bindGraphicsPipeline);
scenegraph->add(bindDescriptorSet);
// set up model transformation node
auto transform = vsg::MatrixTransform::create(); // VK_SHADER_STAGE_VERTEX_BIT
// add transform to root of the scene graph
scenegraph->addChild(transform);
// set up vertex and index arrays
auto vertices = vsg::vec3Array::create(
{{-0.5f, -0.5f, 0.0f},
{0.5f, -0.5f, 0.0f},
{0.5f, 0.5f, 0.0f},
{-0.5f, 0.5f, 0.0f},
{-0.5f, -0.5f, -0.5f},
{0.5f, -0.5f, -0.5f},
{0.5f, 0.5f, -0.5f},
{-0.5f, 0.5f, -0.5f}}); // VK_FORMAT_R32G32B32_SFLOAT, VK_VERTEX_INPUT_RATE_INSTANCE, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE
auto colors = vsg::vec3Array::create(
{
{1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 1.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 1.0f},
}); // VK_FORMAT_R32G32B32_SFLOAT, VK_VERTEX_INPUT_RATE_VERTEX, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE
auto texcoords = vsg::vec2Array::create(
{{0.0f, 0.0f},
{1.0f, 0.0f},
{1.0f, 1.0f},
{0.0f, 1.0f},
{0.0f, 0.0f},
{1.0f, 0.0f},
{1.0f, 1.0f},
{0.0f, 1.0f}}); // VK_FORMAT_R32G32_SFLOAT, VK_VERTEX_INPUT_RATE_VERTEX, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE
auto indices = vsg::ushortArray::create(
{0, 1, 2,
2, 3, 0,
4, 5, 6,
6, 7, 4}); // VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE
// setup geometry
auto drawCommands = vsg::Commands::create();
drawCommands->addChild(vsg::BindVertexBuffers::create(0, vsg::DataList{vertices, colors, texcoords}));
drawCommands->addChild(vsg::BindIndexBuffer::create(indices));
drawCommands->addChild(vsg::DrawIndexed::create(12, 1, 0, 0, 0));
// add drawCommands to transform
transform->addChild(drawCommands);
// scenegraph->addChild(drawCommands);
// create the viewer and assign window(s) to it
auto viewer = vsg::Viewer::create();
auto window = vsg::Window::create(windowTraits);
if (!window)
{
std::cout << "Could not create window." << std::endl;
return 1;
}
viewer->addWindow(window);
// camera related details
auto viewport = vsg::ViewportState::create(0, 0, window->extent2D().width, window->extent2D().height);
auto perspective = vsg::Perspective::create(60.0, static_cast<double>(window->extent2D().width) / static_cast<double>(window->extent2D().height), 0.1, 10.0);
auto lookAt = vsg::LookAt::create(vsg::dvec3(1.0, 1.0, 1.0), vsg::dvec3(0.0, 0.0, 0.0), vsg::dvec3(0.0, 0.0, 1.0));
auto camera = vsg::Camera::create(perspective, lookAt, viewport);
auto commandGraph = vsg::createCommandGraphForView(window, camera, scenegraph);
viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph});
// compile the Vulkan objects
viewer->compile();
// assign a CloseHandler to the Viewer to respond to pressing Escape or the window close button
viewer->addEventHandlers({vsg::CloseHandler::create(viewer)});
//这两句是加入鼠标控制
auto ellipsoidModel = scenegraph->getRefObject<vsg::EllipsoidModel>("EllipsoidModel");
viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel));
// main frame loop
while (viewer->advanceToNextFrame())
{
// pass any events into EventHandlers assigned to the Viewer
viewer->handleEvents();
// animate the transform
float time = std::chrono::duration<float, std::chrono::seconds::period>(viewer->getFrameStamp()->time - viewer->start_point()).count();
transform->matrix = vsg::rotate(time * vsg::radians(90.0f), vsg::vec3(0.0f, 0.0, 1.0f));
viewer->update();
viewer->recordAndSubmit();
viewer->present();
}
// clean up done automatically thanks to ref_ptr<>
return 0;
}
读取vsgt文件画瓶子的代码
#include <vsg/all.h>
#include <vsgXchange/all.h>
#include <iostream>
class InsertStateSwitch : public vsg::Visitor
{
public:
std::vector<vsg::Object*> parents;
std::set<vsg::Object*> visited;
std::map<vsg::BindGraphicsPipeline*, vsg::ref_ptr<vsg::StateSwitch>> pipelineMap;
vsg::Mask mask_1 = 1;
vsg::Mask mask_2 = 2;
void traverse(vsg::Object& object)
{
parents.push_back(&object);
object.traverse(*this);
parents.pop_back();
}
void apply(vsg::Object& object) override
{
traverse(object);
}
vsg::ref_ptr<vsg::GraphicsPipeline> createAlternate(vsg::GraphicsPipeline& pipeline)
{
auto alternative_pipeline = vsg::GraphicsPipeline::create();
*alternative_pipeline = pipeline;
for (auto& pipelineState : alternative_pipeline->pipelineStates)
{
if (auto rasterizationState = pipelineState.cast<vsg::RasterizationState>())
{
auto alternate_rasterizationState = vsg::RasterizationState::create(*rasterizationState);
alternate_rasterizationState->polygonMode = VK_POLYGON_MODE_LINE;
alternate_rasterizationState->cullMode = VK_CULL_MODE_NONE;
pipelineState = alternate_rasterizationState;
}
}
return alternative_pipeline;
}
void apply(vsg::StateGroup& sg) override
{
if (visited.count(&sg) > 0) return;
visited.insert(&sg);
for (auto& sc : sg.stateCommands)
{
if (auto bgp = sc->cast<vsg::BindGraphicsPipeline>())
{
auto& stateSwitch = pipelineMap[bgp];
if (!stateSwitch)
{
stateSwitch = vsg::StateSwitch::create();
stateSwitch->slot = bgp->slot;
stateSwitch->add(mask_1, sc);
auto alternate_gp = createAlternate(*(bgp->pipeline));
auto alternate_bgp = vsg::BindGraphicsPipeline::create(alternate_gp);
stateSwitch->add(mask_2, alternate_bgp);
auto alternate_rasterizationState = vsg::RasterizationState::create();
}
sc = stateSwitch;
}
}
traverse(sg);
}
};
int main(int argc, char** argv)
{
// set up defaults and read command line arguments to override them
vsg::CommandLine arguments(&argc, argv);
// set up vsg::Options to pass in filepaths, ReaderWriters and other IO related options to use when reading and writing files.
auto options = vsg::Options::create(vsgXchange::all::create());
options->fileCache = vsg::getEnv("VSG_FILE_CACHE");
options->paths = vsg::getEnvPaths("VSG_FILE_PATH");
arguments.read(options);
vsg::Path filename = "C:/vsg/vsgExamples/data/models/teapot.vsgt";
//auto scenegraph = vsg::read_cast<vsg::Node>(filename, options);
if (argc > 1) filename = arguments[1];
if (arguments.errors()) return arguments.writeErrorMessages(std::cerr);
// load the scene graph
vsg::ref_ptr<vsg::Node> vsg_scene = vsg::read_cast<vsg::Node>(filename, options);
if (!vsg_scene) return 0;
// create the viewer and assign window(s) to it
auto windowTraits = vsg::WindowTraits::create();
windowTraits->windowTitle = "Hello World";
auto viewer = vsg::Viewer::create();
auto window = vsg::Window::create(windowTraits);
if (!window)
{
std::cout << "Could not create window." << std::endl;
return 1;
}
viewer->addWindow(window);
InsertStateSwitch rgp;
vsg_scene->accept(rgp);
// compute the bounds of the scene graph to help position camera
vsg::ComputeBounds computeBounds;
vsg_scene->accept(computeBounds);
vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5;
double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min) * 0.6;
double nearFarRatio = 0.001;
// set up the camera
auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0));
vsg::ref_ptr<vsg::ProjectionMatrix> perspective;
auto ellipsoidModel = vsg_scene->getRefObject<vsg::EllipsoidModel>("EllipsoidModel");
if (ellipsoidModel)
{
double horizonMountainHeight = 0.0;
perspective = vsg::EllipsoidPerspective::create(lookAt, ellipsoidModel, 30.0, static_cast<double>(window->extent2D().width) / static_cast<double>(window->extent2D().height), nearFarRatio, horizonMountainHeight);
}
else
{
perspective = vsg::Perspective::create(30.0, static_cast<double>(window->extent2D().width) / static_cast<double>(window->extent2D().height), nearFarRatio * radius, radius * 4.5);
}
auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D()));
// add close handler to respond to the close window button and pressing escape
viewer->addEventHandler(vsg::CloseHandler::create(viewer));
// add trackball to control the Camera
viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel));
// add the CommandGraph to render the scene
auto commandGraph = vsg::CommandGraph::create(window);
uint32_t width = window->extent2D().width;
uint32_t height = window->extent2D().height;
// create the vsg::RenderGraph and associated vsg::View
auto main_view = vsg::View::create(camera, vsg_scene);
main_view->mask = 2;
auto main_RenderGraph = vsg::RenderGraph::create(window, main_view);
commandGraph->addChild(main_RenderGraph);
viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph});
// compile all Vulkan objects and transfer image, vertex and primitive data to GPU
viewer->compile();
// rendering main loop
while (viewer->advanceToNextFrame())
{
// pass any events into EventHandlers assigned to the Viewer
viewer->handleEvents();
viewer->update();
viewer->recordAndSubmit();
viewer->present();
}
// clean up done automatically thanks to ref_ptr<>
return 0;
}