PDA

View Full Version : Opengl with Dglopengl.pas



Lowercase
24-08-2007, 05:36 PM
that's probably a noob question...

I use a c++ style template (which use only api, no vcl, no TForm...), a basic style you can find on sulaco.co.za http://www.sulaco.co.za/opengl/template1.5.zip

I have tried to add a function to switch from windowed to fullscreen...

So I destroy current window and create a new one with the good parameters

I don't really understand why, but when I do this, I need to use initopengl function and read extensions every time I create a new window, I also need to reload all my textures (this may take some time).. If I don't do that I only have a blank screen, It seems i have lost the bind to opengl.dll

I have done something wrong ?

andygfx
24-08-2007, 10:27 PM
I used dglOpenGL for my engine Final3D, just now I rewrite him to SDL.

Here is my Viewport class for initializing Opengl viewport, work good in window and fullscreen mode too.




(************************************************* *****************************
Final3D® Engine 2005
support OpenGL 2.0
a3d.intelligentdevelopment.sk
kollar@intelligentdevelopment.sk

Commercial 3D Graphics/Game Engine

************************************************** ****************************
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
************************************************** ****************************)

unit F3D_Viewport_Class;

interface

uses
Windows,
Forms,
Classes,
SysUtils,
extCtrls,
controls,
dglOpenGL,
F3D_TYPES;

type
pF3D_Viewport = ^TF3D_Viewport;
TF3D_Viewport = class

private
FontBase: GLUInt;
StartTime: integer;
hWND: HWND;
bFinished: boolean;
procedure Init();
public
FDC: HDC;
FRC: HGLRC;

width: integer;
height: integer;
bRenderEnbale: Boolean;
constructor Create();
destructor Destroy; override;

procedure SetFullScreen(pWidth, pHeight, pBPP, pFrequency: Word);
procedure GLResize(w, h: integer);
procedure Flip;
procedure Clean;
procedure Clear(R, G, B, A: single);
procedure BeginRender3D();
procedure EndRender3D();

procedure BeginRender2D();
procedure EndRender2D();

procedure TextureEnabled(enable: boolean);
procedure DoubleFace(enable: boolean);
procedure DrawAsLine;
procedure DrawAsFace;
procedure CursorToCenter();
procedure DrawInfo(sx: integer; sy: integer);
procedure UseExtensions();

end;

implementation

uses f3dlib;

{************************************************* *****************************}
{ TF3D_Viewport - CREATE
{************************************************* *****************************}

constructor TF3D_Viewport.Create();

begin
inherited Create;
bFinished := false;

if (F3D.Config.r_fullscreen = true) then
begin
(F3D.FSender as TForm).Width := F3D.CONFIG.r_viewport_width;
(F3D.FSender as TForm).Height := F3D.CONFIG.r_viewport_height;
(F3D.FSender as TForm).Top := 0;
(F3D.FSender as TForm).left :=0;

(F3D.FSender as TForm).WindowState := wsMaximized;
(F3D.FSender as TForm).BorderStyle := bsNone;
(F3D.FSender as TForm).cursor := crNone;
end;

if (F3D.Config.r_fullscreen = false) then
begin

(F3D.FSender as TForm).Position := poScreenCenter;
(F3D.FSender as TForm).ClientWidth := F3D.CONFIG.r_viewport_width;
(F3D.FSender as TForm).ClientHeight := F3D.CONFIG.r_viewport_height;
end;

self.Init();
//clear
Clear(0.5, 0.5, 0.5, 1);
DoubleFace(false);

//swap GL buffer
Flip();
bFinished := true;

end;

{************************************************* *****************************}
{ TF3D_Viewport - ENABLE EXTENSIONS
{************************************************* *****************************}

procedure TF3D_Viewport.UseExtensions();
begin
dglOpengl.ReadExtensions;
dglOpengl.ReadImplementationProperties;

end;

procedure TF3D_Viewport.Init();
begin

FRC := 0;
FDC := 0;
width := F3D.Config.r_viewport_width;
height := F3D.Config.r_viewport_height;

if (F3D.CONFIG.r_fullscreen) then
begin
SetFullScreen(F3D.CONFIG.r_viewport_width,
F3D.CONFIG.r_viewport_height,
F3D.CONFIG.r_viewport_bpp,
F3D.CONFIG.r_viewport_depth);
end;

InitOpenGL;

hWND := (F3D.FSender as TForm).Handle;
FDC := GetDC(hWND);
FRC := CreateRenderingContext(FDC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
ActivateRenderingContext(FDC, FRC);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(F3D.CONFIG.r_viewport_fov, F3D.CONFIG.r_viewport_width / F3D.CONFIG.r_viewport_height, 0.1, F3D.Config.r_viewport_far);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDisable(GL_ALPHA_TEST);
glDisable(GL_FOG);
glDisable(GL_LIGHTING);
glDisable(GL_LOGIC_OP);
glDisable(GL_STENCIL_TEST);
glDisable(GL_TEXTURE_1D);
glShadeModel(GL_SMOOTH);
glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
glPixelTransferi(GL_RED_SCALE, 1);
glPixelTransferi(GL_RED_BIAS, 0);
glPixelTransferi(GL_GREEN_SCALE, 1);
glPixelTransferi(GL_GREEN_BIAS, 0);
glPixelTransferi(GL_BLUE_SCALE, 1);
glPixelTransferi(GL_BLUE_BIAS, 0);
glPixelTransferi(GL_ALPHA_SCALE, 1);
glPixelTransferi(GL_ALPHA_BIAS, 0);

glClearColor(0.5, 0.5, 0.5, 1.0);
glTranslatef(0, 0, -1);
glViewport(0, 0, F3D.CONFIG.r_viewport_width, F3D.CONFIG.r_viewport_height);

//3D screen properties

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glClearDepth(1);
glDepthRange(0, 1);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

end;

// ************************************************** ***************************
// F3D_Viewport: Fullscreen
// ************************************************** ***************************

procedure TF3D_Viewport.SetFullScreen(pWidth, pHeight, pBPP, pFrequency: Word);
var
dmScreenSettings: DevMode;
begin

ZeroMemory(@dmScreenSettings, SizeOf(dmScreenSettings));
with dmScreenSettings do
begin
dmSize := SizeOf(dmScreenSettings);
dmPelsWidth := pWidth;
dmPelsHeight := pHeight;
dmBitsPerPel := pBPP;
dmDisplayFrequency := pFrequency;
dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFREQUENCY;
end;
if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) = DISP_CHANGE_FAILED) then
begin
MessageBox(0, 'Fullscreen is not active!', 'Error', MB_OK or MB_ICONERROR);
exit
end;
end;

{************************************************* *****************************}
{ TF3D_Viewport - FLIP
{************************************************* *****************************}

procedure TF3D_Viewport.Flip;
begin
glFinish();
glFlush();
SwapBuffers(wglGetCurrentDC());
end;

{************************************************* *****************************}
{ TF3D_Viewport - DESTROY
{************************************************* *****************************}

procedure TF3D_Viewport.Clean;
begin

DeactivateRenderingContext;
wglDeleteContext(FRC);
ReleaseDC(hWnd, FDC);
ChangeDisplaySettings(devmode(nil^), 0);

end;

{************************************************* *****************************}
{ TF3D_Viewport - DESTROY
{************************************************* *****************************}

procedure TF3D_Viewport.GLResize(w, h: integer);
begin

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(F3D.CONFIG.r_viewport_fov, F3D.CONFIG.r_viewport_width / F3D.CONFIG.r_viewport_height, 0.1, 10000);
glMatrixMode(GL_MODELVIEW);

end;

{************************************************* *****************************}
{ TF3D_Viewport - DESTROY OpenGL Render Context
{************************************************* *****************************}

destructor TF3D_Viewport.Destroy;
begin
Clean();
inherited Destroy;
end;

{************************************************* *****************************}
{ TF3D_Viewport - CLEAR with current color
{************************************************* *****************************}

procedure TF3D_Viewport.Clear(R, G, B, A: single);
begin
glClearColor(R, G, B, A);
end;

{************************************************* *****************************}
{ TF3D_Viewport: Begin Render 3D content
{************************************************* *****************************}

procedure TF3D_Viewport.BeginRender3D();
var
time : integer;
begin

glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT);

end;

{************************************************* *****************************}
{ TF3D_Viewport: End render 3D content
{************************************************* *****************************}

procedure TF3D_Viewport.EndRender3D();
begin
//F3D.Textures.ResetTextureLayers();
end;

{************************************************* *****************************}
{ TF3D_Viewport: BEGIN RENDER 2D CONTENT
{************************************************* *****************************}

procedure TF3D_Viewport.BeginRender2D();
begin

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, F3D.CONFIG.r_viewport_width, F3D.CONFIG.r_viewport_height, 0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

F3D.Textures.InActiveLayers();
F3D.Textures.ActivateLayer(0);

end;

{************************************************* *****************************}
{ TF3D_Viewport: END RENDER 2D CONTENT
{************************************************* *****************************}

procedure TF3D_Viewport.EndRender2D();
begin

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);

end;

{************************************************* *****************************}
{ TF3D_Viewport: TEXTURE ON/OFF
{************************************************* *****************************}

procedure TF3D_Viewport.TextureEnabled(enable: boolean);
begin
if enable then
glEnable(GL_TEXTURE_2D)
else
glDisable(GL_TEXTURE_2D);
end;

{************************************************* *****************************}
{ TF3D_Viewport: Move Cursor to center of screen
{************************************************* *****************************}

procedure TF3D_Viewport.CursorToCenter();
begin
SetCursorPos(screen.width div 2, screen.height div 2);
end;

{************************************************* *****************************}
{ TF3D_Viewport: CULLING ON/OFF
{************************************************* *****************************}

procedure TF3D_Viewport.DoubleFace(enable: boolean);
begin
if not enable then
begin
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
end
else
glDisable(GL_CULL_FACE);

end;

{************************************************* *****************************}
{ TF3D_Viewport: WIREFRAME RENDER MODE
{************************************************* *****************************}

procedure TF3D_Viewport.DrawAsLine();
begin
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

end;

{************************************************* *****************************}
{ TF3D_Viewport: FLAT RENDER MODE
{************************************************* *****************************}

procedure TF3D_Viewport.DrawAsFace();
begin
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

end;

procedure TF3D_Viewport.DrawInfo(sx: integer; sy: integer);
var
font : string;
begin
if (not F3D.Config.use_infoscreen) then exit;

glDisable(GL_TEXTURE_2D);
font := 'CourierNew';

glEnable(GL_BLEND);
glColor4f(0, 0, 0, 0.3);
F3D.Draw.Rectangle(sx - 8, sy - 4, sx + 256 + 16, sy + 72);

glDisable(GL_BLEND);
F3D.Hud.SetFontColor(font, SetColor4f(1, 0.5, 0, 1));
F3D.Hud.Print(font, sx, sy + 13 * 0, 'FRAMERATE:');
F3D.Hud.SetFontColor(font, SetColor4f(1, 1, 1, 1));
F3D.Hud.Print(font, sx, sy + 13 * 1, 'FPS : ' + IntToStr(F3D.Timer.FrameRate));
F3D.Hud.Print(font, sx, sy + 13 * 2, 'Frame count : ' + IntToStr(F3D.Timer.FrameCount));
F3D.Hud.Print(font, sx, sy + 13 * 3, 'Frame Lag : ' + FloatToStr(F3D.Timer.DeltaTime));
F3D.Hud.Print(font, sx, sy + 13 * 4, 'Frame Elapsed: ' + FloatToStr(F3D.Timer.ElapsedTime));

end;

end.
[/pascal]

Sascha Willems
25-08-2007, 12:27 PM
If you destroy a window you loose it's device context. And since the rendering context of OpenGL is attached to that device context you loose all pointers to your OpenGL functions as well as all objects and namespaces (textures, display lists, shaders, etc.).

Since this is a limitation of the windows API there is no way around this. If you destroy your window (and your DC get's lost) you need to reinitialize OpenGL as you also loose your RC.

Lowercase
25-08-2007, 05:01 PM
Thanks for the info !

So if I don't release the DC when i switch to fullscreen, can I asign it to another window ?

Or is there a simple way to share it ?

Chebmaster
26-08-2007, 07:50 AM
AFAIK, DC is assigned by Windows. You have no control over it.

I did not find any reliable way to switch between window and fullscreen without restarting. Theoretically you can just change your window properties and it works... sometimes. But doesn't work other times. It depends on a multitude of factors.

So, if you don't want a huge headache with debugging and lots of user complaints, use the sure way. I.e. Re-create your window, restart OpenGL and reload all textures every time you switch between fullscreen and windowed.

tpascal
26-08-2007, 05:24 PM
Re-create your window, restart OpenGL and reload all textures every time you switch between fullscreen and windowed.


That's right, every decent 3d app must have to include a rutine to re-create rendering resources not just when it switch from full to windowed mode or back but for also handle the so called "device lost"; which is somthign you should always check and handle in your app.