PDA

View Full Version : OpenGL & .Net Forms



Cacks
10-15-2005, 04:53 AM
Hi Guys,

I want to create am OpenGL app using VC++ .Net forms not MFC. I can create the rendering context fine but can get it to display on the form. Any1 know how to do this?

Thanks for any help given.

Hlz
10-17-2005, 12:42 AM
Seems like there ought to be some frameworks out there to simplify this, though I don't think this site has any links yet. Have you tried a search?

ppeterson
10-17-2005, 01:19 AM
I assume here that you're doing your drawing in the OnPaint method. After you've created your rendering context, did you make it current (with wglMakeCurrent)? And after you're done drawing, did you swap your buffers (with wglSwapBuffers; assuming your using double buffering)?

(By the way, when you get things working maybe you should consider making a re-usable OpenGL control rather than rendering directly on your form.)

Cacks
10-17-2005, 08:33 AM
Hi ppeterson,

I have it rendering now kind of. I have to press a button to activate rendering then swapping of buffers in a loop. What is the best way by means of using an event to trigger rerendering of my OpenGL scence? Do forms have a main method?

Thanks!

ppeterson
10-18-2005, 12:36 AM
You can override the OnPaint method of the form or create an event handler for the Paint event. Whenever your form is invalidated, for instance because it has been resized or it has been activated after being covered by another window, these methods will be called so you can do your drawing. You can also invalidate the form yourself (by calling MyForm.Refresh()) when you want the scene to be updated, for example when you've recieved mouse input from the user and you've used this to change the viewpoint on your scene.

However, this method of rendering a scene only when the OS or user input requires you to, may not be what you after. Perhaps you want to render your scene as many times as possible (in order to get a high framerate), like it's usually done in games.

In this case you'll have to force a redraw of the scene from within the message loop. In .NET this message loop is not as easily accessable as before. I don't know if it is the only or even the best way to break into the message loop, but you'll have to check out the interface IMessageFilter.

ToniS
10-19-2005, 03:41 PM
Hi Cacks,
in my humble opinion, the easiest way of setting up a constant frame rate with Win Forms is creating a Timer event.
You do this by drag & dropping a Timer from the Toolbox into your form. The Toolbox is normaly shown on the left-hand side of the Visual Studio.
After that you can set up in the properties of your timer in witch ineraval the timer is being called.
In the Timer Method you invalidate your form. Invalidating your form causes the Paint method to run, in witch you do your drawing and swap the buffers and so on.

Hope this was helpfully
Toni

Cacks
10-21-2005, 04:33 AM
Hi Tori,

I tried what you said. But for each tick event I rerender the scene, not invalidating the form. Do you know how to set ticks per second?

Thanks for the help!!

Soth
10-21-2005, 05:06 AM
Anyone knows what are the perfomance costs of using OpenGL and Windows Forms?

And by the way is there any difference between using wrappers and calling OpenGL commands right from managed classes?

That`s how I do:

#pragma once

#include <windows.h>
#include "containers.cpp"
#include "GLNurbs.h"
#include "Examples.h"
#include "GLTools.h"

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

CGLEntity *glE;

.
.
.
. //Standart WinForm stuff
.
.
.
.

private: System::Void MainForm_Load(System::Object * sender, System::EventArgs * e)
{
void *p=Handle.ToPointer();
HWND hwnd=static_cast<HWND>(p);
HDC hdc=GetDC(hwnd);
glE=new CGLEntity(hdc);//setting gl context here


glClearColor(0,0,0,1);
glViewport(0,0,Width,Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10.0,10.0,-10.0,10.0,-10.0,10.0);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);



}

private: System::Void MainForm_Paint(System::Object * sender, System::Windows::Forms::PaintEventArgs * e)
{
SampleSurfaceWithDers();
glE->SwapBuffer();

}



private: System::Void MainForm_Resize(System::Object * sender, System::EventArgs * e)
{
glClearColor(0,0,0,1);
glViewport(0,0,Width,Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10.0,10.0,-10.0,10.0,-10.0,10.0);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);

}

ToniS
10-25-2005, 03:55 AM
@Cacks:
A Timer event hast the property Interval. You can set it up in the property page of your Timer (normally on the lower right-hand side of VS .NET).
Interval specifys how often the Timer ticks in milliseconds. For example, if you set the Interval to 20, the tick method is called every 20 milliseconds, which means 50 times per second (hope i calculated this correctly :D ).

Greetz
Toni

ppeterson
10-25-2005, 10:40 PM
Although this discussion is getter less and less to do with OpenGL and more and more Windows-specific, I'll try to keep this as related this forum as possible.

Firstly, a timer is not very reliable. The interval you request may not be the actual interval you get. Secondly, you typically want a frame rate that is as high as possible. This really requires you to use the message loop as the driving force.

As for Soth's question about performance cost when using OpenGL under .NET: there is an inevitable cost which is probably quite noticable in applications like games.
My advise: if your project requires you to use .NET, don't let it discourage you to use OpenGL; if your choice of programming langage is free and you want to use OpenGL (which goes without saying, of course ;) ), avoid using .NET.