Jump to content
  • Advertisement
Sign in to follow this  
_WeirdCat_

make c++ more like glsl

This topic is 936 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement

Naively, something like this:

vec3 xy(){
    vec3 v;
    v.x=x;
    v.y=y;
    v.z=0; // or whatever you want for a non-asked-for swizzle
    return v;
}

It'd be kind of tedious, but you could write out whatever swizzles you want as functions like that - there are only so many permutations for a 3D vector, and with a decent constructor defined, they would be one-liners.

 

In C#, this would probably be something I'd do with some read-only properties, which is effectively the same thing, just lets you do it without writing parentheses.

Share this post


Link to post
Share on other sites
The library linked above provides an exact match so the following is but a humble exercise.

The prior discussions in the thread below also seemed to avoid the "naive" approach so I thought I'd give it the 'ol newbie try...

http://www.gamedev.net/topic/650045-vector-swizzling-in-c/


#include 
#include 
#include 
#include 

enum axis {
	x = 0, y = 1, z = 2
};

template< typename T >
class vec3
{
public:
	vec3(){}
	vec3(T in_x, T in_y, T in_z)
	{
		_values[0] = in_x;
		_values[1] = in_y;
		_values[2] = in_z;
	}
	vec3(const vec3 &in)
	{
		*this = in;
	}
	vec3& operator=(const vec3 &in)
	{
		if(this != &in) {
			_values[0] = in._values[0];
			_values[1] = in._values[1];
			_values[2] = in._values[2];
		}
		return *this;
	}
	T& operator[](axis in_a);
	const T& operator[](axis in_a) const;
	constexpr vec3< T > operator()(axis in_01, axis in_1, axis in_2) const;
private:
	T _values[3] {
		std::numeric_limits::quiet_NaN(),
		std::numeric_limits::quiet_NaN(),
		std::numeric_limits::quiet_NaN()
	};
};

template< typename T >
T& vec3< T >::operator[](axis in_a)
{
	return _values[static_cast< size_t >(in_a)];
}

template< typename T >
const T& vec3< T >::operator[](axis in_a) const
{
	return _values[static_cast< size_t >(in_a)];
}

template< typename T >
constexpr vec3< T > vec3< T >::operator()(axis in_0, axis in_1, axis in_2) const
{
	return vec3< T >(
		_values[in_0],
		_values[in_1],
		_values[in_2]
	);
}

template< typename T >
void vec3_print(const char *in_name, const vec3< T > &in_v)
{
	std::cout << in_name << "{"
		<< in_v[x] << ", "
		<< in_v[y]<< ", "
		<< in_v[z]<< " }\n"
	;
}

int main()
{
	typedef vec3< float > vec3f;

	vec3f v1{1.1f, 1.2f, 1.3f};
	vec3f v2{2.1f, 2.2f, 2.3f};
	vec3f v3;
	
	vec3_print("v1", v1);
	vec3_print("v2", v2);
	vec3_print("v3", v3);

	v1[x] = v2[y];
	v2[z] = v1[y];

	std::cout << "> v1[x] = v2[y]; v2[z] = v1[y];\n";
	
	vec3_print("v1", v1);
	vec3_print("v2", v2);

	v3[y] = v2[z];

	std::cout << "> v3[y] = v2[z];\n";

	vec3_print("v3", v3);

	vec3_print("> v3(y, z, x)\n", v3(y, z, x));

	vec3_print("v3", v3);

	v3 = v2(z, y, x);

	std::cout << "> v3 = v2(z, y, x);\n";
	
	vec3_print("v3", v3);
	vec3_print("v2", v2);
	
	return 0;
}

Share this post


Link to post
Share on other sites

Naively, something like this:

vec3 xy(){
    vec3 v;
    v.x=x;
    v.y=y;
    v.z=0; // or whatever you want for a non-asked-for swizzle
    return v;
}

It'd be kind of tedious, but you could write out whatever swizzles you want as functions like that - there are only so many permutations for a 3D vector, and with a decent constructor defined, they would be one-liners.

 

In C#, this would probably be something I'd do with some read-only properties, which is effectively the same thing, just lets you do it without writing parentheses.

Honestly the function variety makes things eight thousand percent easier. That's what I did in my code, rather than play the ridiculous games required to get native-looking swizzles.

Share this post


Link to post
Share on other sites

I'm assuming here that storage is not an issue, IE, you will not be storing this vector directly into a file.

class Ref2Floats
{
    Ref2Floats(float& r0, float& r1) { ref0= r0; ref1 = r1; }
    float& ref0;
    float& ref1;
    Ref2Floats& operator=(Ref2Floats& a, const Ref2Floats& b) { a.ref0 = b.ref0;  a.ref1 = b.ref1; return a; }

   (add other operators)
};


in vector class:
class Vec3
{
    float x;
    float y;
    float z;
    Ref2Floats xy;
    Ref2Floats xz;
    Ref2Floats yz;

}
in vector constructor:
Vec3::Vec3(): xy(x, y), xz(x, z), yz(y, z)
{
    
Didn't actually test, but should work, but will increase memory use of each Vec3 instance. I've done stuff along the same vein to simplify some situations.

EDIT: Sorry, just realized I misunderstood what you were trying to do. I'll leave the code because you might also find it useful.

Edited by nfries88

Share this post


Link to post
Share on other sites

https://github.com/gwiazdorrr/CxxSwizzle


Good god that is some voodoo right there... I pity the compiler.

Comment from the code:

//! Array needs to be like a steak - the rawest possible
//! (Wow - I managed to WTF myself upon reading the above after a week or two)
Edited by Nypyren

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!