[.net] C#-based OpenGL Engine?

Started by
32 comments, last by cody 18 years, 1 month ago
i have also been playing with Tao Framework and have been using SDL for window creationa and input managment as well as timing. as i have to work on both Window and Linux systems some times. granted i am fairly new to this as i stopped doing any programming a few years ago really. this code contains some of my other classes as well just ignore gameconsole,gameengine and defaultfont

		static void Main(string[] args)		{			bool bRunning = true;			bool bActive = true;			bool bCapMouse = true;			bool bFullScreen = false;			IntPtr sdlSurface = IntPtr.Zero;			int SDLVideoFlags = 0;			int SDLVideoFlagsFull = 0;			bool[] Keys = new bool[500];			bool[] MouseKeys = new bool[8];			int X = 0, Y = 0;			int width = 800, height = 600;			Console.WriteLine("Setting up SDL and Devices Surface!");			if (Sdl.SDL_Init(Sdl.SDL_INIT_VIDEO) < 0)			{				Console.WriteLine("Unable to start SDL, SDL gave the following error!");				Console.WriteLine("{0}", Sdl.SDL_GetError());				Sdl.SDL_Quit();			}			try			{				Sdl.SDL_VideoInfo info = (Sdl.SDL_VideoInfo)Marshal.PtrToStructure(Sdl.SDL_GetVideoInfo(),																			   typeof(Sdl.SDL_VideoInfo));				SDLVideoFlags = Sdl.SDL_OPENGL |								Sdl.SDL_GL_DOUBLEBUFFER |								Sdl.SDL_HWPALETTE |								Sdl.SDL_RESIZABLE;				SDLVideoFlags |= (info.hw_available > 0 ? Sdl.SDL_HWSURFACE : Sdl.SDL_SWSURFACE);				if (info.blit_hw > 0)					SDLVideoFlags |= Sdl.SDL_HWACCEL;				SDLVideoFlagsFull = SDLVideoFlags | Sdl.SDL_FULLSCREEN;				Sdl.SDL_GL_SetAttribute(Sdl.SDL_GL_DOUBLEBUFFER, 1);				sdlSurface = Sdl.SDL_SetVideoMode(width, height, 0, SDLVideoFlags);				Sdl.SDL_WM_SetCaption("Untitled",null);				if (sdlSurface == IntPtr.Zero)				{					Console.WriteLine("Unable to save surface pointer");				}			}			catch (NullReferenceException)			{				Console.WriteLine("Unable to get video info");				Console.WriteLine("{0}", Sdl.SDL_GetError());				Sdl.SDL_Quit();			}			catch (Exception exc)			{				Console.WriteLine("An unknown error has occured while initializing SDL");				Console.WriteLine("{0}", Sdl.SDL_GetError());				Console.WriteLine(exc);				Sdl.SDL_Quit();			}						Sdl.SDL_Event sdlEvent;			InitGL();			CGameEngine engine = new CGameEngine();			engine.InitEngine();			GameConsole console = new GameConsole("console.tga");			engine.Camera.AspectRatio = width / height;			engine.Camera.ResizeCameraViewPort(width,height);			int halfWidth = width >> 1;			int halfHeight = height >> 1;			GameConsole.width = width;			GameConsole.height = height;			Sdl.SDL_WM_GrabInput(Sdl.SDL_GRAB_ON);			Sdl.SDL_ShowCursor(0);			while (bRunning)			{				while(Sdl.SDL_PollEvent(out sdlEvent) == 1)				{					switch (sdlEvent.type)					{						case Sdl.SDL_ACTIVEEVENT:							if (sdlEvent.active.gain == 0)							{								Sdl.SDL_ShowCursor(1);								Sdl.SDL_WM_GrabInput(Sdl.SDL_GRAB_OFF);								bCapMouse = false;							}							else							{								Sdl.SDL_ShowCursor(0);								Sdl.SDL_WM_GrabInput(Sdl.SDL_GRAB_ON);								bCapMouse = true;							}							break;						case Sdl.SDL_VIDEORESIZE:							sdlSurface = Sdl.SDL_SetVideoMode(sdlEvent.resize.w, sdlEvent.resize.h, 0, SDLVideoFlags);							engine.Camera.AspectRatio = (float)sdlEvent.resize.w / (float)sdlEvent.resize.h;							engine.Camera.ResizeCameraViewPort(sdlEvent.resize.w, sdlEvent.resize.h);							halfWidth = width >> 1;							halfHeight = height >> 1;							break;						case Sdl.SDL_KEYDOWN:							if (!GameConsole.IsVisible)							{								Keys[sdlEvent.key.keysym.sym] = true;							}							else							{								int key = sdlEvent.key.keysym.sym;								if (key == (int)Engine.Keys.K_BACKSPACE)								{									GameConsole.Backspace();								}								else if (key == (int)Engine.Keys.K_RETURN)								{									GameConsole.AddLine();								}								else if (key == (int)Engine.Keys.K_TAB)									GameConsole.ToggleState();								else if (key < 256)								{									GameConsole.AddCharacterToEntryLine((char)sdlEvent.key.keysym.sym);								}							}							if (sdlEvent.key.keysym.sym == Sdl.SDLK_ESCAPE)							{								bActive = bRunning = false;								Sdl.SDL_Quit();							}							if (sdlEvent.key.keysym.sym == Sdl.SDLK_F1)							{								bFullScreen = !bFullScreen;								Sdl.SDL_FreeSurface(sdlSurface);								sdlSurface = Sdl.SDL_SetVideoMode(width, height, 0, (bFullScreen ? SDLVideoFlagsFull : SDLVideoFlags));								engine.Camera.AspectRatio = width / height;								engine.Camera.ResizeCameraViewPort(width, height);								InitGL();							}							if (Keys[(int)Engine.Keys.K_TAB])								GameConsole.ToggleState();							break;						case Sdl.SDL_KEYUP:							Keys[sdlEvent.key.keysym.sym] = false;							break;						case Sdl.SDL_MOUSEBUTTONDOWN:							MouseKeys[sdlEvent.button.button] = true;						break;						case Sdl.SDL_MOUSEBUTTONUP:							MouseKeys[sdlEvent.button.button] = false;						break;						case Sdl.SDL_QUIT:							bActive = bRunning = false;							Sdl.SDL_Quit();						break;					}									}				if (bCapMouse)				{					Sdl.SDL_GetMouseState(out X, out Y);					X = X - halfWidth;					Y = Y - halfHeight;					Sdl.SDL_WarpMouse((short)halfWidth, (short)halfHeight);				}								Sdl.SDL_Delay(1); // sleep and allow other threads to execute				engine.Handle_Input(Keys, MouseKeys, -X, -Y);  // handle Key and mouse events in Engine 								engine.GameMain(); // game main								if (bActive)				{					engine.GameRender();					console.Render();					DefaultFont.Print(string.Format("{0} Frames in {1} Seconds = {2} AVG FPS : {3} Actual FPS", 													EngineTime.g_TotalFrames,													(int)EngineTime.CurrentTime,													(int)(EngineTime.g_TotalFrames/EngineTime.CurrentTime),(int)EngineTime.g_FramePerSecond),1,1.0f,10,height -15) ;					Sdl.SDL_GL_SwapBuffers();				}			}			Sdl.SDL_Quit();		}


[Edited by - Rob Loach on March 3, 2006 10:54:44 AM]
Advertisement
Looks great, RenZimE. Speaking of SDL and the .NET Framework, SDL.NET 4.0.3-1 just came out. You can see details on the new version here.

Difference between Tao.Sdl and SDL.NET? SDL.NET puts an object oriented layer onto Tao.Sdl. This means instead of:
IntPtr surface = Tao.Sdl.Sdl_Image.IMG_Load("image.bmp");
... you'd be using ...
Surface surface = new Surface("image.bmp");
Rob Loach [Website] [Projects] [Contact]
Quote:Original post by Rob Loach
Looks great, RenZimE. Speaking of SDL and the .NET Framework, SDL.NET 4.0.3-1 just came out. You can see details on the new version here.

Difference between Tao.Sdl and SDL.NET? SDL.NET puts an object oriented layer onto Tao.Sdl. This means instead of:
IntPtr surface = Tao.Sdl.Sdl_Image.IMG_Load("image.bmp");
... you'd be using ...
Surface surface = new Surface("image.bmp");


hmm ty for the info on SDL.net i had no idea it even existed.
I recently wrote a 3d engine using C# and OpenGL.
I liked it.

Here are a couple of tips though.

Use some OpenGL pinvoke signatures that closely match the normal signatures and create a wrapper around the whole thing again. Find the simplest example that you can on the internet.

Use a wrapper for your code. Later, when you decide to use directx or something else instead, you will need to change much less code and it will be optimized across platforms.

Use directx for sound and joystick work at first. It will be easier that way.

Remember that most examples that you find for OpenGL will be in C++. To be honest though, this didn't pose too much of a problem for me. Just drop the C++ code into the project and port it right there.
Quote:Original post by RipTorn
I can probably host it for you, just as long as 5,000 people don't download it, things should be sweet.


OK, how should I send it to you?

I've made some modifications to the Tao SimpleOpenGLControl to make it:

1. Actually work
2. Behave nicely in design mode or when embedded in another control in design mode
3. Work with .NET 2.0 and VS.NET 2005

Do you think the Tao people would want it or are they sticking with .NET 1.1?

Quote:
Do you think the Tao people would want it or are they sticking with .NET 1.1?


I've recently tried using Tao with .net 2.0, the lastest version on their source control list has a visual studio 2005 solution builder, so I guess they are working on it. However, it doesn't compile as the post processor crashes when using .net 2.0... (unelss I have not set it up right)
Quote:Original post by DaWanderer
I've made some modifications to the Tao SimpleOpenGLControl to make it:

1. Actually work
2. Behave nicely in design mode or when embedded in another control in design mode
3. Work with .NET 2.0 and VS.NET 2005

Do you think the Tao people would want it or are they sticking with .NET 1.1?
Feel free to post it here or upload it to robloach.net/files (guest:guest). Even on the Tao Mailing List. I'll check it out and see what can be added to the repository. People have had problems with it in the past so any help would be really appreciated [smile].

[Edited by - Rob Loach on March 4, 2006 1:17:48 AM]
Rob Loach [Website] [Projects] [Contact]
Quote:Original post by Rob Loach
Feel free to post it here or upload it to robloach.net/files (guest:guest).


I uploaded the file under the "tao" directory. It's called OpenGLWinFormsControl.cs. I hope it helps!

i wouldnt use that control for a game as it makes it platform-dependent without a reason.(i guess)
its ok for a winforms application though.

im programming a game with c#/opengl, too, you can see pics and videos here:
link to the thread

performance is ok on windows, but the linux version is quite slow.(i havent done a real benchmark, its just a feeling though)
Quote:Original post by cody
i wouldnt use that control for a game as it makes it platform-dependent without a reason.(i guess)
its ok for a winforms application though.


I agree completely. In my case, the application is purely for Windows and I need to have the rich WinForms designer in VS.NET 2005 for the UI.

Also, RipTorn has graciously hosted my code for the C# OpenGL BSP engine. You can download it from here. The game is a simple FPS that loads Quake 3 BSP files (probably not 100% correctly...). Only 2 weapons available (numeric keys 1 & 2) ;) The GameServer.msi installer will install the server program that will host a game session so multiple players can connect and fight against each other. There are a few different game types including a simple deathmatch mode, an item collecting contest, and a "marked man" mode where you have to be the marked man at the end of the round to win (you get marked by shooting the current marked man).

This was my final project for my game programming class. I hope other will find the code useful in some way.

This topic is closed to new replies.

Advertisement