Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 06 Jun 2010
Offline Last Active Today, 12:21 AM

#5289218 OpenGL Issues

Posted by mhagain on 29 April 2016 - 05:35 AM

Please see:






Specifically, this is an Arrandale CPU with Ironlake graphics.  It supports Direct3D 10.1 (not 11) and OpenGL 2.1 (not 4.x); it does support shader model 4.1 under Direct3D, but that's not the same thing as the OpenGL version.


So since your hardware doesn't support any GL version beyond 2.1, you're stuck with OpenGL 2.1.

#5288796 Returning by value is inevitable?

Posted by mhagain on 26 April 2016 - 12:37 PM

Anyone care to explain what is wrong with the static variable solution? I've used this for years and always thought it was a convenient and fast solution.


Compute (Function (x), Function (y));


If "Function" uses the static variable trick, does this work?

#5288577 CreateBuffer throws _com_error exception and I can't catch it

Posted by mhagain on 25 April 2016 - 05:28 AM

My reasoning for the parameters: box is NULL (no offset), SrcRowPitch = the total amount of data passed, SrcDepthPitch = 1 since there is just one array of data.

Depth pitch is not the number of depth slices, but rather the number of bytes between each depth slice.  In the MSDN samples, when updating a non-volume resource, depth pitch is set to 0, so you should follow that example and set it to 0 yourself.  The documentation could, of course, have been clearer about that.

#5287825 CreateBuffer throws _com_error exception and I can't catch it

Posted by mhagain on 20 April 2016 - 01:51 PM

You shouldn't be handling exceptions from this.  At all.


ID3D11Device::CreateBuffer returns a HRESULT and the returned values are well-defined in the documentation.  The correct way to handle D3D errors is the documented way: check the HRESULT returned by the call.

#5287465 Compiling HLSL to Vulkan

Posted by mhagain on 18 April 2016 - 08:32 AM

It should be possible (and more useful) to remove GLSL entirely from this, and do HLSL bytecode directly to SPIR-V.

#5287324 Trying to understand normalize() and tex2D() with normal maps

Posted by mhagain on 17 April 2016 - 11:23 AM

"Unit length" means x * x + y * y + z * z = 1.  It might help if you try to visualize this as points on a sphere of radius 1.  When you do linear interpolation between 2 such points you're actually taking a straight line between them, not a curve, and hence the distance from the center to the interpolated point is no longer 1.

#5287049 Which per-frame operations are expensive in terms of performance in OpenGL?

Posted by mhagain on 15 April 2016 - 10:08 AM

1. Yes, if you've got different VBO's per object, you'll have to make extra GL function calls to rebind VBO's inbetween rendering each object. Whether or not this is a problem depends on your game. If you're trying to draw 10's of thousands of unique objects, it's probably an issue. If you're trying to draw one thousand, not as much.
2. Basically, any GL function takes up CPU time. If you design your renderer so that you'll make the least GL calls, then you'll save CPU time. However, in order to do this, sometimes you have to do things that are inefficient for the GPU... Depending on your game, it may be more important to optimize for the CPU or optimize for the GPU.
3. As above, if your game has spare CPU time and is over budget on the GPU, then this could be a good idea. However, if the opposite is true (spare GPU time, over CPU budget), then it may be harmful :P
Also, if you calculate projection*view*model on the CPU, then you need to repeatedly set a uniform value for every single object in the scene. On the other hand, if you put projection*view in one UBO and model in (many) others, then you only need to set projection*view once per frame instead of once per object. If your scene is full of static objects (so model doesn't need to be set every frame), this could be a significant reduction in GL calls...

These are great examples because they also illustrate some other factors to be aware (and beware) of.


The main thing that jumps out here is performance vs code complexity vs flexibility.  The example of putting all objects into a single VBO is a great use case for this.  On the one hand you get to reduce VBO binds, but on the other hand your model loading code becomes more complex because you've now got to record offsets for each object (as well as handle the case where a VBO you allocate up-front may not be large enough).  Then you lose the flexibility to load and unload models on the fly.


Depending on your program any or all of these may be a deal-breaker.  So don't let the quest for the absolute theoretical highest performance overrule other goals.


The example of matrices is another great one, this time illustrating how an optimization in one place can lead to loss of performance in another.  That's often the case with optimizations: you're making a trade-off and hoping that you come out with a net positive.  In this case setting projection * view one-time-only certainly looks attractive, but you end up trading that off against having to make an extra matrix multiplication per-vertex.  That's one of the reasons why we always say "benchmark", because unless you have measurements you'll never know if the work you did to optimize one area didn't come at a greater cost elsewhere.

#5287000 Which per-frame operations are expensive in terms of performance in OpenGL?

Posted by mhagain on 15 April 2016 - 02:51 AM

This kind of thing is actually micro-optimizing with the kind of workload you're doing.


The worst operations for performance are and always will be: (1) reading anything back from the GPU, and (2) updating a resource that's in use.  Avoid those, and so long as the rest of your code isn't fighting the API you'll do OK.

#5286840 DX11 Update textures every frame

Posted by mhagain on 14 April 2016 - 04:45 AM

I've read this may be possible in OpenGL with some kind of PixelBufferObject?  Is there anything like this in DirectX?  I haven't tried reverting my code to UpdateSubResource for this case, but are there any other suggestions?

An OpenGL PBO is the equivalent of using two textures in D3D, either via CopyResource or CopySubresourceRegion.


To summarise, in OpenGL the workflow with a PBO is (1) map the PBO, (2) write data to it, (3) unmap the PBO and (4) update the texture via glTexImage2D/glTexSubImage2D.


The D3D equivalent is (1) map a staging resource, (2) write data to it, (3) unmap the staging resource, and (4) update the texture via CopyResource/CopySubresourceRegion.

#5286042 C++ best way to break out of nested for loops

Posted by mhagain on 09 April 2016 - 11:52 AM

A billion times this. Putting the extra condition in the loop is clean and easy to understand.

You can't break in the middle of a block though:


doSomething ();

if (condition) break;

doSomethingElse ();


Well you could, by introducing an else, but then you're starting to lose clarity.  On balance, return is absolutely unambiguous about what the programmer's intentions are and has the lowest associated risk if someone revisits the code in 6 months and tries to get too clever with it.

#5285998 C++ best way to break out of nested for loops

Posted by mhagain on 09 April 2016 - 06:11 AM

return always seems cleanest to me.

#5285549 Difference when enabling index buffer before and after GL_ARRAY_BUFFER

Posted by mhagain on 07 April 2016 - 01:17 AM

Yes, the current GL_ELEMENT_ARRAY_BUFFER binding is part of the VAO state, so if you change the VAO you'll change that binding, which is most likely what's happening here.

#5285007 In terms of engine technology, what ground is left to break?

Posted by mhagain on 04 April 2016 - 05:57 AM

Lighting and shadowing is still one of those areas where there's a huge amount of work to be done.


It may well seem as though we have all the problems solved, but we really don't.  When you scratch the surface just a little you find that our solutions are still a bunch of hacks, approximations, special-casing, etc.  A truly general solution that looks good and runs well under any arbitrary condition just doesn't exist.


Outside of visual, I think there's a lot of useful work to be done on latency, meaning not just network latency but also latency between player input and game response, rendering commands and response, etc.  That's a tree I'd like to see fall.

#5284163 Should I start with fixed-function-pipeline OpenGL or the newest possible?

Posted by mhagain on 29 March 2016 - 09:25 PM

I used to be of the opinion that learning the fixed pipeline first was the way to go on the grounds that there is a significant upfront investment required with modern GL that a beginner may just not be able to get past.  You have to know what a shader is, you have to know what a buffer is, you have to be able to successfully load and compile shaders, you have to plan out your vertex data ahead of time, if any of that vertex data is dynamic you have to plan out your buffer update strategy ahead of time, and you have to be aware of what the fast paths (which it's easier to fall off with modern GL) for this are.  With the fixed pipeline you can just make a few API calls and get something onscreen.  Make a few more and be interacting with it.  Instant gratification, instant feedback.


On the other hand, it's so easy to get into bad habits with the fixed pipeline, a lot of tutorials for it are really old and contain bad practices (the OpenGL wiki common mistakes page could have been - and probably was - written about the NeHe tutorials) and virtually none of what you learn will transfer forward to modern GL.


The "Learning Modern 3D Graphics Programming" tutorials used to be the default recommendation some time back; they've since fallen off the web but are still available at archive.org (which I've linked).  It'll guide you through getting something onscreen, moving it, lighting it and texturing it, and is (IIRC) pitched at about the OpenGL 3.3 level, which is a reasonable baseline.  I'm not sure of what other resources are available these days; no doubt others will pitch in.

#5283148 Looking for a *.dds texture loading library in C++ that isn't specific to...

Posted by mhagain on 24 March 2016 - 08:41 AM

DDS is such a simple format that i'm not even sure that it needs a library.  There's no parsing/etc involved, it's just a simple header followed by data which can be directly consumed by the API without conversion.