I've been working on a major re-write of the library. For this newer version I've currently dropped support for PSP and Wii, as I wanted to work with systems that support shaders. Now, the current supported platforms are PC, PS3, PS Vita, and Switch. I'd also like to add support for the original XBox as that supports shaders also.
The previous version I've added a git tag for as v0.1.
The following improvements have been added compared to the previous version so far:
Missing features from v0.1:
Static & animated models/file formats
Bounding volume debug drawing
Physics
Music/Audio
Threads
Below shows the current shadow and scene graph/hierarchy in action: the ground is the root node, then sphere then cube as children, each transform affecting its children:
Working on simplifying/unifying shaders between platforms. PC and Switch use GLSL while Vita and PS3 use Cg. Although the VitaGL github says there is experimental GLSL support, TODO look into that.
I'm not really too familiar with Cg so I spent some time looking at the following links: https://developer.download.nvidia.com/cg/Cg_3.1/Cg-3.1_April2012_ReferenceManual.pdf , https://developer.download.nvidia.com/CgTutorial/cg_tutorial_chapter01.html
While attempting to implement the shadow mapping shader for Vita, I found that glGetShaderInfoLog wasn't returning anything. Re-installed VitaGL from source, enabling error logging via "make HAVE_SHARK_LOG=1 LOG_ERRORS=2." and then I could see why the shader compilations were failing.
Vita doesn't have inverse function in shader, so defined one for float3x3 using the same logic from the HopsLib math source code.
VitaGL also doesn't support using a depth attachment to a framebuffer, so I attempted to calculate it and store it in the color attachment, using the following reference for calculation: https://stackoverflow.com/questions/10264949/glsl-gl-fragcoord-z-calculation-and-setting-gl-fragdepth, https://stackoverflow.com/questions/6408851/draw-the-depth-value-in-opengl-using-shaders#6409229
It kind-of works, but the objects themselves have some incorrect shading/ artifacts. Good enough for now though:
Am currently attempting to update and run the PS3 version. The same Cg shaders are compiling for ps3 as for Vita, but I think there are some code fixes needed for creation/usage of a framebuffer for rsx. The skybox is drawing and the game isn't crashing (at least in rpcs3), but the scene itself is not rendering.
Updating the ps3 version - the cg shaders from the vita are compiling. While making a basic unlit shader for debugging, had to send the vertex normals to the fragment shader even though they were unused so that the cg compiler didn't optimize them away; this was causing the normals to be used as the color in the fragment shader.
Now that that's working, next is to get the framebuffer ps3 impl working.
PS3 current shadow map impl working. I debugged the the shadow depth map generation by displaying the texture onscreen as a sprite. I noticed the PS3 version was flipped vertically compared to the PC and Vita versions. My workaround for this so far is to add a define during PS3 shader calculation to flip the uv y coordinate in the cg fragment shader. In Makefile.ps3, I added:
# Cg compiler flags
CGCFLAGS := -Wcg,-DHOPS_PS3_BUILD=1
Then in ShadowedFragment.fcg:
float2 uv = clamp(projCoords.xy,0,1);
// set in Makefile.ps3
#ifdef HOPS_PS3_BUILD
uv.y = 1.0 - uv.y;
#endif
I also needed to normalize the color attribute and the light space fragment position, and clamp the shadow map uv between 0 and 1; and to change the clear color for the color buffers to 1/white instead of 0/black in order to match the original PC depth buffer texture. These changes also had the benefit of getting rid of the artifacts the Vita version previously had.
Original PC shadow map using depth buffer:
Flipped ps3 shadow map texture, using color buffer:
Fixed shutdown crash on Vita, kind-of fixed on ps3. Ps3 hangs then beeps three times but exits to the home screen as opposed to totally freezing like before. On vita I was re-freeing the texture for the framebuffer as it was already freed by the framebuffer class. On Ps3 the shader class was freeing the embedded skybox and 2d sprite shaders, and also wasn't handling when the home button/exit is pressed. Also, I was calling free() instead of rsxFree() on the ps3 vertex buffer memory. Not sure why the ps3 is hanging/beeping on exit currently. Might have to do something with in the sample code, gcmSetWaitFlip()/rsxFinish() are the very last function calls done in the system exit callback, as opposed to the Renderer destructor.
Integrated Imgui, at least visually so far. Interaction (being able to close/move/select dropdowns) is next. PC/Vita/Switch were fairly straightforward, I was able to follow the OpenGL3 implementation from https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp.
On PS3 I ran into more issues. First, as ps3 is big endian, the ImGUI RGBA generated texture was actually ABGR because each pixel is packed into a 32bit integer, hence the bytes were backwards. Additionally, the texture format uploaded to gpu memory is in ARGB format (as opposed to RGBA) which caused the bytes to be even more scrambled. The vertices color attribute given by ImGUI is also a 32 bit integer, which again was flipped bytewise. For the OpenGL implementations you can normalize the attribute to a vec4 float, but that wasn't available in the ps3 rsx library. I tried doing the conversion in the vertex shader but they don't support bit shifting and masking. I instead tried just doing divisions and subtractions to extract each color component, but I couldn't get that working either. I finally ended up doing the conversion in the Vertex buffer init/update functions, converting to a custom vertex structure instead which has a vec4 for the color instead of the 32bit int. This also does the byte swapping so the RGBA values are in the correct order. Whew! The results (initial errors + working version) are shown below:
Basic imgui input on PC working; TODO gamepad/joystick support. Also missing mouse scrollwheel input atm. Implementation is fairly straightforward. There is a ImGui_ImplHops_ProcessEvent() function that maps Hops input keys/mouse to ImGui keys which you forward to the ImGui io object.
Controller/joystick input for imgui working. Tested on PS3, initially found rendering issue when using multiple windows:
I'm guessing the issue was that we were overwriting the vertices in the rsx memory while the old ones were still being rendered. Switching to using one vertex buffer per imgui draw list fixed the issue.
Currently now am having a rendering issue on switch where the imgui components are rendering fine but the background 3d scene right now is not rendering at all, just the screen background clear color.
Fixed switch issue. Turned out not to be a rendering problem, it was actually that the joystick analog values were not being initialized, sometimes resulting in garbage values that were being read as camera movement input and causing the scene to go haywire. That's what I get for not initializing all my variables properly, like in the constructor. I also never added the update on switch to accept analog input, so I added that too:
// new; were missing before
mLeftJoyX = mLeftJoyY = 0.0f;
mRightJoyX = mRightJoyY = 0.0f;
...
const HidAnalogStickState& stickL = gPad.sticks[0];
const HidAnalogStickState& stickR = gPad.sticks[1];
// scale from -32768,32768 to -1,1
mLeftJoyX = float(stickL.x)/32768.0f;
mLeftJoyY = -float(stickL.y)/32768.0f;
mRightJoyX = float(stickR.x)/32768.0f;
mRightJoyY = -float(stickR.y)/32768.0f;