Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

AgentC

Member Since 16 May 2005
Online Last Active Today, 03:18 AM
-----

#5061573 Why do most tutorials on making an API-agnostic renderer suggest that it'...

Posted by AgentC on 13 May 2013 - 12:43 PM

1) So, in essence, you're making code harder to follow by splitting it up at a very fine level, adding runtime overhead by adding superfluous virtual function calls, etc. just so that you can be typing code into an IDE *right this instant*? That seems a *very* poor tradeoff. This seems to be the thought process behind a lot of tutorials, actually.

EDIT 3: This kind of thinking is also what gave us JavaScript, FWIW.

 

2) Maybe in theory. By your own admission, though, there are often fundamental differences in how the API works that render this 'abstraction' meaningless anyway-- you still need to add more of them at different levels, which will in turn make code harder to follow.

 

3) Isn't the point of a tutorial to demonstrate how to take the low-level API and map it to higher-level constructs *anyway*?

 

Note that I was not trying to advocate a low-level abstraction, but to explain why such approach might be chosen. Like you said, tutorials are many times written without sufficient insight. A *good* low-level abstraction (if one can exist) certainly takes careful planning, and it shouldn't involve virtual functions :)




#5061138 Why do most tutorials on making an API-agnostic renderer suggest that it'...

Posted by AgentC on 11 May 2013 - 02:20 PM

A few reasons I can think of:

 

1) it requires (at least superficially) the least amount of thinking / planning to just wrap the low-level API objects

2) by keeping the abstraction at low level you should, theoretically, be able to construct complex API-agnostic higher level rendering code, and not have to duplicate eg. the functionality of Mesh for different APIs

3) A tutorial stays more generally applicable if it doesn't impose its own higher-level constructs

 

It has potential to get messy, though. For an example here's a list, from my engine, of D3D / OpenGL differences that "leak" from the low level abstraction to the higher. It's not unmanageable, but not pretty either. https://code.google.com/p/urho3d/wiki/APIDifferences




#5059466 Is software rasterisation processor-heavy?

Posted by AgentC on 05 May 2013 - 08:02 AM

It depends on the occlusion buffer dimensions.

 

On a 2GHz Core i7, I take less than 1 millisecond to rasterize 2000 triangles of terrain geometry into a 256 pixel wide occlusion buffer. Increasing the resolution to 1024 pixels also increases the time taken to 2.5 ms. My routine is depth only rasterization, and is not optimized to the max, C++ code only and no SIMD instructions.

 

I've found it hard to thread the occlusion rendering though, as the way I use it is a sequential operation: find out visible occluders, rasterize them, then use the result to check object AABB's for visibility.

 




#5054974 Shadow map practices

Posted by AgentC on 19 April 2013 - 12:10 PM

If you want a huge amount of shadow casting lights without having to care of increasing video memory, you can reuse shadow maps, or have just one texture per each possible shadow map resolution. First clear the shadow map, render shadow casters, then switch rendertargets and render the light volume. Repeat for each shadow casting light. That's actually just as possible in forward rendering.




#5052850 Creating a reference object without modifying base class - Possible?

Posted by AgentC on 13 April 2013 - 11:37 AM

I know you said you don't want to modify your existing resource handling, but if you made your smart pointer mechanism intrusively reference-counted, ie. Texture would have its own AddRef() and RemoveRef() functions, then using a smart pointer and an AngelScript handle would be essentially equivalent, and there would be no need for the Reference class at all.




#5050995 Abstraction layer between Direct3D9 and OpenGL 2.1

Posted by AgentC on 07 April 2013 - 04:26 PM

To some degree, you can pick your "favorite API" and then make the others emulate it. Like mhagain warned, actually doing this may require going through some contortions, and even though your program works correctly, you may run into non-optimal performance, usually on the OpenGL side.

 

For example I picked D3D as my favorite and wanted to emulate the simple SetRenderTarget / SetDepthStencil API with OpenGL FBO's. The initial and simple solution was to create a single FBO and attach different color buffers and depth buffers according to the currently set targets. This worked correctly, but exposed performance loss (to add insult to injury, it was Linux-only, Windows drivers were fine.) The solution to avoid the performance loss was to create several FBO's sorted by the resolution and format of the first color buffer, and what was only a few lines of code in D3D became hundreds in OpenGL :)

 

Additionally, to be able to utilize D3D11 effectively in the future you probably need to make your abstract API resemble D3D11 with its state objects, constant buffers etc. and emulate those in the other APIs.




#5050972 Abstraction layer between Direct3D9 and OpenGL 2.1

Posted by AgentC on 07 April 2013 - 03:01 PM

You should be able to handle the exactly same binary vertex data in both Direct3D9 and OpenGL. When using shaders, and generic vertex attributes on the OpenGL side, for example vertex colors can be defined as 4 normalized unsigned bytes in both APIs.




#5050413 Suggestions for Keeping track of Lights and Entities in a scene. [Design Ques...

Posted by AgentC on 05 April 2013 - 02:45 PM

What I meant was to have both:

 

- The lights knowing the entities they light. This is what I'd consider the authoritative information (generated from scene queries), and it can persist from frame-to-frame if nothing moves.

- The entities' light lists can be created from the lights' entity lists. This is derived information, it's simplest to regenerate each frame, should not be a big hit. It's also where you'd cap the maximum lights if for example you want some particular object to only have 2 lights maximum.

 

Yes, for shadow rendering you certainly need to know the entities within a light's view in any case.




#5050271 Making an optimized 3d mmo in open gl c++

Posted by AgentC on 05 April 2013 - 06:22 AM

I have seen good OpenGL performance and compatibility in the newest Intel integrated GPUs, like HD Graphics 3000 and co. These will eg. be able to do deferred rendering without problems and with reasonable performance. Anything older than that (for example GMA 3000/4000, not HD) will be problematic and works much better with D3D. Note I'm only talking of Windows drivers here, have not tested Intel cards on Linux or Mac.

 

To scale performance consists of many things, in addition to texture resolution you can eg.

- reduce complexity of shading equations

- leave out "decoration" objects on low-end systems, as well as particle effects

- have object LODs with fewer triangles

- disable dynamic shadows, or render them with lower resolution

- disable or scale down post processing effects

 

Basically, everything you usually see in games' graphics settings menus.




#5046003 Direct3D 11 Deferred Shading Banding

Posted by AgentC on 23 March 2013 - 11:53 AM

Analyzing the picture in an image editor shows the 8-bit color value decreasing by one at each band, so you simply don't get more color resolution from a 8-bit backbuffer. The result would be the same with forward rendering.




#5041820 Whats the shader data a Material class holds?

Posted by AgentC on 11 March 2013 - 06:47 AM

You can consider shadow map a whole independent scene view to be rendered (different camera, different rendertarget, different culling) so to me it seems most logical that it would also have its own dedicated renderqueue. There would be higher-level logic in the renderer which renders the shadow map renderqueues first.

 

But yes, generally multipass materials would get broken down into independent drawcalls just like you describe.




#5041578 Whats the shader data a Material class holds?

Posted by AgentC on 10 March 2013 - 01:03 PM

Cannot comment on the cbuffer slot issue, but I'd recommend that the material holds a reference to a "base" shader, from which permutations can be built/requested, and the rendering system chooses, during runtime, the actual shader permutation based on the object's lighting environment.

 




#5041179 What's everyone doing with Angelscript!

Posted by AgentC on 09 March 2013 - 09:39 AM

AngelScript is the scripting language of choice in my 3D game/rendering engine Urho3D http://urho3d.googlecode.com , where most of the C++ objects and functions are exposed to script, except low-level access like direct modification of vertex buffer or texture data.

 

The performance, especially in recent AngelScript versions, is very impressive. In an Urho3D example game I had an unintended O(n^2) algorithm going on in script without noticing it at first. Basically, each AI enemy was scanning the whole scene for new targets each physics/logic frame (at 100fps), which is of course stupid. But that still worked for up to 50 enemies. After changing it to cache the last found target it can run a lot more enemies smile.png

 




#5015474 asSFuncPtr executable size optimization

Posted by AgentC on 29 December 2012 - 11:18 AM

For my personal use (Urho3D engine) I've done some modifications to AngelScript, some of which are dubious, but here's something that shouldn't be much destructive to performance, but reduce the executable size, possibly even by a hundred KB or so, if there's a lot of classes & functions being registered.

 

It has to do with the template functions for initializing asSFuncPtr's. While the original template code memclear's the function pointer object (which is possibly also inlined), and then sets the flag member variable according to whether it's a function or method

 

 

// Specialization for functions using the generic calling convention
template<>
inline asSFuncPtr asFunctionPtr<asGENFUNC_t>(asGENFUNC_t func)
{
    asSFuncPtr p;
    asMemClear(&p, sizeof(p));
    p.ptr.f.func = reinterpret_cast<asFUNCTION_t>(func);

    // Mark this as a generic function
    p.flag = 1;

    return p;
}

 

 

I've created a non-inline constructor for asSFuncPtr, which does the memclear and sets the flag

 

 

asSFuncPtr::asSFuncPtr(asBYTE f)
{
    asMemClear(this, sizeof(asSFuncPtr));
    flag = f;
}

 

 

By using that, the template functions become shortened and should consume less memory:

 

 

// Specialization for functions using the generic calling convention
template<>
inline asSFuncPtr asFunctionPtr<asGENFUNC_t>(asGENFUNC_t func)
{
    asSFuncPtr p(1);
    p.ptr.f.func = reinterpret_cast<asFUNCTION_t>(func);

    return p;
}

 




#4980680 Game Engine Architecture, Separation of Application, Game Logic,& GameVie...

Posted by AgentC on 16 September 2012 - 12:24 PM

I'd say, simply use direct function calls instead of events whenever it leads to a cleaner design; define interfaces (for things like Controllable, Damageable) or use a component system so that the various aspects of the game objects stay both manageable, and directly accessible. Be less afraid of some coupling, and more afraid of possibly totally unspecified control flow :)

At my workplace I've participated in two major Unity projects; in the first Unity's SendMessage facility (which allows arbitrary receiving objects to execute a named function) was extensively used, with the idea that it would be easy to add more responses to internal events when need arises, while keeping coupling low. It quickly became a mess. In the later, SendMessage is practically forbidden, function calls are favored, but C# delegates are also judiciously used. As a result, the execution flow is much better defined.




PARTNERS