public void Initialize(string utopiaPath) { if (_engine == null) { _utopiaFolder = utopiaPath; ClientSettings.PathRoot = _utopiaFolder; ClientSettings.EffectPack = Path.Combine(_utopiaFolder, @"EffectsPacks\Default\"); ClientSettings.TexturePack = Path.Combine(_utopiaFolder, @"TexturesPacks\Default\"); _engine = new D3DEngine(); DXStates.CreateStates(_engine); } var modelsStorage = new ModelSQLiteStorage(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Realms", "Common", "models.db")); var voxelMeshFactory = new VoxelMeshFactory(_engine); _modelManager = new VoxelModelManager(); _modelManager.VoxelModelStorage = modelsStorage; _modelManager.VoxelMeshFactory = voxelMeshFactory; _modelManager.Initialize(); _visualWorldParameters = new VisualWorldParameters(); _textureManager = new CubeTexturesManager(_engine); _textureManager.Initialization(_engine.ImmediateContext, FilterFlags.Point); _cubeTextureView = _textureManager.CubeArrayTexture; _visualWorldParameters.CubeTextureManager = _textureManager; _iconFactory = new IconFactory(_engine, _modelManager, _visualWorldParameters); //ArrayTexture.CreateTexture2DFromFiles(_engine.Device, _engine.ImmediateContext, // Path.Combine(ClientSettings.TexturePack, @"Terran\"), @"ct*.png", // FilterFlags.Point, "ArrayTexture_DefaultEntityRenderer", // out _cubeTextureView); }
public void Refresh() { Vector3Int newDimensions = voxelGrid.GetBinGridDimensions(); if (dimensions == Vector3Int.zero) { dimensions = newDimensions; } int newLength = newDimensions.x * newDimensions.y * newDimensions.z; if (meshObjects == null) { meshObjects = new MeshObject[newLength]; } Debug.AssertFormat(newDimensions.x <= dimensions.x && newDimensions.y <= dimensions.y && newDimensions.z <= dimensions.z, "VoxelBuilder size: {0} > {1}!", newDimensions, dimensions); dimensions = newDimensions; Mesh[] meshes = new Mesh[newLength]; for (int i = 0; i < newLength; i++) { Bin bin = voxelGrid.GetBin(i); if (VoxelMeshFactory.TryGetMesh(bin, out meshes[i]) && meshObjects[i] == null) { meshObjects[i] = Instantiate(meshObjectPrefab, meshTransform).GetComponent <MeshObject>(); // TODO: make a global meshobject pool } } for (int i = newLength; i < meshObjects.Length; i++) { if (meshObjects[i] != null) { Destroy(meshObjects[i].gameObject); } } StartCoroutine(WaitThenFinishRefresh(meshes, meshObjects, newLength, dimensions, material)); }
public void TestVoxelMeshFactory() { VoxelMeshFactory.RunTests(); }
static void Main(string[] args) { Console.WriteLine(AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES").ToString()); Console.WriteLine($"Hello Vulkan!"); Init(); if (!GLFW.Vulkan.IsSupported) { Console.Error.WriteLine("GLFW says that vulkan is not supported."); return; } WindowHint(Hint.ClientApi, ClientApi.None); NativeWindow window = new GLFW.NativeWindow(width, height, "Fabricor"); Glfw.SetKeyCallback(window, (a, b, c, d, e) => { GLFWInput.KeyCallback(a, b, c, d, e); }); FInstance finst = new FInstance(); VkSurfaceKHR surface = CreateSurface(finst.instance, window); VkDevice device = CreateDevice(finst.instance, out var physicalDevice, surface, out var queueFamilyIndex); VkSwapchainKHR swapchain = CreateSwapchain(VkSwapchainKHR.Null, finst.instance, device, physicalDevice, surface, queueFamilyIndex); VkRenderPass renderPass = CreateRenderPass(device); uint swapchainImageCount = 0; Assert(vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, null));////////////IMAGES VkImage[] swapchainImages = new VkImage[swapchainImageCount]; fixed(VkImage *ptr = &swapchainImages[0]) Assert(vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, ptr)); CommandPoolManager.Init(device, queueFamilyIndex); int poolId = CommandPoolManager.CreateCommandPool(VkCommandPoolCreateFlags.ResetCommandBuffer); VkSemaphoreCreateInfo pCreateInfo = VkSemaphoreCreateInfo.New(); VkSemaphore acquireSemaphore = new VkSemaphore(); vkCreateSemaphore(device, &pCreateInfo, null, &acquireSemaphore); VkSemaphore releaseSemaphore = new VkSemaphore(); vkCreateSemaphore(device, &pCreateInfo, null, &releaseSemaphore); VkQueue graphicsQueue = VkQueue.Null; vkGetDeviceQueue(device, queueFamilyIndex, 0, &graphicsQueue); string[] textures = new string[] { "res/Linus.png", "res/Alex.png", "res/Victor.png", "res/Alex2.png", //"res/Cyan.png", "res/Alex3.png", //"res/Red.png", }; FTexture texture = new FTexture(device, physicalDevice, poolId, graphicsQueue, textures, VkFormat.R8g8b8a8Unorm, 512, 512, (uint)(Math.Log(512) / Math.Log(2)) + 1); VkPipelineCache pipelineCache = VkPipelineCache.Null;//This is critcal for performance. FGraphicsPipeline voxelPipeline = new FGraphicsPipeline(device, physicalDevice, pipelineCache, renderPass, "shaders/voxel", swapchainImageCount, texture); voxelPipeline.CreateDepthBuffer(physicalDevice, (uint)width, (uint)height); VkImageView[] swapchainImageViews = new VkImageView[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { swapchainImageViews[i] = FTexture.CreateColourImageView(device, swapchainImages[i], surfaceFormat.format); } VkFramebuffer[] frambuffers = new VkFramebuffer[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { frambuffers[i] = CreateFramebuffer(device, renderPass, swapchainImageViews[i], voxelPipeline.depthImageView); } MeshWrapper <VoxelVertex> mesh = VoxelMeshFactory.GenerateMesh(device, physicalDevice); Action updateMesh = delegate { VoxelMeshFactory.UpdateMesh(device, physicalDevice, mesh); }; GLFWInput.Subscribe(Keys.U, updateMesh, InputState.Press); Action changeTexture = delegate { Span <VoxelVertex> span = mesh.Mesh.vertices.Map(); for (int j = 0; j < span.Length; j++) { span[j].textureId++; } span = mesh.Mesh.vertices.UnMap(); }; GLFWInput.Subscribe(Keys.F, changeTexture, InputState.Press); FCommandBuffer[] cmdBuffers = new FCommandBuffer[swapchainImageCount]; VkFence[] fences = new VkFence[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { cmdBuffers[i] = new FCommandBuffer(device, poolId); VkFenceCreateInfo createInfo = VkFenceCreateInfo.New(); createInfo.flags = VkFenceCreateFlags.Signaled; VkFence fence = VkFence.Null; Assert(vkCreateFence(device, &createInfo, null, &fence)); fences[i] = fence; } FCamera camera = new FCamera(); camera.AspectWidth = width; camera.AspectHeight = height; camera.position.Z = -1f; //camera.rotation=Quaternion.CreateFromYawPitchRoll(MathF.PI,0,0); double lastTime = Glfw.Time; int nbFrames = 0; while (!WindowShouldClose(window)) { PollEvents(); GLFWInput.Update(); // Measure speed double currentTime = Glfw.Time; nbFrames++; if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1 sec ago // printf and reset timer Console.WriteLine($"ms/frame: {1000.0 / nbFrames}"); nbFrames = 0; lastTime += 1.0; } if (GLFWInput.TimeKeyPressed(Keys.D) > 0) { camera.position += Vector3.Transform(Vector3.UnitX * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.A) > 0) { camera.position -= Vector3.Transform(Vector3.UnitX * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.W) > 0) { camera.position += Vector3.Transform(Vector3.UnitZ * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.S) > 0) { camera.position -= Vector3.Transform(Vector3.UnitZ * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.Space) > 0) { camera.position += Vector3.Transform(Vector3.UnitY * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.LeftShift) > 0) { camera.position -= Vector3.Transform(Vector3.UnitY * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.Right) > 0) { camera.rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0.00015f); } if (GLFWInput.TimeKeyPressed(Keys.Left) > 0) { camera.rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, -0.00015f); } uint imageIndex = 0; Assert(vkAcquireNextImageKHR(device, swapchain, ulong.MaxValue, acquireSemaphore, VkFence.Null, &imageIndex)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; voxelPipeline.swapchainFramebuffer = frambuffers[imageIndex]; voxelPipeline.swapchainImage = swapchainImages[imageIndex]; voxelPipeline.swapchainImageIndex = imageIndex; voxelPipeline.mesh = mesh; voxelPipeline.camera = camera; fixed(VkFence *ptr = &(fences[imageIndex])) { vkWaitForFences(device, 1, ptr, VkBool32.False, ulong.MaxValue); vkResetFences(device, 1, ptr); } cmdBuffers[imageIndex].RecordCommandBuffer(new Action <VkCommandBuffer>[] { voxelPipeline.Execute, }); VkPipelineStageFlags submitStageMask = VkPipelineStageFlags.ColorAttachmentOutput; VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = &acquireSemaphore; submitInfo.pWaitDstStageMask = &submitStageMask; submitInfo.commandBufferCount = 1; fixed(VkCommandBuffer *ptr = &(cmdBuffers[imageIndex].buffer)) submitInfo.pCommandBuffers = ptr; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &releaseSemaphore; Assert(vkQueueSubmit(graphicsQueue, 1, &submitInfo, fences[imageIndex])); VkPresentInfoKHR presentInfoKHR = VkPresentInfoKHR.New(); presentInfoKHR.swapchainCount = 1; presentInfoKHR.pSwapchains = &swapchain; presentInfoKHR.pImageIndices = &imageIndex; presentInfoKHR.waitSemaphoreCount = 1; presentInfoKHR.pWaitSemaphores = &releaseSemaphore; Assert(vkQueuePresentKHR(graphicsQueue, &presentInfoKHR)); vkDeviceWaitIdle(device); } finst.Destroy(); DestroyWindow(window); Terminate(); }