Jump to content

  • Log In with Google      Sign In   
  • Create Account

aeroz

Member Since 06 Apr 2008
Offline Last Active Apr 02 2013 08:20 PM

Topics I've Started

Blur shader (2 passes)

01 December 2012 - 09:23 PM

I'm learning how to use GLSL shaders at the moment. I'm implementing a Gaussian blur shader which uses 2 passes, one for horizontal and one for vertical blur.
My question is, do I need to create a texture target for each pass? This way I would render the scene to the first texture, then I would render the first texture to the second texture using the horizontal blur shader, and finally render the second texture to the screen using the vertical shader. I'm not sure if this is the right way.
The second possibility I have is to render the scene to the same texture two times once with each shader (and add a * 0.5 to the end of each shader). But with this solution, all the scene geometry has to be drawn twice (and not just 2D textures).

Is the double texture approach better? Is there another one?
Thank you!

Visual Studio namespace problem? (ambiguous call to boost::make_shared)

28 January 2012 - 10:44 AM

Hi! I'm having a strange problem that I hope you guys can help me understand.
I'm using Visual Studio 2010 SP1. The code compiles fine with the g++ compiler.
I tried to reproduce the problem with minimum code, but I was not yet able to get the error.

Here's my code:

SomeClass::SomeMethod()
{
  using boost::make_shared;

  // this does work:
  make_shared<WidgetButton>( Rect(1,2,3,4), "hoi", boost::bind( &MainMenuState::onPressedButBack, this ), boost::bind( &MainMenuState::onPressedSound, this ) );

  // this does not work: (produces the error below)
  make_shared<WidgetButton>( Rect(1,2,3,4), "hoi", boost::bind( &MainMenuState::onPressedOpenLevel, this, "hoi" ), boost::bind( &MainMenuState::onPressedSound, this ) );

  // this does work:
  boost::make_shared<WidgetButton>( Rect(1,2,3,4), "hoi", boost::bind( &MainMenuState::onPressedOpenLevel, this, "hoi" ), boost::bind( &MainMenuState::onPressedSound, this ) );
}

VS gives me this:

1>..\src\game\states\MainMenuState.cpp(125): error C2668: 'boost::make_shared' : ambiguous call to overloaded function
1>		  C:\Libraries\boost_1_47\boost/smart_ptr/make_shared.hpp(330): could be 'boost::shared_ptr<T> boost::make_shared<WidgetButton,Rect,const char(&)[4],boost::_bi::bind_t<R,F,L>,boost::_bi::bind_t<R,boost::_mfi::mf0<R,MainMenuState>,boost::_bi::list1<A1>>>(Rect &&,A2,A3 &&,A4 &&)'
1>		  with
1>		  [
1>			  T=WidgetButton,
1>			  R=void,
1>			  F=boost::_mfi::mf1<void,MainMenuState,const std::string &>,
1>			  L=boost::_bi::list2<boost::_bi::value<MainMenuState *>,boost::_bi::value<const char *>>,
1>			  A1=boost::_bi::value<MainMenuState *>,
1>			  A2=const char (&)[4],
1>			  A3=boost::_bi::bind_t<void,boost::_mfi::mf1<void,MainMenuState,const std::string &>,boost::_bi::list2<boost::_bi::value<MainMenuState *>,boost::_bi::value<const char *>>>,
1>			  A4=boost::_bi::bind_t<void,boost::_mfi::mf0<void,MainMenuState>,boost::_bi::list1<boost::_bi::value<MainMenuState *>>>
1>		  ]
1>		  C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxshared(33): or	   'std::tr1::shared_ptr<_Ty> std::tr1::make_shared<WidgetButton,Rect,const char(&)[4],boost::_bi::bind_t<R,F,L>,boost::_bi::bind_t<R,boost::_mfi::mf0<R,T>,boost::_bi::list1<A1>>>(_Arg0 &&,_Arg1,_Arg2 &&,_Arg3 &&)' [found using argument-dependent lookup]
1>		  with
1>		  [
1>			  _Ty=WidgetButton,
1>			  R=void,
1>			  F=boost::_mfi::mf1<void,MainMenuState,const std::string &>,
1>			  L=boost::_bi::list2<boost::_bi::value<MainMenuState *>,boost::_bi::value<const char *>>,
1>			  T=MainMenuState,
1>			  A1=boost::_bi::value<MainMenuState *>,
1>			  _Arg0=Rect,
1>			  _Arg1=const char (&)[4],
1>			  _Arg2=boost::_bi::bind_t<void,boost::_mfi::mf1<void,MainMenuState,const std::string &>,boost::_bi::list2<boost::_bi::value<MainMenuState *>,boost::_bi::value<const char *>>>,
1>			  _Arg3=boost::_bi::bind_t<void,boost::_mfi::mf0<void,MainMenuState>,boost::_bi::list1<boost::_bi::value<MainMenuState *>>>
1>		  ]
1>		  while trying to match the argument list '(Rect, const char [4], boost::_bi::bind_t<R,F,L>, boost::_bi::bind_t<R,F,L>)'
1>		  with
1>		  [
1>			  R=void,
1>			  F=boost::_mfi::mf1<void,MainMenuState,const std::string &>,
1>			  L=boost::_bi::list2<boost::_bi::value<MainMenuState *>,boost::_bi::value<const char *>>
1>		  ]
1>		  and
1>		  [
1>			  R=void,
1>			  F=boost::_mfi::mf0<void,MainMenuState>,
1>			  L=boost::_bi::list1<boost::_bi::value<MainMenuState *>>
1>		  ]

EDIT: the declaration of WidgetButton's constructor might be helpful for you:
WidgetButton( Rect area, const std::string& caption, boost::function0<void> clickedCallbackFunc, boost::function0<void> mouseOverCallbackFunc );

Nowhere I have "using namespace std;", so for me its weird that it tries to use "std::tr1::make_shared" and not "boost::make_shared".
The other weird thing is that when slightly modify the 3rd argument to the WidgetButton constructor (see code), it works...

As you can see I could just remove the using declaration and prepend boost:: to the make_shared call, but I want to understand why its not working.

Looking forward to your replies!

Is it worth hiding the implementation details of a class in C++?

24 February 2011 - 10:13 AM

Hello

I'm having trouble deciding if it is worth to hide implementation details of a class (and reducing compile time dependencies) for the cost of making the code more complex.
Currently my code looks like this:

Class.h
#include <boost/scoped_ptr.hpp>
class coolLib_Type;
class AnotherClass;

class Class
{
public:
	Class();
	~Class();
	// ...
private:
	void privateMethod();
	boost::scoped_ptr<AnotherClass> m_pFoo;
	boost::scoped_ptr<coolLib_Type> m_pBar;
};

Class.cpp
#include <CoolLibrary.h>
#include "AnotherClass.h"
 
 Class::Class() :
 m_pFoo (new AnotherClass),
 m_pBar (new coolLib_Type)
{}

Class::~Class() {} // needs to be here because of scoped_ptr

void Class::privateMethod() {
	// bla bla
}

As you can see, it does already reduce compiling dependencies.
I'm trying to simplify the code and get rid of these smart pointers (they should be normal objects on the stack, in my opinion).
At the same time it would be nice to keep the dependencies as low as possible.

Maybe I go back to no hiding at all, because it's so much simpler.

Class.h
#include <CoolLibrary.h>
#include "AnotherClass.h"

class Class
{
public:
	// ...
private:
	void privateMethod();
	AnotherClass m_foo;
	coolLib_Type m_bar;
};

But in this way, when I use the class in another file, the library and the other class get included automatically, even if I don't use it.

I guess the only solution is to use an interface class or pimpl.
I like the interface class method (described in this article) but with it you cannot create an instance of the base class (need to call factory method that gives you a pointer).
I don't like the pimpl idiom very much because you have to write boilerplate code...

My question is, how do you solve this problem in your projects, and, do you use one of these two methods?

Thanks in advance

Base factory method with automatic registration

16 February 2011 - 09:27 AM

I'm trying to create a factory method for a base class which instantiates a derived class corresponding to the method's parameters.
So I can do:
Base* b = Base::create("DerivedClass");
I read this interesting post on Stackoverflow http://stackoverflow...c/534396#534396 (by epatel) but noticed he uses a factory singleton (Factory::instance()->registerCreator()).
Instead of a singleton I used a static varible. Here is my solution:

(C++)
#include <iostream>
#include <string>
#include <map>
using namespace std;

class Base
{
public:
  	typedef Base* (*CreateFun)();

	static Base* create(string name)
	{
   	   	FunctionMap::iterator it = creators.find(name);
        	if (it == creators.end())
           	return NULL;
        	return (it->second)();
	}
	static bool reg(string name, CreateFun fun)
	{
 	      creators[name] = fun;
 	      return true;
	}
	virtual ~Base() {}

private:
	typedef map<string, CreateFun> FunctionMap;
 	static FunctionMap creators;
};

Base::FunctionMap Base::creators;

// this registers a derived class in the factory method of the base class
// it adds a factory function named create_NAME()
// and calls Base::reg() by the help of a dummy static variable to register the function
#define REGISTER( _name ) \
namespace { \
Base* create_ ## _name() {  return new _name; } \
static bool _name ## _creator_registered = Base::reg(# _name, create_ ## _name); }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class DerivA: public Base
{
public:
 	DerivA()
	{
     	cout << "DerivA was created" << endl;
	}
};

REGISTER(DerivA)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class DerivB: public Base
{
public:
 	DerivB()
  {
 	cout << "DerivB was created" << endl;
  }
};

REGISTER(DerivB)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main()
{
   Base* b = Base::create("DerivA");
   b = Base::create("DerivB");
   return 0;
}
When you create a new derived class, all you need to do is to use the REGISTER() macro.
Note I don't have a separate factory class. I use the base class for this.
Note also that this code should be slightly modified if split into multiple files (multiple compilation units: no guarantee on the order of initialization of static variables).
Actually I want to use this as a component factory, so I can do something like

GameObject obj;
for each XML component node {
   Component* comp = Component::createFromXml(node).
   obj.addComponent( comp );
}
What do you think of this solution?

EDIT: having problems with identation

Mix_CloseAudio() from SDL_mixer takes too long

09 February 2011 - 01:59 PM

Hello! I hope somebody can help me with this problem with SDL_mixer:

The statement "Mix_CloseAudio();" takes too long to run and I don't know why. Here is the full code:

#include <SDL/SDL_mixer.h>
#include <sys/time.h>

int main(){
  // init
  Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
  
  // loand and play a sound
  Mix_Chunk *sample = Mix_LoadWAV( "sound.wav" );
  Mix_PlayChannel(-1, sample, 0);
  while (Mix_Playing( -1 ))
  	usleep(100000); // wait till the sound is finished
  Mix_FreeChunk( sample );
  
  -- start timer
  Mix_CloseAudio();
  -- stop timer

  return 0;
}

The call to Mix_CloseAudio() takes 2.1 seconds to complete. This is definitely too slow!

I tried to search on the Internet, but found nothing...

Thank you!

PARTNERS