Saturday, August 27, 2016

Hiatus

Apologies for the late (really late) reply; work has been in full swing and nothing is allowed to be bloggable.

What will this mean? Progress will be down to a crawl (couple of hours on the weekends; I gotta enjoy life as well) but will continue. Keep posted for any progress! I promise it will be visual.

Until then, I'll be working on a base application class for Vulkan.

Friday, August 19, 2016

Nearly There

Whew! Managed to construct all the basic components necessary for the example. Now I just need to create a base class for that example (and any others that may follow).

It's mind-boggling to see how much a low-level API really requires from people in terms of not just knowledge, but sheer self-structuring and (3000+ lines of code). Seems like the input wasn't anything special though; the direction just looks like it's following basic keycodes.

Ah well, I liked using them anyways.

Thursday, August 18, 2016

UI Is Its Own Beast

Yeah, I forgot that. The big components for today were the mesh loading class (which uses assimp, always a top open source choice) and the UI text overlay, which simply does thinks like update for FPS and the like. Thing is, it also requires its own set of buffers, descriptors(especially for the changing text), image objects, command buffers, the works. Seriously, the only thing we could really take out of the thing was composing the device on as a reference.

Soon we shall be back to a main program of sorts at hand! I'll also see what secrets lie in input for this application as well (moving around). It may even be better than DirectInput!

Wednesday, August 17, 2016

The Parts Add Up

Construction continues! Mainly parts on a swap chain and debug tools. The example I'm following also supports linear tiling instead of using a staging buffer, but it's heavily unlikely I'll be using it.

I'm also concerned if using C-style casts is a good idea for void*; I hear a lot that reinterpret_cast isn't a good idea, but I'm also hard-wired to prefer the new C++ casts.

And now working on a texture loader class! I'm actually quite happy that such complex details like image, image memory, and samplers can all be wrapped up in a single object. If only Vulkan followed a similar structure; it seems that they have the parts all there but they could use to be wrapped up nicely.


Tuesday, August 16, 2016

Component by Component

One of the main reasons why I had to start over from the ground up instead of carefully find out what the problem was (other than just not knowing how) was me not slicing the application (Vulkan) into enough components.

Some of the main ones I focused on today was a buffer object to hold things such as the buffer, device memory, and a reference to the device in question. This was linked to the object that I was also working on, an instance that holds both physical and logical device instead of keeping them separate.

One of the more interesting and helpful methods I learned was to actually make up for the heavy code writing for setting up structs by actually creating initializing functions for them. They had none of their own, so instead of

struct s = {};
s.a = 1;
s.b = 2;
s.c = 3;
...
Or {1, 2, 3}, since the members got a bit tricky to understand and a constructor (not present for the structs) would come in handy.

This is still a fairly lengthy process, so I definitely won't get anything on the screen until I'm absolutely sure it works.

Monday, August 15, 2016

Failure Once More

Yeugh, that's what I get for following a tutorial that doesn't have an established project. I get all the way to model construction and nothing shows.

Turns out I'll have to start from square one, but by following some more proper examples that work. Who knows? Maybe it'll work out better this time. But right now, I nor the source code can explain why a blank screen shows instead of a model.

Sunday, August 14, 2016

Texturing in the Deep

Today managed a couple more simple topics through the excessive complexity of Vulkan.

First off, texture mapping! The image is a bit different from buffers, which required a different set of functions for copying, creating, and transferring image objects. I also had to create a sampler object and combine the layout with the uniform buffer object to make sure it got read through the shader. Luckily enough, the texture coordinates weren't too difficult to add to the shader. Voila!


I also added some quick linear filtering and texture addressing for repeating textures:



We can even quickly multiply a color! But this is simple enough once we get past setting up the proper image object, memory, and view:


But wait! What's this:


The left object is actually behind the right; this means I need to setup depth calculations, which includes testing for the correct depth-stencil format and setting up the proper depth image view along with the swap chain image views when presenting to the screen. That way, we can use the z-buffer to show the correct pixel at the correct depth:


We need some 3D models, though! Time to tackle some model loading.

A shout out to the stb library and the tinyobjloader library for containing single header files instead of static library linking! It definitely makes it easier for multiple platforms and configurations.

Friday, August 12, 2016

In Space

Phew, the information is nearly overloading my brain with how much Vulkan requires to even get a proper world-view-projection matrix setup in the uniform buffer. The uniform buffer follows a similar setup to the vertex and index setup, but a resource descriptor has to be created for data that updates frame by frame. This also requires an in-depth setup with the pool of memory in which the descriptor set came from. Yikes!

However, this means that we can now present an object moving in space! I also found a tip to use std::chrono to easily use that as frame-time when measuring time-based movement. Though a flipping square doesn't need too much adherence to time-based movement, it is a helpful method:


As for actual textures, watch out! I'm now working on an image object. The image object works much like a buffer, but has slightly different bindings and setups. I will keep using the stb library they recommended; it works very well and only requires a header file (instead of that static-linked SOIL).

Thursday, August 11, 2016

Wait, a Square

Such wonders a buffer can hold! Today was mainly spent working with buffers; these objects are similar to the DX11 buffers, except we can use a staging buffer to allocate them from high performance memory then transfer them to longer-lived buffers. In this way, I can change input data without having to re-do the whole shader and compilation process:


However! Not all is set for buffers; the index buffer is also available in a similar format, which works very much so like index drawing for DX11:


What's next? Resource descriptors! They are required to setup free access to resources during drawing such as buffers and images. What buffer? A uniform buffer, which means world/view/projection fun times!

Wednesday, August 10, 2016

Actual Imagery

Phew! After all these days of setting up the framework, I finally got a thing going on the screen!


It's also resizable, which means I had to properly setup the GLFW callback and recreate the swap chain (along with all other things connected to it) after the swap chain images were invalidated by a resize.

After creating the command buffers, I also had to create synchronization objects. With Vulkan, we could either use fences or semaphores, so I used a semaphore for image availability and render finishing. This also requires waiting if anything (like swap chains) in the system had to be changed during program running.

And with that, the image is finally presented to the screen! Let's try actual input data this time.

Tuesday, August 9, 2016

Piping that Line

Phew, the extra components required to setup graphics programming never ends! I'm getting much more in depth to the process of drawing a triangle than I ever felt possible!

I pulled in the necessary components for fixed functions (input assembly, rasterization, color blending) and also had to make a render pass that would inform Vulkan about the framebuffers it would be attached to.

Then I had to make the framebuffers! And the whole pipeline object. Everything's static for now, as a dynamic array would be necessary to specify to the pipeline what would change over time. Otherwise I'd have to recreate the pipeline.

And now onto command pools and command buffers! Because an API known for multithreaded wonder has to setup the render commands with a specific pool of multithreadable memory somehow.

Monday, August 8, 2016

Rising From the Ashes

Wowza, I totally forgot that because I was using educational software, they had to RIP it away from me in a computer wipe. I did manage to come back, though! I keep most of my big projects intact so they may live on through my website, and I did a similar gesture for my current Vulkan work.

As for my current Vulkan work? Since today was a lot of installations, I mainly had time to setup image views (which were also encapsulated in RAII objects, but I totally forgot) and start working on the shader pipeline.

Very interesting tidbit - shaders are actually read in as bytecode through Vulkan programs. The actual compilation of the shaders into .sfv bytecode (SPIR-V's the name) is actually done separate from the code. This ensures much quicker loading than kid-friendly GLSL/HLSL. However, I can still use GLSL shaders as long as they are compiled into SPIR-V format.

According to this pipeline, I can fully program vertex/geometry/fragment shaders and tessellation, and also control quite a bit of the color blending/rasterization processes.

Sunday, August 7, 2016

Devil in the Details

The itty bitty and the nitty gritty keeps going at me in Vulkan. No end in sight just yet. Apart from making the mistakes of callback functions being class member functions and trying to use native GLFW code, I'm making a bit of progress.

The main big things that I've learned are that Vulkan treats GPUs (and other such objects) as physical devices. How to interact with them? Interfaces called physical devices.

What of the window interaction? There's a window surface, but don't forget the various queues for graphics, presentation, and the swap chain for images. All these require intimate and in-depth structure-based creation, with possible iteration to either find the one that can or a best one. In one case, one can look for ideal things such as geometry shader support (essential) or discrete GPU architecture (optional, but highly preferred).

As for that triangle? Welp, this is Vulkan we're talking about. We've still got views for our images on the swap chain AND creating our pipeline from the ground up. This is gonna be awhile.

Saturday, August 6, 2016

Vulkan's Hammer

Vulkan is a beast; that's all I can say.

I'm currently working with setting up the development environment and making sure everything's linked the way it should. This means using extensions like GLFW and libraries like GLM to build around the Vulkan code. The Vulkan code is right now starting out with creating things such as instances and devices.

This means tricky memory management! However, I built a templated class to help differentiate between destroying and cleaning up various objects' (VkInstance, VkDevice) memory upon destruction of the object.

What's next? Validations layers and debug callbacks! We'll probably turn them off when making the actual rendering in order to make it quick, which is a good thing! Bad thing is that we have to build it all from the ground up. Ugh.

Thursday, August 4, 2016

Lurking from the Shadows

Finally! I figured out what the shadow blob needed in order to show up. Originally we wanted to reduce shadowing in the project, but there was no way to completely reduce shadows unless we got rid of them altogether. Enter the shadow blob, a quick way to vary a texture placed on a quad on a surface. Thing is, I had no idea the example used world position, not relative position. This meant the blob would only be at the height of 0 in world space each time. Now we have...a shadow blob!


As for extra project work, the memory manager's taken a side, as it really doesn't need too much else. What else to work with? Why not Vulkan? It's a strange and powerful API, so it might do me well to at least learn the basics.

Wednesday, August 3, 2016

Unexpected Brainfry

Yeuch, my brain is awash. I fixed up a massive crash bug in our capstone project again (seems as if the bridge manager was casting without checking for a successful cast) and fixed a variety of little things. Missing walls, precarious perches and misplaced menu options.

As for the memory manager, I attempted to place it inside either a dynamic library or a static library; unfortunately, that class set is not usable from a dynamic linking (static helper functions only) and the attempt to move the code to a static library was...ugly. Missing assemblies and god knows what else. I managed to put it just in an example project, so I'll stick with getting the memory to work before expanding it into something linkable to other projects.

I nearly lost hope, but realized that I forgot to cast the pointer properly when subtracting the header size from it. I should definitely not make these coding sessions late in the evening.

Brain, rest!

Tuesday, August 2, 2016

Terrain Release

Due to today being stocked with so many final presentations, there's not too much work I was up to today.

For allocators, I created two more - a fixed-size, fixed-alignment allocator for fast and uniform allocations/deallocations, and a proxy allocator. What does a proxy allocator do? It essentially holds another allocator and provides the option to store debug information if necessary.

As for the terrain, it's finally released online! Check out my website (here) and go to my Portfolio link to download the full source.

A few more hours and this presentation extravaganza will be over...

Monday, August 1, 2016

Free the List

And yet, I am not allowed to stop capstone work just yet. There was an instance where the elevator did not hit the ground (conflicting geometry) and the insect used attacks that were de-programmed.

That said, we fixed it and the build is again ready to go!

As for memory manager work, I fixed up a stack allocator and the free list (linked list) allocator; hopefully best-fit will work better than first fit for free-block finding!