class Raster
{
//Necesitamos Importar los metodos para obtener y liberar el
//Device Context
#region Importaciones
/// <summary>
/// IMporta el metodo GetDC(Intptr hWnd) del GDI
/// </summary>
/// <param name="hWnd">El handle de una ventana</param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr hWnd);
/// <summary>
/// Este importa el ReleaseDC que libera el dispositivo
/// </summary>
/// <param name="hWnd">El Handle de la ventana</param>
/// <param name="hDC">El dispositivo q se va a liberar</param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
#endregion
#region MiembrosPrivados
private Control _renderTarget;
private byte _colorBits;
private byte _depthBits;
//El tipo Intpts es para handles o para referencias
private IntPtr _handleDeviceContext;
private IntPtr _handleRenderContex;
#endregion
#region Propiedades
public byte ColorBits
{
set
{
_colorBits = value;
}
get
{
return _colorBits;
}
}
public byte DepthBits
{
set
{
_depthBits = value;
}
get
{
return _depthBits;
}
}
public IntPtr DeviceContext
{
set
{
_handleDeviceContext = value;
}
get
{
return _handleDeviceContext;
}
}
public IntPtr RenderContext
{
set
{
_handleRenderContex = value;
}
get
{
return _handleRenderContex;
}
}
#endregion
#region Constructor
/// <summary>
/// Inicializa varias cosas
/// </summary>
public Raster()
{
ColorBits = 24;
DepthBits = 32;
RenderContext = IntPtr.Zero;
DeviceContext = IntPtr.Zero;
}
#endregion
#region Metodos Publicos
/// <summary>
/// Inicializa OpenGl
/// </summary>
/// <returns>True si se inicializo, sino false</returns>
public bool Init(Control RenderTarget)
{
//Variables Locales
int pixelFormat;
Gdi.PIXELFORMATDESCRIPTOR pixelFormatDescriptor;
//Paso de datos
_renderTarget = RenderTarget;
//Intentamos obtener el device context de la ventana
DeviceContext = GetDC(_renderTarget.Handle);
if (DeviceContext == IntPtr.Zero)
{
//y mostramos un mensaje de error si no se pudo
MessageBox.Show(_renderTarget, "No se pudo obtener el"
+ " Device Context para la ventana","Error"
,MessageBoxButtons.OK,MessageBoxIcon.Error);
_renderTarget = null;
return false;
}
//Se llena el pixelformatdescriptor y hacemos que el programa
//escoja un formato de pixeles adecuado
pixelFormatDescriptor = llenarPixelFormatDescriptor();
pixelFormat = Gdi.ChoosePixelFormat(DeviceContext, ref pixelFormatDescriptor);
if (pixelFormat == 0)
{
//Y chequiamos si se pudo o no
MessageBox.Show(_renderTarget, "No se pudo escoger un"
+ " Formato de pixeles", "Error"
,MessageBoxButtons.OK,MessageBoxIcon.Error);
ReleaseDC(_renderTarget.Handle, DeviceContext);
DeviceContext = IntPtr.Zero;
_renderTarget = null;
return false;
}
//Ñe decimos al programa que use ese formato de pixeles en la ventana
if (!Gdi._SetPixelFormat(DeviceContext, pixelFormat, ref pixelFormatDescriptor))
{
MessageBox.Show(_renderTarget, "No se pudo setear el"
+ " Formato de pixeles para la ventana", "Error"
,MessageBoxButtons.OK,MessageBoxIcon.Error);
ReleaseDC(_renderTarget.Handle, DeviceContext);
DeviceContext = IntPtr.Zero;
_renderTarget = null;
return false;
}
//Con el deveice context creamos un render context para el programa
RenderContext = Wgl.wglCreateContext(DeviceContext);
if (RenderContext == IntPtr.Zero)
{
MessageBox.Show(_renderTarget, "No se pudo obtener el"
+ " Render Context para la ventana", "Error"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
ReleaseDC(_renderTarget.Handle, DeviceContext);
DeviceContext = IntPtr.Zero;
_renderTarget = null;
return false;
}
//Acemos que el thread que llama al metodo use el render context
//que creamos como su render context actual
if (!Wgl.wglMakeCurrent(DeviceContext, RenderContext))
{
MessageBox.Show(_renderTarget, "No se pudo obtener el"
+ " Render Context para la ventana", "Error"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
Wgl.wglDeleteContext(RenderContext);
ReleaseDC(_renderTarget.Handle, DeviceContext);
RenderContext = IntPtr.Zero;
DeviceContext = IntPtr.Zero;
_renderTarget = null;
return false;
}
return true;
}
public bool Release()
{
//Revisa si se ha llamado al metodo init correctamente antes de liberar
//los recursos
if (RenderContext == IntPtr.Zero || DeviceContext == IntPtr.Zero)
{
MessageBox.Show("No esta inicializado");
return false;
}
//Dejamos de hacer que el thread use nuestro rendercontext para dibujar
if (!Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero))
{
MessageBox.Show(_renderTarget, "No se pudo liberar al DC y al RC",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
//Liberamos el Rendering Context
if (!Wgl.wglDeleteContext(RenderContext))
{
MessageBox.Show(_renderTarget, "No se pudo liberar al RenderContext",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
RenderContext = IntPtr.Zero;
//Liberamos al Device Context
if (!ReleaseDC(_renderTarget.Handle, DeviceContext))
{
MessageBox.Show(_renderTarget, "No se pudo liberar al Device Context",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
DeviceContext = IntPtr.Zero;
//y limpio la referencia a la ventana
_renderTarget = null;
return true;
}
#endregion
#region Metodos Privados
private Gdi.PIXELFORMATDESCRIPTOR llenarPixelFormatDescriptor()
{
Gdi.PIXELFORMATDESCRIPTOR pixelFormat = new Gdi.PIXELFORMATDESCRIPTOR();
pixelFormat.nSize = (short)Marshal.SizeOf(pixelFormat);
pixelFormat.nVersion = 1; //En Windows siempre es 1
pixelFormat.dwFlags = Gdi.PFD_DRAW_TO_WINDOW | Gdi.PFD_DOUBLEBUFFER |
Gdi.PFD_SUPPORT_OPENGL;
//La otra opcion en pixel Type es el modo paleta que es muy antiguo
pixelFormat.iPixelType = Gdi.PFD_TYPE_RGBA;
pixelFormat.cColorBits = ColorBits;
pixelFormat.cDepthBits = DepthBits;
pixelFormat.cStencilBits = 0; //No lo necesitamos en esta oportunidad
pixelFormat.cAuxBuffers = 0; //No es permitido en esta implementacion
pixelFormat.bReserved = 0; //No necesitamos underlay o overlay planes
pixelFormat.dwVisibleMask = 0; //No usamos Underlay planes
#region Propiedades que no usamos
pixelFormat.iLayerType = 0;
pixelFormat.dwLayerMask = 0;
pixelFormat.dwDamageMask = 0;
pixelFormat.cRedBits = 0;
pixelFormat.cGreenBits = 0;
pixelFormat.cBlueBits = 0;
pixelFormat.cAlphaBits = 0;
pixelFormat.cAccumBits = 0;
pixelFormat.cAccumBlueBits = 0;
pixelFormat.cAccumGreenBits = 0;
pixelFormat.cAccumRedBits = 0;
pixelFormat.cAccumAlphaBits = 0;
pixelFormat.cRedShift = 0;
pixelFormat.cGreenShift = 0;
pixelFormat.cBlueShift = 0;
pixelFormat.cAlphaShift = 0;
#endregion
return pixelFormat;
}
#endregion
}
Help with Tao in c#[Solved]
Hi everybody, I've been reading the book "OpenGl Game Developing" by Chris Seddon and translating the code to c# with Tao and I'm running into some troubles in Chapter 2 so I wanted to know if somebody could help me out a bit :D.
When using the SimpleOpenglControl provided with the framework I had no problem (other than buggy graphics, but I believe that's because of the integrated video card), but when I try my own Initialization of OpenGL, It seems like it creates the contexts just fine but It won't draw in the Panel, so I believe it has something to do with the Raster class:
Excuse the use of spanish comments, they were too many to translate.
Ok, so In the form1 class I create an object of the Raster class, after the InitializeComponents() method has been called, I initialize some variables and call the Init(Control RenderTarget) method of the raster object giving it the panel(this instead of the SimpleOpenglControl InitializeContexts() Method).
Then I force a change in the form size to call an event that will set the viewport and the ortho projection(this is called every time the window resizes).
Finally in the Render method at the end I use the Gdi.SwapBuffers method giving it the DeviceContext from the raster object(Instead of the SimpleOpenGlControl SwapBuffers() method).
Thanks to anybody who read all of this XD, any help is appreciated.
[Edited by - crackers on February 19, 2008 10:00:15 AM]
Quote:
Why are you doing this ?
SimpleOpenGLControl works just fine.
What should a panel improve `?
I don't know what the panel would improve but I was using it because the SimpleOpenGLControl was giving me buggy graphics, but now I found what the problem was, I wasn't calling the Render Method at all XD, now it works fine with both the SimpleOpenGlControl and my implementation, except that when I resize the window it looks like I get too far away from the image or it becomes too small.
Before Resizing: http://link.imgshare.us/2hjG4L
After Resizing : http://link.imgshare.us/2hjGGz
PS: I also wanted to create my own implementation to get more control over the context creation and because I want to learn more about how OpenGL works
@crackers: Make sure you reset the projection matrix on each resize event.
@V-man: That was an unfortunate design decision (or lack of design) when Tao was first conceived. Alas, it's too late to fix now, too many applications depend on it (the clean break was done on OpenTK - see sig).
@V-man: That was an unfortunate design decision (or lack of design) when Tao was first conceived. Alas, it's too late to fix now, too many applications depend on it (the clean break was done on OpenTK - see sig).
I think I am doing that:
I'll try the OpenTK, thanks for the help
edit: Moving the code from ResizeGLWindow to the constructor gave me the problem right from the start, maybe the problem is in that method but I don't know what it is, my code in that method it's just like the book's code but the book's program works fine.
Thanks again
edit2: Yep the values from glOrtho were giving me troubles, although they do work in the book's example. The values that fixed it were:
Gl.glOrtho(-1, 1, -1, 1, -2000, 2000);
Thanks again for the help :D
PS:I just had one more question though. I started learning DirectX a few months ago and in some tutorials they said that you could loose control of the device and had to create a method to regain control of it, does that happens too in OpenGL?
[Edited by - crackers on February 19, 2008 10:42:53 AM]
private void ResizeGLWindow(int Width, int Height) { Gl.glViewport(0, 0, Width, Height); Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glLoadIdentity(); Gl.glOrtho(-200, 200, -200, 200, -2000, 2000); Gl.glMatrixMode(Gl.GL_MODELVIEW); }protected override void OnSizeChanged(EventArgs e) { //I change the panel's size to match the new window's size this.renderPanel.Width = (this.Width - Ancho - _separadorx); this.renderPanel.Height = (this.Height - menu.Height - _separadory); base.OnSizeChanged(e); //I call the method that sets the viewport ResizeGLWindow(this.renderPanel.Width, this.renderPanel.Height); }
I'll try the OpenTK, thanks for the help
edit: Moving the code from ResizeGLWindow to the constructor gave me the problem right from the start, maybe the problem is in that method but I don't know what it is, my code in that method it's just like the book's code but the book's program works fine.
Thanks again
edit2: Yep the values from glOrtho were giving me troubles, although they do work in the book's example. The values that fixed it were:
Gl.glOrtho(-1, 1, -1, 1, -2000, 2000);
Thanks again for the help :D
PS:I just had one more question though. I started learning DirectX a few months ago and in some tutorials they said that you could loose control of the device and had to create a method to regain control of it, does that happens too in OpenGL?
[Edited by - crackers on February 19, 2008 10:42:53 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement