Skip to main content
gamedev.net
🔒 Locked

OpenGL init

Started by James Sioutis 16 replies 1.3k views
Original Post
James Sioutis
James Sioutis
I was just wondering is there any proper way to optimally initialize opengl? For instance, with Direct3D, in order to initialize it you have to use about 30 pages of code and all these classes in order to enumerate the devices and stuff like that, but with OpenGL, you just have to fill in the PIXELFORMATDESCRIPTOR thing and type less then a page of code. And also ive noticed that on my comp D3D runs about 80 FPS faster than OpenGL does. So is there any proper way that you should initialize it in order to get max performance?? ~aussie [edited by - James Sioutis on April 28, 2004 5:20:17 AM]
[~aussie]
supagu
supagu
hrmm i have developed applications using d3d, then moved to ogl recently, i have used the same engine architecture and with d3d9 could only push 60k polys with about 80fps, but with ogl i can do 70k polys at around 120fps, so i think fps differences are more due to what the developer has put more effort into developing.... i just find opengl natually easier/faster for my engine architecture.

as for initilisation, i wouldnt know, i let SDL do it for me.
CProgrammer
CProgrammer
quote:

For instance, with Direct3D, in order to initialize it you have to use about 30 pages of code and all these classes in order to enumerate the devices and stuff like that


Ahm, I like OpenGL and DirectX. But I''m just wondering what DirectX version you last used? Cause since DX8 initialisation is not a big deal at all. Maybe still more then OpenGL but not much.
-CProgrammer

James Sioutis
James Sioutis
well now Im using dx9, i just moved to it from OpenGL a couple of months ago and was surprised to see how much code it took to initialize it.

[edited by - James Sioutis on April 28, 2004 11:35:44 AM]
[~aussie]
_the_phantom_
_the_phantom_
For OpenGL init i took the weekend to write a window manager, window manager, OGL and Display device caps enumerator. Took me about 24h to write and get the bugs out, once i''ve cleaned the interface up a bit and added one or two things i''ll probably release the code/lib for general consumption
(it has GLee intergrated into it, so i dont even have to worry about setting up OpenGL, just create the manager, init it and use OpenGL calls to my hearts content)
James Sioutis
James Sioutis
@_the_phantom_: that sounds pretty tight if you could release that, but what im curious is, how exactly do you enumerate the devices with OGL? because (to my knowledge) it doesnt have any functions and stuff to do it like D3D does. Are there any wiggle functions or something in GLut that could take care of this??

~aussie
[~aussie]
Tachikoma
Tachikoma
In Windows I use EnumDisplaySettings() and ChangeDisplaySettings() enumerate different display modes. Is this what you mean?

Puzzler183
Puzzler183
There isn''t as far as I know. I just let GLUT do it for me and my code is like 30-50 lines for a minimal program with input.
_the_phantom_
_the_phantom_
quote:
Original post by Tachikoma
In Windows I use EnumDisplaySettings() and ChangeDisplaySettings() enumerate different display modes. Is this what you mean?



yeah, thats what i''m using, the idea is that, when i get a chance to get a linux box working, i''ll build a linux version of the code to do the same jobs and hopefully remove some X-platform dev woes
(interface to the windows stays the same via the manager, but the rest of it is designed to be chunked around and changed at will, not quite platform independant, but close enuff )

After some fiddling last night my test up as it making two windows and drawing the same content to both (added a function to share textures/display list/etc between two windows), however due to the issue with bufferswapping and v-sync its currently halfing the frame rate

Currently i''m working on dialog to allow mode selection then i''ll hopefully be able to shove out a demo of a windows binary this weekend, source to follow some time next week (work and other factors permitting, for a change i''ve a busy social life this weekend, hehe).

If i can swing a second monitor for a while i might try and get dual monitor support going as well (its about the only thing we dont have spare in the house... *mutters*)

James Sioutis
James Sioutis
quote:
Original post by Tachikoma
In Windows I use EnumDisplaySettings() and ChangeDisplaySettings() enumerate different display modes. Is this what you mean?




i already knew about the ChangeDisplaySettings, i had never even heard about EnumDisplaySettings though, i just looked through the MSVC++ docs and found the EnumDisplaySettings and EnumDisplayDevices, so could you just use them in like a big loop to determine what display modes the device supports and pick the best one??

~aussie
[~aussie]
Tachikoma
Tachikoma
This chunk of code is ripped straight out of my 3D Engine. Basically, it enumerates all the video modes available, and stores them into an array for structs, called ModeList .



//Define the field mask

uint32 Mask = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;

//Enumerate all the video modes

DEVMODE DeviceMode;
for (int I = ModeCount = 0; (EnumDisplaySettings(NULL, I, &DeviceMode) != 0); I++)
{
//Break loop when the video mode list is filled up

if (ModeCount >= VID_MAX_MODECOUNT)
{fprintf(stderr, "GL_Video::EnumVideoMode( ): WARNING: The number of video modes exceed the maximum array size: %d.\n", VID_MAX_MODECOUNT); break;}

//Include video modes that have all the desired fields available

if ((DeviceMode.dmFields & Mask) == Mask)
{
//Test if the mode can be set

if (ChangeDisplaySettings(&DeviceMode, CDS_TEST | CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
{
ModeList[ModeCount].Res.X = DeviceMode.dmPelsWidth;
ModeList[ModeCount].Res.Y = DeviceMode.dmPelsHeight;
ModeList[ModeCount].BitsPerPixel = DeviceMode.dmBitsPerPel;
ModeList[ModeCount].RefreshRate = DeviceMode.dmDisplayFrequency;


ModeCount++;
}
}
}

//Exit with error if no video modes are available

if (ModeCount == 0)
{fprintf(stderr, "GL_Video::EnumVideoMode( ): No video mode was available for enumerating.\n"); return false;}

return true;



I never tried EnumDisplayDevices() though. I guess you could do something similar what I did with EnumDisplaySettings().

[edited by - Tachikoma on April 30, 2004 4:20:33 AM]
James Sioutis
James Sioutis
@Tachikoma: thats all you really need to do to enumerate it? that looks pretty simple i was expecting to write like 10 pages or something like D3D.
But also how would you change the presentation interval when you''re storing the display modes and stuff? The main problem i have is that OpenGL always seems to completely freeze/crash the system whenever i move the mouse over the window, i know that the display driver has a bug in it and is ultimately causing the problem, but its by S3 and ive asked them hundreds of times with no reply. What ive noticed with D3D is though, when i change the presentation interval from ''immediate'' to ''one'', the mouse doesnt flicker at all, so i was thinking that might stop OpenGL from f*cking up with the mouse all the time.



~aussie

"one of these days im going to cut you into little pieces!!" - Pink Floyd
[~aussie]
Tachikoma
Tachikoma
quote:
thats all you really need to do to enumerate it?

That''s practically it.

- First you enumerate the available modes for the current display;
- Use ChangeDisplaySettings() to change a desired display resolution;
- Create a new window with CreateWindowEx() function;
- Use ChoosePixelFormat() and SetPixelFormat() to setup buffers for OpenGL rendering.
- Use wglCreateContext() and wglMakeCurrent() to create an OpenGL rendering context for the window you just created.

This how I setup the PIXELFORMATDESCRIPTOR structure:

//Setup the pixel format descriptor

PIXELFORMATDESCRIPTOR PixFormatDesc;
memset(&PixFormatDesc, 0, sizeof(PIXELFORMATDESCRIPTOR));
PixFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); //Size of this descriptor

PixFormatDesc.nVersion = 1; //Version number

PixFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | //Support window

PFD_SUPPORT_OPENGL | //Support OpenGL

PFD_DOUBLEBUFFER | //Double buffered

PFD_SWAP_EXCHANGE; //Exchange buffers instead of copying

PixFormatDesc.iPixelType = PFD_TYPE_RGBA; //RGBA type

PixFormatDesc.cColorBits = Mode.BitsPerPixel; //Color depth

PixFormatDesc.cRedBits = 0; //R, G, B Color bits ignored

PixFormatDesc.cRedShift = 0;
PixFormatDesc.cGreenBits = 0;
PixFormatDesc.cGreenShift = 0;
PixFormatDesc.cBlueBits = 0;
PixFormatDesc.cBlueShift = 0;
PixFormatDesc.cAlphaBits = 0; //No alpha buffer

PixFormatDesc.cAlphaShift = 0; //Shift bit ignored

PixFormatDesc.cAccumBits = 0; //Accumulator bits ignored

PixFormatDesc.cAccumRedBits = 0;
PixFormatDesc.cAccumGreenBits = 0;
PixFormatDesc.cAccumBlueBits = 0;
PixFormatDesc.cAccumAlphaBits = 0;
PixFormatDesc.cDepthBits = BitsPerZ; //BitsPerZ is a variable that can be either 16 or 32-bit for Z-buffer

PixFormatDesc.cStencilBits = 0; //No stencil buffer

PixFormatDesc.cAuxBuffers = 0; //No auxiliary buffer

PixFormatDesc.iLayerType = PFD_MAIN_PLANE; //Main layer

PixFormatDesc.bReserved = 0; //Reserved

PixFormatDesc.dwLayerMask = 0; //Layer masks ignored

PixFormatDesc.dwVisibleMask = 0;
PixFormatDesc.dwDamageMask = 0;


quote:
But also how would you change the presentation interval when you''re storing the display modes and stuff?

I''m not sure about what you mean by "presentation interval".

quote:
The main problem i have is that OpenGL always seems to completely freeze/crash the system whenever i move the mouse over the window

Make sure you have the Win32 event handler setup correctly - i.e.. use PeekMessage() to get windows events and handle them accordingly.
James Sioutis
James Sioutis
by presentation interval i mean the rate at which the frame buffer is presented to the screen with respect to the electron gun.
If you have an immediate presentation interval, for example, then the device will immediately copy the buffer to the screen, regardless of the position of the electron gun, which can cause tearing and other stuff.
If you have a presentation interval 'one' then it waits until the electron gun has finished repainting the screen and while the gun is doing the vertical retrace (moving from the end of the screen to start again) and it copies the data over then which eliminates tearing and in my case might stop OpenGL from being a jackass and freezing the system.

oh and yeah i use PeekMessage() in the main loop in WinMain:


for (;;)
{
if (PeekMessage(...))
{
some stuff
}

Render()
}





~aussie

"one of these days im going to cut you into little pieces!!" - Pink Floyd

[edited by - James Sioutis on May 1, 2004 2:50:16 AM]

[edited by - James Sioutis on May 1, 2004 2:52:14 AM]
[~aussie]
Tachikoma
Tachikoma
Be sure to use TranslateMessage() and DispatchMessage() for unhandled Win32 events:


MSG ThreadMsg;
if (PeekMessage(&ThreadMsg, WinHandle, 0, 0, PM_REMOVE))
{
switch (ThreadMsg.message)
{
//Quit message

case WM_QUIT:
case WM_CLOSE:
case WM_DESTROY:
case WM_NCDESTROY:
//Do stuff to shutdown, etc.

break;

//Other messages

default:
TranslateMessage(&ThreadMsg);
DispatchMessage(&ThreadMsg);
break;
}
}


Regarding presentation interval... ah, you mean V-Syncing - i.e.. Vertical Retrace Synchronisation. You can change the refresh rate of the video mode by using the ChangeDisplaySettings() function. For example:


DEVMODE DeviceMode;
//Setup the device mode parameters

memset(&DeviceMode, 0, sizeof(DeviceMode));
DeviceMode.dmSize = sizeof(DEVMODE);
DeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
DeviceMode.dmPelsWidth = Res.X;
DeviceMode.dmPelsHeight = Res.Y;
DeviceMode.dmBitsPerPel = BitsPerPixel;
DeviceMode.dmDisplayFrequency = RefreshRate;

//Change the video mode

ChangeDisplaySettings(&DeviceMode, CDS_FULLSCREEN);
James Sioutis
James Sioutis
well i already have the refresh rate at 60hz but what i meant to say last time was how would you let the device know not to flip/copy the buffer until after the electron gun has finished its vertical retrace. So the device will essentially wait until the electron gun has finished painting before sending out the new buffer.

I looked around in MSVC++ docs and couldnt find anything but this is what it said about presentation interval in the D3D9 SDK:

quote:

D3DPRESENT_INTERVAL_ONE:
The driver will wait for the vertical retrace period (the runtime will "beam follow" to prevent tearing). IDirect3DDevice9:: Present operations will not be affected more frequently than the screen refresh; the runtime will complete at most one IDirect3DDevice9:: Present operation per adapter refresh period. This is equivalent to using D3DSWAPEFFECT_COPYVSYNC in Microsoft® DirectX® 8.1. This option is always available for both windowed and full-screen swap chains.



now i just need to know how to do this ^^ in OpenGL. If anyone knows thanks ALOT in advance...



~aussie

"one of these days im going to cut you into little pieces!!" - Pink Floyd

[edited by - James Sioutis on May 2, 2004 4:09:40 AM]
[~aussie]
Tachikoma
Tachikoma
There is a WGL_EXT_swap_control extension that allows you to use the wglSwapIntervalEXT() function. I never used it myself though.

http://www.3dlabs.com/support/developer/WGLmanpages/wglswapintervalext.htm

That said, you should be able to enable/disable v-syncing through your video card driver settings.
James Sioutis
James Sioutis
well i dont have that extension on my (very shitty) video card and i have OpenGL 1.1 so would any later versions of OpenGL support the presentation interval stuff in the core?



~aussie

"one of these days im going to cut you into little pieces!!" - Pink Floyd
[~aussie]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.