Like other Application Programmers Interfaces (APIs), Warp3D Nova has little "gotchas" that catch programmers out. These are common pitfalls that new programmers fall into. Even experienced programmers can make these mistakes; yes, even the API's designer (i.e., me).
Binding Vertex Arrays to the Wrong Shader Inputs
Setting up vertex arrays is a multi-step process and there are multiple places where things can go wrong. One easy mistake to make is binding the arrays to the wrong vertex shader input (a.k.a., vertex attribute). Accidentally binding the surface normal array to the shader's position attribute will probably result in an empty screen, and you'll be scratching your head as to why.
GLSL compilers don't guarantee that the shader variables remain in the order you put them in unless you use the layout(location = n) qualifier. In fact, I guarantee you that our current compiler does not preserve the order. So you have two options:
- Call ShaderGetOffset() to get the variable's actual location
- Use layout(location = n) to fix the attribute locations, e.g.,
#version 310 es in layout(location = 0) vec3 vertPosition; in layout(location = 1) vec3 vertNormal;
I highly recommend using layout(location = n) to fix the order of the input arrays as this simplifies the code (no need to get the offsets). You still need to carefully bind the arrays to their corresponding shader inputs/attributes, though.
IMPORTANT: Warp3D Nova will put the variables in ascending location order, but doesn't allow gaps. So, if you have a gap (e.g., no location = 2) then the locations won't match the variable attribute number after that gap. ShaderGetObjectInfo() can be used to get the location values in such situations (needed for OpenGL).
Wrong Datatype or Layout for Index Arrays
I recently made this mistake myself via a copy, paste & modify error. I was wondering why DrawElements() was returning an "illegal input parameter" error when I was definitely passing it the index array. Well, the mistake was several lines above:
context->VBOSetArray(vbo, indexArrayIdx, W3DNEF_FLOAT, FALSE, 1, sizeof(float), indexArrayOffset, indexArrayLength);
Spotted the mistake? No? Okay, here's a clue: index arrays must be of type uint16 or uint32 and be tightly packed.
See it now? Yes, I forgot to change W3DNEF_FLOAT to W3DNEF_UINT32. Floating-point indices make no sense whatsoever, and the driver correctly rejected it. At least I got the stride right, although that was pure luck (sizeof(float) happens to equal sizeof(uint32)).
Passing the Wrong Type of Data
The mistake above is a specific example of passing the wrong type of data. It's possible to do this elsewhere too. Put integers in an array where the shader expects floats? Rendering will fail. Use floats when it expects an integer? Rendering will fail yet again. And you won't get an error message, because Warp3D Nova can't tell if you're sending it bad data.
The same goes for putting variables in the wrong place. Get the vertex array stride wrong or put uniform variable data in the wrong place and you'll get confusing results. So when things get weird, check that your data is what the shaders expect.
Check the Error Codes
Most Warp3D Nova functions have error codes which give you a hints as to why calls failed, and it's important to check those when debugging your code. They can't catch data layout mistakes like the ones described above, but will point you in the right direction for other mistakes.
Error codes are useful, but don't always give the full picture. For example, the "illegal input parameter" I got earlier didn't say it was a bad index array. It would be useful to have extra debugging tools. One idea I have is debug layers. A debug layer would wrap around the context and do things such as exhaustive error checking or API call logging (similar to SnoopDos). Such tools exist for OpenGL, and it would be great to have for Warp3D Nova as well. I'm too busy working on Warp3D Nova's core functionality to implement that. Maybe later... unless someone volunteers for the task.
Got Caught Out by Anything Else?
Have you made any mistakes that left you baffled? Let me know via email or leave a comment below. Together we can build a list of the most common ones and help everyone avoid or recover from them.