Jump to content

  • Log In with Google      Sign In   
  • Create Account

InvalidPointer

Member Since 04 Apr 2007
Offline Last Active Yesterday, 08:42 AM

#5045313 Interesting effects for particle physics...

Posted by InvalidPointer on 21 March 2013 - 11:26 AM

While touched upon in the C&C presentation, Halo: Reach also has probably one of the coolest little collision tricks I've seen-- basically treat the depth buffer as a heightfield and collide against that. Details are in the presentation located at the GDC Vault and a short summary is here.




#5001563 VS 2010 is generating .lib and .exp files for a normal project, why?

Posted by InvalidPointer on 16 November 2012 - 09:54 AM

I would imagine Boost does some stuff, and it's also very likely the Microsoft CRT does some futzing too, especially if you use the run-time-linked libraries.


With that said this will have very, very negiligible impact on final compile time and you're making a mountain out of a molehill. Sometimes things need to be exported for stuff to Just Work and VIsual Studio is mature enough that basic kinks like this would have been worked out. :)


#4994017 Animated title screen?

Posted by InvalidPointer on 25 October 2012 - 09:06 PM

Nope, it's clearly not possible to accomplish. OoT/Aiydn broke reality :)

You'll need to elaborate what you mean by 'in 2D' though. If you're looking to display a sort of 'demo' run-through of a special level, that's not too hard to do; you're basically just slapping an overlay over you regular rendering pipeline. You could have an AI-controlled player character in such case, or record yourself playing something and then have the game play that back somehow-- this depends on what your technology lets you do (and the latter is rather helpful for automated testing/benchmarks, if you're into that sort of thing) and the specific effect you're looking to accomplish.


#4990718 Destructor vs Cleanup()

Posted by InvalidPointer on 16 October 2012 - 08:04 AM

yes, from C# object gets anownced that it would like to be freed (By OS manager GC). You then perform alll logic to free resources the object posesss. Like sicrane said, study cli/c++

in c++ destrocturos are not necesary, nor any good logic, from C#, managememet of memory yes

You can still design your logic to not need destructors, but your logic must be freed and managed well


I really, really hope you don't use C++ exceptions.


Why shouldn't one use exceptions in C++?


They can carry some very subtle, complicated costs and require some extra thinking when designing algorithms and classes. For games I don't really think they're worth said cost; in most cases using error codes can work equally well and can 're-enable' more dangerous (but speedier) class architectures. The latter is why I bring things up-- the C++ spec says the compiler will walk up the call stack, invoking destructors on everything until it finds an appropriate catch block. If you don't release any resources in the destructor, congratulations! You've just created a pretty massive, totally unfixable memory leak.

EDIT: That also means that using raw allocations on the stack, anywhere, is unsafe. Consider the implications. Overloading operator new can help you in limited cases, come to think of it. If you don't, though, you're in trouble.


#4990618 Destructor vs Cleanup()

Posted by InvalidPointer on 15 October 2012 - 10:41 PM

yes, from C# object gets anownced that it would like to be freed (By OS manager GC). You then perform alll logic to free resources the object posesss. Like sicrane said, study cli/c++

in c++ destrocturos are not necesary, nor any good logic, from C#, managememet of memory yes

You can still design your logic to not need destructors, but your logic must be freed and managed well


I really, really hope you don't use C++ exceptions.


#4987320 vector subscript out of bounds

Posted by InvalidPointer on 05 October 2012 - 09:46 PM

For starters you never appear to set the (extremely poorly named-- what does it do/control?) member variable 'i' to anything, so it's going to be 0xCDCDCDCD on MSVC/heap memory debugging enabled and random garbage in release mode. That's pretty big in decimal, and is very likely to be out of range when you do
void MD5Class::RenderBuffers(ID3D11DeviceContext* deviceContext)
{
    // Set vertex buffer stride and offset.
    stride = sizeof(VertexType);
    offset = 0;
	
    // Set the vertex buffer to active in the input assembler so it can be rendered.
    deviceContext->IASetVertexBuffers(0, 1, &MD5Model.subsets[i].vertBuff, &stride, &offset);
    // Set the index buffer to active in the input assembler so it can be rendered.
    deviceContext->IASetIndexBuffer(MD5Model.subsets[i].indexBuff, DXGI_FORMAT_R32_UINT, 0);

    // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
    deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    deviceContext->DrawIndexed(MD5Model.subsets[i].indices.size(), 0, 0);

    return;
}

EDIT: I also apologize if this comes off as snarky, but I'm not sure why you jumped to index buffer creation as being problem when the debugger explicitly tells you that you're feeding a vector an index larger than what it has room for. Slow down a bit and take the time to learn the debugger, as it's designed to make this process really straightforward. You need to walk before you can run.


#4985907 Graphics programming book recommendations

Posted by InvalidPointer on 01 October 2012 - 05:08 PM

Chiming in to recommend Real-Time Rendering. If you're into photorealistic rendering, then Physically-Based Rendering from Theory to Implementation is also a really good book-- although it's very much centered on offline rendering.

If you're just getting started, Game Engine Architecture is a good read and the chapter on animation alone is probably worth the price of the book; it was written by one of the programmers at Naughty Dog/Uncharted and has a lot of simple yet effective ideas and some practical advice.


#4980946 Delegates in AngelScript

Posted by InvalidPointer on 17 September 2012 - 11:04 AM

Currently thinking about how delegates should work, as I find myself becoming really, really hamstrung without their inclusion in AngelScript. While I think I have some of the implementation worked out, I'm curious what people would want in an implementation and what the syntax should be. From a technical perspective, I think it's best approached at a single-subscriber level, with a delegate storing a function to call and an additional 'this' pointer; multicast delegates/events could be either a library add-on extending the built-in array type or something left to the application interface to provide.

What I'm not sure of, however, is how this should interact with garbage collection (as I understand it, this bites people in the ass with startling frequency in C#, do we need to have a language-level 'weak reference' construct too?) and cross-module function imports. Community, fire away.


#4969077 How do you multithread in Directx 11?

Posted by InvalidPointer on 13 August 2012 - 08:24 AM

It takes 7 miliseconds to render a large building with 10 large directional lights and about 11 miliseconds for 60 large directional lights.I'm not very happy about the performance right now and I'm gonna optimize some more and implement instancing,but from what I understood modern engines like Frostbite 2 have both instancing and multi-threaded rendering.The thing is I have no idea how to implement multithreading,what changes do I have to make to my device and context creation?Currently I'm just using D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &DEVICE, NULL, &CONTEXT));

You aren't listening to what Hodgman is saying here. Do you know how much of that time is spent queuing up draw calls on the CPU? What he's getting at is that you may actually be GPU limited-- that is, your CPU is mostly farting around waiting for the GPU to do the work assigned to it. You'd ultimately end up making the CPU fart around even more for no actual performance gain and in fact stand to make it worse if you handle threading poorly-- many professionals still can't get this right, although that's probably more the result of mediocre teaching than any inherent difficulty.

For what it's worth, though, this and this (and even more specifically, these two methods) should help get you started.


#4967965 Template methods

Posted by InvalidPointer on 09 August 2012 - 09:21 PM

I've actually exposed asIObjectType this way to scripts and it works fairly well. The only thing I dislike is that you're (Jake) not writing idiomatic code, but with that said it's insanely flexible and can be implemented wholly with pre-implemented features.

EDIT(2): My implementation. It's not going to be a perfect cut-and-paste job, but this should get the ball rolling.
/*==================================================================*\
  AngelscriptReflection.cpp
  ------------------------------------------------------------------
  Purpose:

  ------------------------------------------------------------------
  ©2010-2012 Eldritch Entertainment, LLC.
\*==================================================================*/

//==================================================================//
// INCLUDES
//==================================================================//
#include <Scripting/Angelscript/AngelscriptReflection.hpp>
#include <Scripting/Angelscript/AngelscriptContextExtraData.hpp>
#include <Scripting/Angelscript/AngelscriptCommon.hpp>
#include <Util/Containers/UTF8String.hpp>
#include <Util/Assert.hpp>
#include <angelscript.h>
//------------------------------------------------------------------//
//==================================================================//
// LIBRARIES
//==================================================================//
ET_LINK_LIBRARY( "angelscript.lib" )
//------------------------------------------------------------------//
using namespace ::Eldritch2;
using namespace ::Eldritch2::Scripting;
using namespace ::Eldritch2::Util;
#define TYPE  "Type"
#define FUNCTION "Function"
#define MEMBER  "Member"
#define ATTRIBUTE "Attribute"
namespace
{
static const char typeName[]  = TYPE;
static const char functionName[] = FUNCTION;
static const char memberName[] = MEMBER;
static const char attributeName[] = ATTRIBUTE;
// ---------------------------------------------------
static UTF8String TypeGetNameProperty( asIObjectType* const thisPtr )
{
  AngelscriptContextExtraData* const contextExtraData = static_cast<AngelscriptContextExtraData*>( asGetActiveContext()->GetUserData() );
  return UTF8String( thisPtr->GetName(), contextExtraData->allocator );
}
// ---------------------------------------------------
static UTF8String TypeGetNamespaceProperty( asIObjectType* const thisPtr )
{
  AngelscriptContextExtraData* const contextExtraData = static_cast<AngelscriptContextExtraData*>( asGetActiveContext()->GetUserData() );
  return UTF8String( thisPtr->GetNamespace(), contextExtraData->allocator );
}
// ---------------------------------------------------
static ETNoAliasHint asIObjectType* TypeGetBaseTypeProperty( asIObjectType* const thisPtr )
{
  asIObjectType* const basePtr = thisPtr->GetBaseType();
  if( ETBranchLikelyHint( nullptr != basePtr ) )
  {
   basePtr->AddRef();
  }
  return basePtr;
}
// ---------------------------------------------------
static ETNoAliasHint asIObjectType* TypeGetSubtypeProperty( asIObjectType* const thisPtr )
{
  asIObjectType* const basePtr = thisPtr->GetSubType();
  if( ETBranchLikelyHint( nullptr != basePtr ) )
  {
   basePtr->AddRef();
  }
  return basePtr;
}
// ---------------------------------------------------
static ETNoAliasHint bool ETCDecl TypeIsInterface( asIObjectType* const thisPtr )
{
  return ( ( 0u == thisPtr->GetSize() ) & !!( asOBJ_SCRIPT_OBJECT & thisPtr->GetFlags() ) );
}
// ---------------------------------------------------
static ETNoAliasHint bool ETCDecl TypeIsFinal( asIObjectType* const thisPtr )
{
  return !!( asOBJ_NOINHERIT & thisPtr->GetFlags() );
}
// ---------------------------------------------------
static ETNoAliasHint asIScriptFunction* ETCDecl TypeGetMethodProperty( asIObjectType* const thisPtr, uint32 methodIndex )
{
  asIScriptFunction* const function = thisPtr->GetMethodByIndex( methodIndex );
  if( ETBranchLikelyHint( nullptr != function ) )
  {
   function->AddRef();
  }
  return function;
}
// ---------------------------------------------------
static ETNoAliasHint asIObjectType* ETCDecl TypeOf( void* const object, int typeID )
{
  ETUnreferencedParameter( object );
  if( asIObjectType* const result = asGetActiveContext()->GetEngine()->GetObjectTypeById( typeID ) )
  {
   result->AddRef();
   return result;
  }
  return nullptr;
}
// ---------------------------------------------------
static asIObjectType* ETCDecl GetTypeByName( const UTF8String& name )
{
  asIScriptEngine* const scriptEngine = asGetActiveContext()->GetEngine();
  AngelscriptNamespace typeNamespace;
  AngelscriptClassName typeName;
  if( ExtractClassPath( typeNamespace, typeName, name ) )
  {
   if( asIScriptModule* const scriptModule = scriptEngine->GetModule( typeNamespace ) )
   {
	asIObjectType* const objectType = scriptEngine->GetObjectTypeById( scriptModule->GetTypeIdByDecl( typeName ) );
	if( objectType )
	{
	 objectType->AddRef();
	 return objectType;
	}
   }
  }
  return nullptr;
}
// ---------------------------------------------------
static asIObjectType* ETCDecl GetTypeByName( const UTF8String& name, const UTF8String& package )
{
  asIScriptEngine* const scriptEngine = asGetActiveContext()->GetEngine();
  AngelscriptNamespace typeNamespace;
  AngelscriptClassName typeName;
  StrCpy( typeName, name );
  StrCpy( typeNamespace, package );
  if( asIScriptModule* const scriptModule = scriptEngine->GetModule( typeNamespace ) )
  {
   if( asIObjectType* const objectType = scriptEngine->GetObjectTypeById( scriptModule->GetTypeIdByDecl( typeName ) ) )
   {
	objectType->AddRef();
	return objectType;
   }
  }
  return nullptr;
}
} // anonymous namespace
namespace Eldritch2
{
namespace Scripting
{
  void RegisterReflection( asIScriptEngine* const engine )
  {
   ETRuntimeVerification( 0 <= engine->RegisterObjectType( typeName, 0u, asOBJ_REF ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectType( functionName, 0u, asOBJ_REF ) );
   // ETRuntimeVerification( 0 <= engine->RegisterObjectType( memberName, 0u, asOBJ_REF ) );
   ETRuntimeVerification( 0 <= engine->RegisterInterface( attributeName ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectBehaviour( typeName, asBEHAVE_ADDREF, "void f()",
				   asMETHOD( asIObjectType, AddRef ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectBehaviour( typeName, asBEHAVE_RELEASE, "void f()",
				   asMETHOD( asIObjectType, Release ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectBehaviour( functionName, asBEHAVE_ADDREF, "void f()",
				   asMETHOD( asIScriptFunction, AddRef ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectBehaviour( functionName, asBEHAVE_RELEASE, "void f()",
				   asMETHOD( asIScriptFunction, Release ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, TYPE "@ get_BaseType() const",
				   asFUNCTIONPR( TypeGetBaseTypeProperty, ( asIObjectType* const ), asIObjectType* ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, TYPE "@ get_Subtype() const",
				   asFUNCTIONPR( TypeGetSubtypeProperty, ( asIObjectType* const ), asIObjectType* ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "string get_Name() const",
				   asFUNCTIONPR( TypeGetNameProperty, ( asIObjectType* const ), UTF8String ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "string get_Namespace() const",
				   asFUNCTIONPR( TypeGetNamespaceProperty, ( asIObjectType* const ), UTF8String ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "bool get_IsInterface() const",
				   asFUNCTIONPR( TypeIsInterface, ( asIObjectType* const ), bool ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "bool get_IsFinal() const",
				   asFUNCTIONPR( TypeIsFinal, ( asIObjectType* const ), bool ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "bool DerivesFrom( const " TYPE "@ ) const",
				   asMETHODPR( asIObjectType, DerivesFrom, ( const asIObjectType* ) const, bool ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "bool Implements( const " TYPE "@ ) const",
				   asMETHODPR( asIObjectType, Implements, ( const asIObjectType* ) const, bool ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, "uint32 get_MethodCount() const",
				   asMETHODPR( asIObjectType, GetMethodCount, () const, asUINT ), asCALL_THISCALL ) );
   ETRuntimeVerification( 0 <= engine->RegisterObjectMethod( typeName, FUNCTION "@ get_Method( uint32 ) const",
				   asFUNCTIONPR( TypeGetMethodProperty, ( asIObjectType* const, uint32 ), asIScriptFunction* ), asCALL_CDECL_OBJFIRST ) );
   ETRuntimeVerification( 0 <= engine->RegisterGlobalFunction( TYPE "@ TypeOf( ?&in )",
				   asFUNCTIONPR( TypeOf, ( void* const, int ), asIObjectType* ), asCALL_CDECL ) );
   ETRuntimeVerification( 0 <= engine->RegisterGlobalFunction( TYPE "@ GetTypeByName( const string&in )",
				   asFUNCTIONPR( GetTypeByName, ( const UTF8String& ), asIObjectType* ), asCALL_CDECL ) );
   ETRuntimeVerification( 0 <= engine->RegisterGlobalFunction( TYPE "@ GetTypeByName( const string&in, const string&in )",
				   asFUNCTIONPR( GetTypeByName, ( const UTF8String&, const UTF8String& ), asIObjectType* ), asCALL_CDECL ) );
  }
} // namespace Scripting
} // namespace Eldritch2

EDIT 3: One thing I really, really would like to look into is attributes Like What C# Has™, on a totally unrelated note. I can think of a way to hack it together again using stock functionality, but on the subject of reflection it's really a powerful concept.


#4967341 How do I maintain a good quality real time rendering without textures?

Posted by InvalidPointer on 08 August 2012 - 04:56 AM

I have discarded the textures because our artist refuses to share his.

Sounds like it's time to get a new artist? Seriously, that's their job.


#4966361 Deferred shading ugly Phong

Posted by InvalidPointer on 05 August 2012 - 08:13 AM

Yeah, reason #3289472 why OpenGL is a design trainwreck. Remember kiddos, adding a clamp instruction is fine, but adding a special-case, higher-performance one that can be implemented in terms of the former somehow breaks hardware compatibility(???)

Good job, Khronos. You make us all so very, very proud.


#4966237 Deferred shading ugly Phong

Posted by InvalidPointer on 04 August 2012 - 08:40 PM

Phong was intentional, since it's more accurate (I am aware it's slower).


Actually Blinn-Phong produces more accurate results (try both at glancing angles and you'll see how bad Phong looks!), to even better results try Enery conserving Blinn-Phong.

QFE. The tl;dr version is that Blinn-Phong is actually an approximation to evaluating a Gaussian centered on the halfway vector.

In more plain English, you're using some statistics hacks to guess what fraction of the total surface of the area to be shaded is angled in such a way to bounce light towards you/give you laser eye surgery if it starts out coming from the light in question.

EDIT: And for extra credit, use Toksvig filtering to account for actual texture detail in the normal map!

EDIT 2: Also
float NdL = max(0.0f, dot(Normal, LightVector));
makes me really, really angry. You wouldn't like me when I'm angry. Do
float NdL = saturate(dot(Normal, LightVector));
instead to avoid my wrath.

For clarification, you're wasting precious GPU time with those max() operations that you could be getting for free with a saturate modifier. You might think that the compiler can optimize this. You'd be wrong, though-- remember that the dot product itself does not have a defined range and that the compiler generally lacks sufficient context to know that you're dotting normalized vectors.


#4963095 Register functions with default value parameters

Posted by InvalidPointer on 25 July 2012 - 04:47 PM

Default parameters are entirely a compiler thing-- they're just instructions to the compiler to add some behind-the-scenes code if you don't manually specify arguments when the function is called. Due to how Angelscript works, you can't take advantage of this since it doesn't call functions the 'normal' way. You'll need to actually add the default arguments to the AS declaration instead of just assuming the compiler will handle it.

EDIT: For clarity, I refer specifically to the "void begin(const string &in, int renderop, const string &in)" bit.


#4951906 Bloom before tonemapping

Posted by InvalidPointer on 22 June 2012 - 09:02 PM

They tell you right in the image title, you use the 'screen' blend mode instead of a direct addition. Much, much simpler ;)




PARTNERS