Jump to content

  • Log In with Google      Sign In   
  • Create Account

Juliean

Member Since 29 Jun 2010
Online Last Active Today, 10:25 AM

Topics I've Started

Transparent backbuffer

09 October 2014 - 08:56 AM

Hello,

 

I'm trying to get a transparent backbuffer, for integrating my DX-rendered gui better with the rest of the OS. I've got a few questions/issues with that though:

 

- I've found out that I'm supposed to use DwmExtendFrameIntoClientArea for that. It also kind of works, though I get some sort of strange alpha/z-ordering issues, as you can see in Issue.png. Here is the code I'm using the create the window (plain old windows w/o any libary): (see edit below)

 

- Even though I can now see whats underneath the empty areas of my GUI... I still can't click/do anything else there, since the empty backbuffer is still overlapping the whole screen. Is there any way of "deactivating" certain areas of my backbuffer/invisible window, so that my application behaves like it was rendered using normal windows? Note that I can't just move the backbuffer as the main window you see moves, because there might be popup-windows of all sorts, which can go over the area of the main window... so any method for willingly deactivate area of a window?

 

EDIT: Ok, I was too fast in blaming the windows-part for this. Apparently the issue is with my rendering, because its those areas with the weird issues, where I render an alpha-blended texture over a solid texture. That happens for all my texts, and also for the icon in the upper left. Now I can get rid of this effect for most parts, by using alpha testing via clip (when alpha in the texture is 0), but what am I supposed to do when I have semi-transparent values, like the edges of the icon in the upper left? I can't just disable alpha-writing all together, since after clearing everything in the backbuffer is 0 (transparent). But I need to somehow only write alpha when the value is greater then what is currently in the buffer.

 

I'm rendering my gui with painters-algorithm and batched, so everything that is on top gets drawn last, in one go. Is there any way to achieve this kind of alpha-effect to fix my issue? So what I want summed up is:

 

- Every pixel with alpha > 0 should get drawn.

- In case texture pixel alpha is greater than backbuffer pixel alpha, the alpha value is written

- Otherwise, the pixel should still be blended to the content thats already in the backbuffer, but alpha value should stay the same.

 

EDIT2: Ugh, I'm just too tired to think. Of course I can configurate the AlphaSrcBlend and AlphaDestBlend-states to fig this issue. Havn't used those in a while, huh. So the rendering problems are solved now, though Issue#2 is still up. Any ideas for that?


std::unique_ptr issues

08 September 2014 - 08:06 AM

Hello,

 

I'm just in the process of replacing objects that owned and deleted a pure pointer with std::unique_ptr. However, I'm running into some issues:

 

- I've been heavily using forward declaration to speed up compile times, like here:

class Trigger;

class Instance
{
    typedef std::unordered_map<std::wstring, Trigger*> TriggerMap;
public:

    ~Instance(void)
    {
        for(auto& trigger : m_mTrigger)
        {
            delete trigger.second;
        }
    }
    
private:

    TriggerMap m_mTrigger;
}

However, I keep getting "warning C2027" in visual studio, in that an incomplete type can't be deleted when replacing the pure pointer with std::unique_ptr. Some of the times leaving the empty dtor fixes it, however in most cases, especially containers, I have to replace the forward-declaration with a direct include in the header. Is there some way around this? It really bugs me having to do this on so many occasions, could make recompile times significantly larger (already kind of a problem since I'm heavily using templates)...

class Trigger;

class Instance
{
	typedef std::unordered_map<std::wstring, std::unique_ptr<Trigger>> TriggerMap;
public:

	~Instance(void); // defined in cpp-file
	
private:

	TriggerMap m_mTrigger;
}

- I also keep getting compilation-errors with this kind of container-of-pointer setup when the class has a default copy ctor/operator. So the above example wouldn't even compile unless I put:

class Trigger;

class Instance
{
	typedef std::unordered_map<std::wstring, std::unique_ptr<Trigger>> TriggerMap;
public:

        Instance(void) = default;
        Instance(const Instance&) = delete;
	~Instance(void); // defined in cpp-file

        void operator=(const Instance&) = delete;
	
private:

	TriggerMap m_mTrigger;
}

Now I don't completely mind it, in fact I have been very sloppy about doing this before, since a class the won't compile that way shouldn't have been copyable before. Still, I wonder whether there is any shorthand to this? E.g. adding a std::unique_ptr member will automatically disable copy ctor/operator for the class, I wonder if thats possibly within a container class too?


decltype(vector<Type>) doesn't compile

31 August 2014 - 04:37 AM

Hello,

 

I have a chain of classes with a pair of templated set/get methods that require different return semantics based on the type.

float pod = GetAttribute<float>(0);
SomeClass* pObject = GetAttribute<SomeClass>(1);
std::vector<float>& vPOD = GetAttributeArray<float>(2);
const std::vector<SomeClass*>& vObjects= GetAttributeArray<SomeClass>(2);

auto & decltype seemed to do the job:

template<typename Type>
auto Variable::GetValue(void) const -> decltype(returnSemantics<Type>::value)
{
	ACL_ASSERT(m_type == getVariableType<Type>::type);
	ACL_ASSERT(m_isArray == isArray<Type>::value);

	return getObjectData<Type, isPrimitiveType<Type>::value>::GetData(m_pData, m_objectType);
}

returnSemantics is a templated struct that gets specialized for the destired return type:

template<typename Type, bool isPOD = isPrimitiveType<Type>::value>
struct returnSemantics
{
	static Type value = Type();
};

template<typename Type>
struct returnSemantics<Type, true>
{
	static Type value;
};

template<typename Type>
Type returnSemantics<Type, true>::value = Type();

template<typename Type>
struct returnSemantics<Type, false>
{
	static Type* value;
};

template<typename Type>
Type* returnSemantics<Type, false>::value = nullptr;

However, I can't seem to get this to work with the "array"-overload of the method:

template<typename Type>
auto AttributeComponent::GetAttributeArray(unsigned int slot) -> decltype(core::returnSemantics<std::vector<Type>>::value)
{
	return GetAttribute<std::vector<Type>>(slot);
}

When I use this code like in the examples above, I get:

error C2893: Funktionsvorlage 'unknown-type acl::event::AttributeComponent::GetAttributeArray(unsigned int)' konnte nicht spezialisiert werden
1>          Mit den folgenden Vorlagenargumenten:
1>          'Type=int'

which translates to something along the lines of "function template '...' could not be specialized with template arguments 'Type=int'. Why? Is there anything wrong with the decltype-usage?

decltype(core::returnSemantics<std::vector<Type>>::value)

I'm using the "Type" argument to form a vector, and use the vector as template-argument for my returnSemantics-structure... I'm using Visual Studio 2013, does anybode see the issue here?

 

EDIT: Also fails without the specific overload, even using

std::vector<float>& vTest = GetAttribute<std::vector<float>>(0);

which calls the first posted method fails with the same compilation error...


Destructor in vector called too often

19 August 2014 - 02:29 AM

Hello,

 

I recently experienced a very strange crash, which after inspecting further turned out to be caused by the destructor of a class being called one time too often in a certain vector creation. I havn't been able to fully determine the excact reason this is happening, so I hope some of you guys has a better idea of what could be going on. I'm using VS2013. This is the code that crashes:

const ecs::ComponentDeclaration& Sprite::GenerateDeclaration(void)
{
	const ecs::ComponentDeclaration::AttributeVector vAttributes = 
	{
		{ L"Texture", core::VariableType::STRING, offsetof(Sprite, stTexture), onSetTexture },
		{ L"Blending", core::VariableType::INT, offsetof(Sprite, blend) },
	}; // this line here

	static const ecs::ComponentDeclaration declaration(L"Sprite", vAttributes);

	return declaration;
}

The crash happens in the commented line, so appearently in the vector construction. Let me show you all related code:

struct ACCLIMATE_API ComponentDeclaration
{
public:
	typedef std::vector<AttributeDeclaration> AttributeVector;
		
//...
}

This is the declaration of the vector.

struct ACCLIMATE_API AttributeDeclaration
{
	typedef void(*SetCallback)(BaseComponent& component);

	AttributeDeclaration(const std::wstring& stName, core::VariableType type, size_t offset, SetCallback pCallback = nullptr);

	std::wstring stName;
	size_t offset;
	SetCallback pCallback;
	ICustomComponentAttributes* pCustom;

private:
	core::Variable m_default;
};

AttributeDeclaration::AttributeDeclaration(const std::wstring& stName, core::VariableType type, size_t offset, SetCallback pCallback) :
    stName(stName), pCallback(pCallback), m_default(type, false), pCustom(nullptr)
{
}

Thats the class that is being stored, with all related variables/methods. It stores a core::Variable class, which acts like a semi-variant data-container, which is defined as follows:

class ACCLIMATE_API Variable
{
public:
	static const unsigned int NO_OBJECT = -1;

	Variable(VariableType type, bool isArray);
	Variable(const Variable& variable);
	Variable(Variable&& variable);
	~Variable(void);

	Variable& operator=(const Variable& variable);
	Variable& operator=(Variable&& variable);

private:

	void* m_pData;
	VariableType m_type;
	bool m_isArray;
	unsigned int m_objectType;
};

Variable::Variable(VariableType type, bool isArray) :
	m_type(type), m_isArray(isArray), m_objectType(NO_OBJECT),
	m_pData(nullptr)
{
	ACL_ASSERT(m_type != VariableType::OBJECT);

	if(type != VariableType::UNKNOWN)
		m_pData = CallByTypeNoObject<newData, void*>();
}

Variable::Variable(const Variable& variable) :
	m_type(variable.m_type), m_isArray(variable.m_isArray), m_objectType(variable.m_objectType)
{
	m_pData = CopyData(variable.m_pData);
}

Variable::Variable(Variable&& variable) :
	m_type(variable.m_type), m_isArray(variable.m_isArray), m_objectType(variable.m_objectType)
{
	m_pData = variable.m_pData;

	variable.m_pData = nullptr;
	variable.m_type = VariableType::UNKNOWN;
	variable.m_objectType = NO_OBJECT;
}

Variable::~Variable(void)
{
	// just for simplicities sake - the actual deletion of the correct type is normally handled
	delete m_pData;
}

Variable& Variable::operator=(const Variable& variable)
{
	if(this != &variable)
	{
		m_type = variable.m_type;
		m_isArray = variable.m_isArray;
		m_objectType = variable.m_objectType;

		DeleteData();

		m_pData = CopyData(variable.m_pData);
	}
	
	return *this;
}

Variable& Variable::operator=(Variable&& variable)
{
	if(this != &variable)
	{
		m_type = variable.m_type;
		m_isArray = variable.m_isArray;
		m_objectType = variable.m_objectType;

		m_pData = variable.m_pData;
		variable.m_pData = nullptr;
		variable.m_type = VariableType::UNKNOWN;
		variable.m_objectType = NO_OBJECT;
	}

	return *this;
}

Now the crash happens inside this classes ctor. Obviously, m_pData is destroyed more then once. The call hierachy looks as follows:

 

- ctor of first line is being called (line in the first code snipped)

- ctor for second line is being called

- copy-ctor is called from the object of the first line

- copy-ctor is called from the object of the second line

- Destructor is called on the first object

- Destructor is called on the second object

- Destructor is called on the second object again - crash!

 

Now the reason I know that the destructor is called again, and not m_pData is somehow deleted twice is that by setting m_pData to nullptr in the destructor, the crash resolves. Also note that it is probably not an issue with the Variable-class, as the void* m_pData has already been part of the AttributeDeclaration-class before, as well as part of some other class.

 

_____________________________________________________

 

So, thats about all the information I can give. I can't make any sense of the vector-code, so debugging it further is rather out of the question. My question is now: Does someone see something obviously wrong, or knows/has some idea what is going on? Appearently I *could* fix it by simply putting in the nullptr-set in the ctor, but thats way to hackish and obviously just hides the problem. One thing I find interesting is that the move-ctor isn't called, as it is almost always when dealing with this kind of vector-emplacement, maybe thats related to the problem?

 

 


Passing function template pointer

13 August 2014 - 03:43 PM

Hello,

 

I want to be able to pass a pointer to a templated function as a paramter of another function, without specifying the concret template type. From what I've read, this is not possible per-se, however since my case is very specific, I belive that there is at least a work-around. This is how it should syntactically work and look like:

// template function to be passed & called
template<typename Type>
void appendAttribute(ICustomComponentAttributes::AttributeVector& vAttributes, const xml::Node& value)
{
    vAttributes.emplace_back(value.GetName(), conv::FromString<Type>(value.GetValue()));
}

// this is the receiving function/method
template<typename Function, typename Return, typename... Args> // ???
Return AttributeDeclaration::CallByType(Args&&... args) const
{
    switch(type)
    {
    case AttributeType::BOOL:
        return Function<bool>(args...);
    case AttributeType::FLOAT:
        return Function<float>(args...);
    case AttributeType::INT:
        return Function<int>(args...);
    case AttributeType::STRING:
        return Function<std::wstring>(args...);
    default:
        ACL_ASSERT(false);
    }
}

// in code

attribute.CallByType<appendAttribute>(vAttributes, node);

So as you can see, what I already try is to pass the function as part of a template, which of course didn't work that easily. I searched around a bit and found template template arguments, which unfortunately didn't seem to work for my example.

 

Is there a way to get this to work with a similar way to what I try to achieve with template arguments here? I belive that there is, since technically the template instantiations are known inside the CallByType-method. If there isn't, is there any workaround? Code complexity is of no concern, but it should be as easy to use in the actual code as possible, since this will be used in many instances. Thanks!

 

 

 

 

 

 

 

 


PARTNERS