Assigning a pointer generated from new to a type that is not a pointer
Using delete on objects created with new and not new
Using braces instead of brackets for trying to call the constructor of an object
Returning a pointer pointing to what is supposed to be an array of pointers pointing to pointers (given the new and delete), even though the value being returned isn't of type pointer (which is a double-WTF because if it were to compile, that would still be retarded)
using a lookup method of complexity O(n)
Attempting to declare a return type without template arguments.
Returning a nullptr in the case of not finding an entry, implying that the templated type is always a pointer.
I just came across the following. Regulator_t is a struct holding various parameters.
/* only one of these */
/* initialise regulator */
set_coil_value( 0.0001f, /* 100uH coil */
set_maximum_coil_current( 1.5f, /* allow 1.5 amps */
set_maximum_output_voltage( 200.0f, /* cap output voltage to 200 volts */
set_switching_voltage( 325.0f, /* voltage from rectifier is 230*sqrt(2) = 325V */
set_output_voltage_divider_ratio( 100.0f, /* 1Meg to 10k is a ratio of 100 */
initialise_regulator( theRegulator ))))));
/* ---SNIP--- */
I'm not sure how to feel about this. Someone was obviously trying to be a smartass by defining all "set" functions with the pattern:
Regulator_t* set_whatever( float someValue, Regulator_t* regulator )
regulator->someValue = someValue;
/* do other important stuff */
On one hand, it's a little confusing because the first section of code is executed "backwards", i.e. initialise_regulator is called first and then the chain is executed from the inside out.
On the other hand, it might actually be easier to read than doing it the traditional way:
@all - Thanks a lot, the information provided was very insightful to me, and I see that applying the "OO" style to my program is going to be overkill, adding unnecessary complexity.
Just makes me wish I was using C++ though - any reason you aren't?
Three reasons: Mainly because the program in question is simple, needs to be very close to the underlying hardware, and there actually isn't a compiler (that I know of) that is capable of compiling C++ code to the target architecture.
Even if there were a possibility to use C++, I'd neglect to do so. I feel more comfortable programming micro controllers in C because it keeps things clean and simple. Especially when others work with your code.
If you cut them irregularly using some kind of recognition algorithm, you're just asking for the animation to screw up. How are you going to determine the correct offset for every frame so the animation frames are correctly aligned over one another?
Don't over-engineer things. Sprite sheets have always been designed so every frame has equal size. What purpose is there in changing this? The few bytes of storage space it could save is insignificant, and frankly, I don't see any other motivator to do what you propose.
Yet another example is MineCraft. The world is generated by a 32-bit seed, yet it is infinitely large (theoretically). Obviously, you can't reverse that back into a seed, as explained above.
I would like to point out that early versions of MineCraft used to save the differences between the original world generated by the seed and the modified world edited by the player. Alas, the longer the world existed and the more you mined, the larger the save-files became and the longer it took to apply the differences whenever you loaded the world.
I recommend saving absolute states and not relative states. You can optimize it in many ways, one way is only saving the sub-sections that are different than what was generated by the seed.
Consider using A-star instead of dijkstra, it'll be a lot faster, and requires only a small modification to dijkstra's to make it work.
Secondly, don't rebuild the path every frame. Maybe space the rebuilds over 60 frames (1 second apart). You might even do it in a background thread so the main thread can continue with processing the game, and take over the newly generated graph once its ready.
If you get paid by the number of lines created, or if your boss even cares about this as some kind of metric, it's time to switch job.
Or write the most inefficient, crappy code imaginable. Unroll your for-loops, replace arrays with variables having actual numbers in their names, and obviously add "hacker protection code" to impress your boss - that's far more enterprisey.
Okay, upon closer inspection, I understand why the tangent transformation matrix is being used in the pixel shader. It's because there really isn't any other way to do it.
If you did the transformation in the vertex shader, you'd be limited to the number of texcoord channels, but by moving it to the pixel shader, you can go way over the 8-light-limit. You're just trading that off for speed, because for every single pixel on the screen you're doing light_count+1 number of transforms into tangent space.
My educated guess is that the slowdown has something to do with that transformation matrix.
The way I see it, you have two options:
You could consider multipass lighting. Basically, the pixel shader is called once for every light in your scene, and you blend them all together. It's very speedy because no state changes are involved.
You could optimise the crap out of the current shader, and cross your fingers in the hopes of it being a little bit faster.
If you choose number 1), I need to know something: Is it possible to use for-loops inside a technique?
The TBN matrix is calculated and used in the pixel shader?! That makes zero sense, and is a slowdown in performance. You should never be doing transformations in pixel shaders. It's enough to do the necessary transformations in the vertex shader and pass what's really required to the pixel shader, since the rasteriser does the necessary interpolations. So: Don't pass the binormal, normal, and tangent to the pixel shader. Instead, construct your TBN matrix in the vertex shader and transform the necessary vectors required for lighting in the vertex shader, and then only output what the pixel shader needs.
You are unnecessarily sampling twice from the normal map. Sampling textures is an expensive operation.
The input datatype for your pixel shader is VS_OUTPUT. This means the rasteriser is forced to unnecessarily interpolate registers it doesn't really need (POSITION for instance).
On some cards, using integers for for-loops is a huge slowdown. I've observed this before on my laptop when writing a fractal shader. The solution was to use floats (you might want to consider using float16 to save space and computational power).
You're always allocating space for 16 lights, even though you might only be using 1. This seems inefficient to me.
You might also want to consider using a lower shader model as well. None of the commands in your shader require shader model 3.0.