Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 14 Feb 2007
Offline Last Active Today, 02:11 AM

#5274743 Best way of finding resource leaks

Posted by Hodgman on Yesterday, 06:19 AM

If you've got your own D3D wrapper, then whenever you create a resource, capture a call-stack and a user defined name and store it alongside the resource. When shutting down, print out the names and creation-call-stacks for any leaked, objects. That will at least tell you where it came from.

#5274717 which way is more efficient to implementing texture atlas

Posted by Hodgman on 06 February 2016 - 10:06 PM

because the same texture can be used in multiple scenes,if i make texture atlas for every scene ahead of time,there will be many texture duplication

This isn't necessarily a problem. It only affects the size of your game on disc, and how long it takes to download (and this can be almost entirely fixed by using good compression that takes advantage of the duplication!).
On PS3 it was actually common to deliberately duplicate assets on the game disc, as seeking a BluRay is very slow, so it's better to make sure that every scene is saved in a contiguous blob on the disc.

#5274606 Have You Ever....?

Posted by Hodgman on 06 February 2016 - 01:18 AM

Have you ever tried to refactor a big-picture part of your code's architecture, and bit off a larger chunk than you could chew at once, taking more than two weeks to get your code even compiling again, let alone running?
Try two months! Was porting someone else's product with a looming deadline... Oh gawd the stress...

#5274588 Any alternatives to automatic class instantiation via macro?

Posted by Hodgman on 05 February 2016 - 08:56 PM

If you're keen on it, put it into a "helper"/"utility" layer that's optional. It only saves you 3 lines of code, once in thr entire application -- macros are generally used where they'll be paying off more than that.

Also, I'd personally find it more idiomatic for thr "app" object to be executed via operator() rather than a named method, and would call the macro something like:
#define DECLARE_MAIN(T)\
int main(int argc, char **argv){\
    T app(argc, argv);\
    return app();
If you're porting to a bunch of different platforms, which all use non-standard names for the main function, then it might be handy to have a wrapper for "main". This is common on engines that need to run in different environments, such as Java, .NET, etc as well as "native apps" -- i.e. on some platforms you can't write your main function in C/C++!
In that situation, you'd write a standard main for every platform which then calls out to some forward-declared but non-existent custom-main function that the user can implement.

Alternatively, if you want to force the user to use a "main object" like in your example, you could use your macro, or force the user to define it as a compiler -D option, e.g. your engine might include:
int main(int argc, char **argv){
#ifndef MAIN_CLASS
#error "You must define MAIN_CLASS when compiling the engine"
    MAIN_CLASS app(argc, argv);
    return app();
Or you can simply declare the main class but not implement it:
class Main { public:
  Main( int argc, char** argv);
  int Run();
void* userdata;
int main(int argc, char **argv){
    Main app(argc, argv);
    return app.Run();

#include "app.h"
Main::Main( int argc, char** argv) { userdata = 0; }
int Main::Run()
{ return 42; }
But I agree with others that it's better to let the app write it's own main function...

#5274567 which way is more efficient to implementing texture atlas

Posted by Hodgman on 05 February 2016 - 07:31 PM

Can you do #3 -- make a tool that combines all the textures ahead of time, so that you don't have to do #1/#2 at runtime at all?

#5274549 Dumping every frame to an image file

Posted by Hodgman on 05 February 2016 - 05:25 PM

Is there a way to save the frames like this?

Sure. You can use IDirect3DDevice9::GetRenderTargetData to get the pixels from the GPU, and then save them to disk using whatever format you like (I find TGA is easy for raw pixel dumps).

#5274432 Fake Blur after 2D Ray Tracing in one pass

Posted by Hodgman on 05 February 2016 - 07:01 AM

To do a blur, you need to be able to fetch the results of neighboring pixels (or pass your result to neighboring pixels)... which generally means you need all the data to be generated in a pass before the blur begins (in a later pass).


If the SSR is generated in a compute shader, you can use memory barriers to implement limited communication techniques within the one pass.

In a pixel shader, you can use the ddx_fine and ddy_fine instructions to communicate between neighboring pixels in a 2x2 pixel grid area (see "Shader Amortization using Pixel Quad Message Passing" in GPU Pro 2 if its available to you).

Besides that, you'll need to perform the blur in an additional pass (or two!).


What's the rationale behind wanting to do it all in one pass?

#5274403 Are computer skills necessary for becoming a game designer?

Posted by Hodgman on 05 February 2016 - 02:13 AM

Despite not being proficient now, you can become proficient if you choose to practice.

Whether you're proficient or not, getting hired as a game designer is always a challenge -- it's a very rare job.

Don't just practice being an "ideas guy" make sure you also practice the hard parts of game design (mechanics, interactions, emergence, balance, pacing, statistics...)

#5274397 Footware at work

Posted by Hodgman on 04 February 2016 - 11:06 PM

When I worked in corporate software, I got told off for wearing thongs ("flip flops"), as apparently it's a breach of workplace safety laws, and leaves them open to a lawsuit if I hurt my toes, or whatever...


In games software, it's common for people to be shoeless and not get told off :lol:

#5274363 Circular clipping (Target HUD)

Posted by Hodgman on 04 February 2016 - 07:14 PM

Use the clip intrinsic in your shader:
clip( -distance( texcoord, circleCenter_texcoord ) + circleRadius )

#5274218 When you realize how dumb a bug is...

Posted by Hodgman on 04 February 2016 - 06:06 AM

I use /Wall (except for PCH and few codes like automatic inline and padding) on MSVC2015 but it didn't warned me :\ 
EDIT: even the static analyser does not warn :\
Really? You should get e.g.:

1>------ Build started: Project: engine (Visual Studio 2010), Configuration: Dev Win32 ------
1>  Model.cpp
1>..\..\src\gx\Model.cpp(319): error C2220: warning treated as error - no 'object' file generated
1>..\..\src\gx\Model.cpp(319): warning C4390: ';' : empty controlled statement found; is this the intent?
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

#5274216 Any portable/semi-portable way of forcing class field order in C++?

Posted by Hodgman on 04 February 2016 - 05:50 AM

So far Googling has led me to the notion that it's, to quote StackOverflow, "a bit of a nightmare".

The SO ivory tower is a tad different to the real world.
I've seen this type of code, working easily, in almost every game I've worked on and make extensive use of it on my current projects. Just make it a POD struct full of public (default) members, use fixed-size types, and be aware of padding/alignment rules.
Like LS, I use static assertions on the size to catch stupid errors, and static assertions on the offsets if I'm being really careful.
On all the platforms/compilers that you care about, the padding/alignment rules will almost certainly be predictable, fairly sane, and reliable enough to write this kind of code without even having to worry about portability issues.

Biggest portability issue that I have is sometimes I have a pointer field in these structs -- or an integer 'offset' that is converted into a real pointer on load. This creates two different versions of the struct for 32/64bit platforms, which sometimes is fine if you're building the data per platform (just be sure to use a pointer-sized integer), or alternatively I have a typedef for a "cross-platform pointer sized integer", which is basically uint64_t laugh.png

#5274185 WVP and vertex position relationship

Posted by Hodgman on 04 February 2016 - 01:06 AM

Hmmmm. Even when I post multiply the vertex vector (5,5,5,1) with the WVP matrix I get the exact same answer (as I suspected earlier).

1.66292 0       0       0
0       2.21723 0       0
5       5       16.002  1
0       0       -2.002  0

This doesn't make sense -- a vector4 (AKA 1x4 matrix, or 4x1 matrix, depending on conventions) multiplied by a matrix4x4 produces a vector4 result -- it does not produce a matrix4x4 result.

You want to be doing this, where P/V/W are Mat4x4's, and Vertex is a Mat4x1 (aka Vector4 - and Vertex.w should be 1.0):
ProjectedVertex = Projection * View * World * Vertex
Note that you can do it this way, which is three "Mat4x4 * Mat4x1" operations:
ProjectedVertex = Projection * (View * (World * Vertex))
Or you can do it this way, which is two "Mat4x4 * Mat4x4" operations, and one "Mat4x4 * Mat4x1" operation:
ProjectedVertex = ((Projection * View) * World) * Vertex
Both should produce the same result.
So... as well as your Mat4x4 Multiply(Mat4x4 a, Mat4x4 b) function, you also need a Vec4 Multiply(Mat4x4 a, Vec4 b) function.

Also, assuming there are no transforms, rotations, & scaling required. Couldn't you just multiply VP with the vertex vector?

Yes. The "world" matrix is actually the "model space to world space transform". If the vertices are already in world-space, then this matrix would be identity, which does nothing (so could be optimized out).

#5274183 WVP and vertex position relationship

Posted by Hodgman on 04 February 2016 - 12:32 AM

World matrix (actual vertex pos is 5,5,5

The world matrix is not a vertex...

I would have though the new x & y co-ords

You haven't transformed any vertices yet. You can't have new x & y coords if you don't even have original/input x & y coords.
After creating a WVP matrix, you can multiply the vertex position [x,y,z,1] against the WVP matrix to get [x',y',z',w']. The screen (NDC) pos is then: XNDC = x'/w', YNDC = y'/w'

#5274175 When you realize how dumb a bug is...

Posted by Hodgman on 03 February 2016 - 11:26 PM

You've just gained +5 development points in the programming skill-tree.

You've also suddenly realised why all the people who complain about Python's syntactically-significant whitespace are wrong ;)

And why you should enable a strict warning mode and warnings-as-errors in C++. That code should be a compile time error :)