Jump to content

  • Log In with Google      Sign In   
  • Create Account

Stinkee2

Member Since 18 Nov 2011
Offline Last Active Jan 16 2013 11:07 AM

Topics I've Started

Terrain management on iOS for iPads?

02 December 2012 - 10:08 PM

I've been looking around the internet for the past week on and off and can't find anything about what sort of terrain management system would be the best for specifically the iPads.

I wanted to implement ROAM but I can't seem to understand certain aspects of it for some reason and it's taken a massive amount of effort to not only have time to program recently but also understand the concept of the ROAM algorithm. So before I put the effort into it, would it be a lost cause due to the possible performance issues? What would be the best kind of algorithm to use on the iPad? Should most of the work go to the CPU or the GPU?

Need help calling an API function from a script

05 August 2012 - 06:28 PM

I'm building a scripting language for fun and the learning experience. So far I've discovered that using variadic templates I can call a function pointer that has been cast to void (*)() using this function class:

[source lang="cpp"]template <typename ReturnType>class EFunction : public BFunction { public: typedef void (*FuncPtr)(); EFunction() : Function(0) { Type = BFunction::FT_ENVIRONMENT; } template <typename FuncType> EFunction(FuncType Func,const UString &FName) : Function((FuncPtr)Func) { Type = BFunction::FT_ENVIRONMENT; Name = FName; } ~EFunction() { } template <typename FuncType> void SetFunction(FuncType Func) { Function = (FuncPtr)Func; } FuncPtr GetFunction() const { return Function; } template <typename... Arguments> ReturnType Call(Arguments... Params) { ReturnType (*Func)(Arguments...) = (ReturnType (*)(Arguments...))Function; return Func(Params...); } protected: FuncPtr Function; };[/source]
and calling it like this:
[source lang="cpp"]EFunction <int>Print(printf);int Result = Print.Call("Hello, %s","world!\n");Print.Call("Result is: %d\n",Result);[/source]
The output of this would be:

Hello, world!
Result is: 14

This is all fine and good, I think. I only just learned about variable template arguments. Please tell me if anything I've done here is bad or in bad form.

With this in mind, my question is this: when I bind a function call on the C++ side to a function on the script side, when the execution gets to the point when it actually calls that function on the C++ side, how do I pass the arguments? Assume that I have all of the parameter values in an array with an enumeration value that defines the data type of that variable.

Do I need to get my hands dirty with assembly to push the values to the stack manually?

Is rendering to a texture faster than rendering to the screen?

05 July 2012 - 02:47 PM

This is really a question I'd expect to find on google, but I didn't.

So I'm building a GUI to be used with future games. Each time a GUI element is changed visually it receives the event to render itself to a texture and every frame that the element is visible the texture is rendered rather than all of the child GUI elements or characters of text.

I do it in this order:
-Enable RTT
--Render GUI element (and its children if it has any)
-Disable RTT

This made me think. Since that works without going to the screen that is limited to 60FPS, can I move the rendering code for the rest of my engine to another thread that renders to a texture to save time for doing things like full screen anti-aliasing or HDR effects and then just render the texture at 60FPS?

Matrix problems

21 April 2012 - 08:00 AM

I am putting together a little math library for a larger project, and I'm having trouble with my matrix math. This isn't the first time I've had this problem. The last time I had this problem I just used the GLM library instead of writing it all myself though, but now I think it's important for me to understand it well enough to do it myself.

I've made some regular old Vector2,3, and 4 classes to use as rows in my Matrix2,3, and 4 classes. My matrix classes are row major. My main concern right now is the Matrix4 class. Since all the Vector classes are pretty standard, I don't think it's necessary to put them here. Here's my Matrix4 class:

				template <typename ValueType>
				class Matrix4
					{
						public:
							Matrix4()
								{
									Identity(1.0f);
								}
							Matrix4(const Matrix4 <ValueType>&Mat)
								{
									*this = Mat;
								}
							~Matrix4()
								{
								}
						  
							void DebugPrint() const
								{
									for(int i = 0;i < 4;i++)System::USystem::GetSystem()->Log(Ungine::System::LOG_MESSAGE,"%f\t%f\t%f\t%f\n",Rows[i][0],Rows[i][1],Rows[i][2],Rows[i][3]);
								}
						  
							Matrix4 <ValueType>Transpose() const
								{
									Matrix4 <ValueType>Ret;
								  
									Ret[0][0] = Rows[0][0]; Ret[0][1] = Rows[1][0]; Ret[0][2] = Rows[2][0]; Ret[0][3] = Rows[3][0];
									Ret[1][0] = Rows[0][1]; Ret[1][1] = Rows[1][1]; Ret[1][2] = Rows[2][1]; Ret[1][3] = Rows[3][1];
									Ret[2][0] = Rows[0][2]; Ret[2][1] = Rows[1][2]; Ret[2][2] = Rows[2][2]; Ret[2][3] = Rows[3][2];
									Ret[3][0] = Rows[0][3]; Ret[3][1] = Rows[1][3]; Ret[3][2] = Rows[2][3]; Ret[3][3] = Rows[3][3];
								  
									return Ret;
								}
							void operator =(const Matrix4 <ValueType>&Mat)
								{
									for(int i = 0;i < 4;i++) for(int j = 0;j < 4;j++) Rows[i][j] = Mat[i][j];
								}
							Matrix4 <ValueType>operator *(const Matrix4 <ValueType>&Mat) const
								{
									Matrix4 Ret;
								  
									Ret[0][0] = Rows[0].DotProduct(Mat.GetColumn(0));
									Ret[0][1] = Rows[0].DotProduct(Mat.GetColumn(1));
									Ret[0][2] = Rows[0].DotProduct(Mat.GetColumn(2));
									Ret[0][3] = Rows[0].DotProduct(Mat.GetColumn(3));
								  
									Ret[1][0] = Rows[1].DotProduct(Mat.GetColumn(0));
									Ret[1][1] = Rows[1].DotProduct(Mat.GetColumn(1));
									Ret[1][2] = Rows[1].DotProduct(Mat.GetColumn(2));
									Ret[1][3] = Rows[1].DotProduct(Mat.GetColumn(3));
								  
									Ret[2][0] = Rows[2].DotProduct(Mat.GetColumn(0));
									Ret[2][1] = Rows[2].DotProduct(Mat.GetColumn(1));
									Ret[2][2] = Rows[2].DotProduct(Mat.GetColumn(2));
									Ret[2][3] = Rows[2].DotProduct(Mat.GetColumn(3));
								  
									Ret[3][0] = Rows[3].DotProduct(Mat.GetColumn(0));
									Ret[3][1] = Rows[3].DotProduct(Mat.GetColumn(1));
									Ret[3][2] = Rows[3].DotProduct(Mat.GetColumn(2));
									Ret[3][3] = Rows[3].DotProduct(Mat.GetColumn(3));
								  
									return Ret;
								}
							Matrix4 <ValueType>operator *=(const Matrix4 <ValueType>&Mat)
								{
									*this = *this * Mat;
									return *this;
								}
							Vector4 <ValueType>operator *(const Vector4<ValueType>&Vec) const
								{
									Vector4 <ValueType>Ret;
								  
									Ret.x = Rows[0].DotProduct(Vec);
									Ret.y = Rows[1].DotProduct(Vec);
									Ret.z = Rows[2].DotProduct(Vec);
									Ret.w = Rows[3].DotProduct(Vec);
								  
									return Ret;
								}
							Vector3 <ValueType>operator *(const Vector3<ValueType>&Vec) const
								{
									Vector3 <ValueType>Ret;
								  
									Ret.x = Rows[0].DotProduct(Vec);
									Ret.y = Rows[1].DotProduct(Vec);
									Ret.z = Rows[2].DotProduct(Vec);
								  
									return Ret;
								}
						  
							void Identity(ValueType id = 1.0f)
								{
									Rows[0] = Vector4 <ValueType>(id,0.0f,0.0f,0.0f);
									Rows[1] = Vector4 <ValueType>(0.0f,id,0.0f,0.0f);
									Rows[2] = Vector4 <ValueType>(0.0f,0.0f,id,0.0f);
									Rows[3] = Vector4 <ValueType>(0.0f,0.0f,0.0f,id);
								}
							void Translate(const Vector3 <ValueType>&Trans)
								{
									Matrix4 <ValueType> Mat;
								  
									Mat[0] = Vector4 <ValueType>(1.0f,0.0f,0.0f,Trans.x);
									Mat[1] = Vector4 <ValueType>(0.0f,1.0f,0.0f,Trans.y);
									Mat[2] = Vector4 <ValueType>(0.0f,0.0f,1.0f,Trans.z);
									Mat[3] = Vector4 <ValueType>(0.0f,0.0f,0.0f,1.0f   );
								  
									*this = *this * Mat;
								}
							void Rotate(const Vector3 <ValueType>&Axis,ValueType Angle)
								{
									Matrix4 Mat;
								  
									ValueType hAngle = Angle * 0.5f;
								  
									ValueType SinAngle = Sin(hAngle);
									ValueType CosAngle = Cos(hAngle);
								  
									ValueType w = CosAngle;
									ValueType x = Axis.x * SinAngle;
									ValueType y = Axis.y * SinAngle;
									ValueType z = Axis.z * SinAngle;
								  
									ValueType xSq = x * x;
									ValueType ySq = y * y;
									ValueType zSq = z * z;
									ValueType xy  = x * y;
									ValueType xz  = x * z;
									ValueType xw  = x * w;
									ValueType yw  = y * w;
									ValueType zw  = z * w;
									ValueType zy  = z * y;
								  
									Mat[0][0] = 1.0f - 2.0f * (ySq + zSq);
									Mat[0][1] = 2.0f *   (xy + zw);
									Mat[0][2] = 2.0f *   (xz - yw);
									Mat[0][3] = 0.0f;
									Mat[1][0] = 2.0f *   (xy - zw);
									Mat[1][1] = 1.0f - 2.0f * (xSq + zSq);
									Mat[1][2] = 2.0f *   (zy + xw);
									Mat[1][3] = 0.0f;
									Mat[2][0] = 2.0f *   (xz + yw);
									Mat[2][1] = 2.0f *   (zy - xw);
									Mat[2][2] = 1.0f - 2.0f * (xSq + ySq);
									Mat[2][3] = 0.0f;
								  
									Mat[3][0] = 0.0f;
									Mat[3][1] = 0.0f;
									Mat[3][2] = 0.0f;
									Mat[3][3] = 1.0f;
								  
									*this = *this * Mat;
								}
							void Scale(ValueType Scale)
								{
									Matrix4 <ValueType> Mat;
								  
									Mat[0] = Vector4 <ValueType>(Scale,0.0f,0.0f,0.0f);
									Mat[1] = Vector4 <ValueType>(0.0f,Scale,0.0f,0.0f);
									Mat[2] = Vector4 <ValueType>(0.0f,0.0f,Scale,0.0f);
									Mat[3] = Vector4 <ValueType>(0.0f,0.0f,0.0f,Scale);
								  
									*this = *this * Mat;
								}
							void Scale(const Vector4 <ValueType> &Scale)
								{
									Matrix4 <ValueType> Mat;
								  
									Mat[0] = Vector4 <ValueType>(Scale.x,0.0f,0.0f,0.0f);
									Mat[1] = Vector4 <ValueType>(0.0f,Scale.y,0.0f,0.0f);
									Mat[2] = Vector4 <ValueType>(0.0f,0.0f,Scale.z,0.0f);
									Mat[3] = Vector4 <ValueType>(0.0f,0.0f,0.0f,Scale.w);
								  
									*this = *this * Mat;
								}
							ValueType Determinant() const
								{
									abort();
								}
							bool Inverse(Matrix4 <ValueType>*Mat)
								{
									abort();
									return false;
								}
						  
							ValueType *Ptr()
								{
									return &Rows[0].x;
								}
							Vector4 <ValueType>GetColumn(Index Idx) const
								{
									return Vector4 <ValueType>(Rows[0][Idx],Rows[1][Idx],Rows[2][Idx],Rows[3][Idx]);
								}
							Vector4 <ValueType>&operator[](Index Idx)
								{
									return Rows[Idx];
								}
							Vector4 <ValueType>operator[](Index Idx) const
								{
									return Rows[Idx];
								}
						protected:
							Vector4 <ValueType>Rows[4];
					};

I realized I had a problems when I was trying to use this class to build a MVP matrix for a camera. No matter how I do it, what order I multiply in, whether or not the end MVP matrix or the individual matrices are transposed, what I see on the screen is just a very stretched out polygon. I am attempting to render a simple square at 0,0,0,0 with a perspective and orthographic projection.

Here's part of the render function where I am testing the matrix class:
System::USystem::GetSystem()->SetAngleType(Ungine::System::AT_DEGREE);
	  
		Matrix4f Model, View, Projection, MVP;
		static f32 Val = 0.0f;
		Val += 0.01f;
		//Model.Translate(Vector3f(768 / 2,1024 / 2,0));
		//Model.Rotate(Vector3f(0,1,1).Normalize(),Val / 2.0f);
		//Model.Scale(Vector4f((2 + Math::Sin(Val)) * 0.5f,(2 + Math::Sin(Val)) * 0.5f,(2 + Math::Sin(Val)) * 0.5f,1.0f));//;Rotate(Vector3f(0,0,1),Val);
		View = LookAt(Vector3f(0,0,-20.0f),Vector3f(0,0,0),Vector3f(0,1,0));
	  
		Projection = Perspectivef(50.0f,768.0f / 1024.0f,0.1f,1000.0f);
		//Projection = Orthographicf(0.0f,768.0f,0.0f,1024.0f,0.0f,1000.0f);
	  
		MVP = Projection * View * Model;
	  
		glUniformMatrix4fv(MVP_Loc,1,false,MVP.Ptr());
	  

And here are the projection and LookAt functions:
Matrix4f Perspectivef(f32 FieldOfView,f32 AspectRatio,f32 Near,f32 Far)
					{
						Matrix4f Mat;
					  
						f32 TanFov = Tan(FieldOfView * 0.5f);
					  
						f32 a = 1.0f / (AspectRatio * TanFov);
						f32 b = 1.0f / TanFov;
						f32 c = Far / (Far - Near);
						f32 d = -(2.0f * Near * Far) / (Far - Near);
					  
						Mat[0] = Vector4f(a	 , 0.0f , 0.0f , 0.0f);
						Mat[1] = Vector4f(0.0f  , b	, 0.0f , 0.0f);
						Mat[2] = Vector4f(0.0f  , 0.0f , c	, d   );
						Mat[3] = Vector4f(0.0f  , 0.0f , 1.0f , 0.0f);
					  
						return Mat;
					}
				Matrix4f Orthographicf(f32 Left,f32 Right,f32 Top,f32 Bottom,f32 Near,f32 Far)
					{
						Matrix4f Mat;
					  
						f32 dW = Left - Right;
						f32 dH = Top - Bottom;
						f32 dL = Far - Near;
					  
						f32 Tx = (Right + Left) / (Right - Left);
						f32 Ty = (Far + Near) / (Far - Near);
						f32 Tz = (Top + Bottom) / (Top - Bottom);
					  
						Mat[0] = Vector4f(2.0f / (dW),0.0f	   ,0.0f		,Tx  );
						Mat[1] = Vector4f(0.0f	   ,2.0f / (dH),0.0f		,Ty  );
						Mat[2] = Vector4f(0.0f	   ,0.0f	   ,-(2.0f / dL),Tz  );
						Mat[3] = Vector4f(0.0f	   ,0.0f	   ,0.0f		,1.0f);
					  
						return Mat;
					}
				Matrix4f LookAt(const Vector3f &Eye,const Vector3f &Target,const Vector3f &Up)
					{
						Matrix4f Mat;
					  
						Vector3f Forward, Side, _Up;
						Forward = (Target - Eye).Normalize();
						Side = Forward.CrossProduct(Up).Normalize();
						_Up = Side.CrossProduct(Forward).Normalize();
						Mat[0] = Vector4f(Side		   ,0.0f		  );
						Mat[1] = Vector4f(_Up			,0.0f		  );
						Mat[2] = Vector4f(Forward * -1.0f,0.0f		  );
						Mat[3] = Vector4f(0.0f		   ,0.0f,0.0f,1.0f);
						Mat.Translate(Eye * -1.0f);
					  
						return Mat;
					}

It's a bunch of code to look through, but if anyone has the patience, could you tell me if you see anything that looks wrong?
Matrix4f is just Matrix4 <f32>. Also, sorry about the large amount of whitespace before each line, that's just from the indentation from two namespaces that I didn't include in the code, for some reason they got larger when I submitted this thread.

Thank you for your time!

Terrain generation from heightmap

18 November 2011 - 02:26 PM

Hello, everybody. This is my first post here, but I've been reading these forums for years and it's always been very helpful to me. I'm having a problem creating an index buffer for terrains generated from heightmaps with dimensions that are greater than 256x256. I've searched for hours and I've tried to solve the problem on my own for days, but sadly nothing works. I have everything else working though, loading, getting height values, vertex generation. It works perfectly for heightmaps 256x256 and below...

Before I post my code I'll show you some screenshots. Ignore the blue thing, it's a camera that I want to roam (heh heh, ROAM...) around the terrain so I can test out various culling and LOD algorithms to find out which one is the best for specific iDevices.

256x256
Posted Image

512x512
Posted Image

This is making me pull my hair out... And I know it's not a loading/setting vertices thing because when I render the vertex buffer (not the index buffer) I get this
512x512
Posted Image

This is what my index buffer construction code looks like:
void TerrainSceneNode::CreateFromHeightMap(const HeightMap &HMap,const Dimension2D &TerrainSize,float MinHeight,float MaxHeight)
	{
 		Dimension2D TexSize = HMap.GetDimensions();
 		for(int X = 0;X < TexSize.Width;X++)
 		{
     		for(int Z = 0;Z < TexSize.Height;Z++)
 			{
     			Vertices += HMap.GetVertexAtPos(Vector2D(X,Z),TerrainSize,MinHeight,MaxHeight);
 			}
 		}

 		for(int X = 0;X < TexSize.Width;X++)
 		{
     		IndexBuffer Strip;
     		Strip.SetVertexBuffer(&Vertices);
     		for(int Z = 0;Z < TexSize.Height;Z++)
 			{
         		Strip += X * TexSize.Width + (Z + 1);
         		Strip += (X + 1) * TexSize.Width + (Z + 1);
     		}
     		TStrips.push_back(Strip);
 		}
            	
 		TerrainArea = Rectangle2D(-TerrainSize.Width * 0.5f,-TerrainSize.Height * 0.5f,TerrainSize);
 		Loaded = true;
	}

The first set of for loops works perfectly, the problem has to be something with the index buffer code.

I've looked over that a million times and I don't understand what's going on. Vertices is a vertex buffer I use that has TexSize.Width * TexSize.Height vertices in it, so the index of a 2D position of an element in the buffer (a 1D std::vector) would be X * TexSize.Width + Z. Why does that work perfectly for heightmaps 256x256 and below, but not a SINGLE pixel more? I cannot find my error.

Also, this is probably important. When I render the vertices as points like in the last 512x512 image but with a 1024x1024 heightmap I get this:
1024x1024
Posted Image
It's kind of neat that 1,048,576 vertices looks like a regular mesh here, but that's irrelevant. Also sorry for the large image size, I forgot to click resize on tinypic...
The left side of the terrain is identical to about 1/4 of the right side! What the heck is going on here? Please somebody help me before I pull all my hair out and my girlfriend leaves me.

PARTNERS