Win32/OpenGL antialiasing

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
GnarlyHotep
Posts: 10
Joined: Tue Aug 14, 2007 6:35 pm

Win32/OpenGL antialiasing

Post by GnarlyHotep »

I have the code for OpenGL Win32 antialiasing that I've been using for some time. It's a drop-in replacement for COpenGLDriver::initDriver in the Win32 section of COpenGLDriver.cpp, and it's 170 lines long. What's the prefered way to post a snippet that long? Do I put it inside code brackets in a message, or should I post it somewhere and provide a link? I don't think I can attach a snippet to a message in these forums.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You can upload it to the Patch tracker on the SourceForge project page. Or mail it to me directly, you can find my mail adresse on my webpage.
sgt_pinky
Posts: 149
Joined: Sat Oct 14, 2006 11:20 am
Location: Melbourne, Australia

Post by sgt_pinky »

Regardless of submitting it to the patch tracker can you please post it here too in code tags. I think a lot of people would benefit from that.

Regards,

Pinky
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
GnarlyHotep
Posts: 10
Joined: Tue Aug 14, 2007 6:35 pm

Win32 OpenGL antialias code snippet

Post by GnarlyHotep »

Okay, here's the code. It's grown a bit as I added some appropriate error handling. I'm trying to get it cleaned up for submission to Irrlicht 1.4 or later, but my main problem is testing it on lower-end cards. I don't have access to any. So, if anyone out there with a lower-end card could test this code, I'd appreciate it.

This snippet replaces COpenGLDriver::initDriver() in the _IRR_USE_WINDOWS_DEVICE_ section of COpenGLDriver.cpp (at about line 50).

Code: Select all

// --- BEGIN:
// Code taken from wglext.h  Uncomment the following lines if you do not include
// wglext.h in this file.
//typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
//
//#define WGL_DRAW_TO_WINDOW_ARB         0x2001
//#define WGL_SUPPORT_OPENGL_ARB         0x2010
//#define WGL_ACCELERATION_ARB           0x2003
//#define WGL_FULL_ACCELERATION_ARB      0x2027
//#define WGL_COLOR_BITS_ARB             0x2014
//#define WGL_ALPHA_BITS_ARB             0x201B
//#define WGL_DEPTH_BITS_ARB             0x2022
//#define WGL_STENCIL_BITS_ARB           0x2023
//#define WGL_DOUBLE_BUFFER_ARB          0x2011
//
//#define WGL_SAMPLE_BUFFERS_ARB         0x2041
//#define WGL_SAMPLES_ARB                0x2042
// --- END: code taken from wglext.h

//! inits the open gl driver
bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
				HWND window, u32 bits, bool fullscreen, bool vsync, bool stencilBuffer)
{
    // Set up the pixel format descriptor with the desired parameters:
    static	PIXELFORMATDESCRIPTOR pfd =	{
        sizeof(PIXELFORMATDESCRIPTOR),	// Size Of This Pixel Format Descriptor
        1,				// Version Number
        PFD_DRAW_TO_WINDOW |		// Format Must Support Window
        PFD_SUPPORT_OPENGL |		// Format Must Support OpenGL
        PFD_DOUBLEBUFFER,		// Must Support Double Buffering
        PFD_TYPE_RGBA,			// Request An RGBA Format
        bits,				// Select Our Color Depth
        0, 0, 0, 0, 0, 0,		// Color Bits Ignored
        0,				// No Alpha Buffer
        0,				// Shift Bit Ignored
        0,				// No Accumulation Buffer
        0, 0, 0, 0,			// Accumulation Bits Ignored
        24,				// Z-Buffer (Depth Buffer)
        stencilBuffer ? 1 : 0,		// Stencil Buffer Depth
        0,				// No Auxiliary Buffer
        PFD_MAIN_PLANE,			// Main Drawing Layer
        0,				// Reserved
        0, 0, 0				// Layer Masks Ignored
    };

    // Attempt to get a valid PixelFormat:
    s32 PixelFormat;

    if(AntiAlias)
    {
        // Create a window to test antialiasing support
        const c8* ClassName = "GLCIrrDeviceWin32";
        HINSTANCE lhInstance = GetModuleHandle(0);

        // Register Class
        WNDCLASSEX wcex;
        wcex.cbSize		    = sizeof(WNDCLASSEX);
        wcex.style		    = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc	= (WNDPROC)DefWindowProc;
        wcex.cbClsExtra		= 0;
        wcex.cbWndExtra		= 0;
        wcex.hInstance		= lhInstance;
        wcex.hIcon		    = NULL;
        wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName	= 0;
        wcex.lpszClassName	= ClassName;
        wcex.hIconSm		= 0;
        wcex.hIcon          = 0;

        RegisterClassEx(&wcex);
        RECT clientSize;
        clientSize.top = 0;
        clientSize.left = 0;
        clientSize.right = screenSize.Width;
        clientSize.bottom = screenSize.Height;

        DWORD style = WS_POPUP;

        if (!fullscreen)
            style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

        AdjustWindowRect(&clientSize, style, FALSE);

        s32 realWidth = clientSize.right - clientSize.left;
        s32 realHeight = clientSize.bottom - clientSize.top;

        s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
        s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;

        HWND temporary_wnd=CreateWindow( ClassName, "", style, windowLeft, windowTop,
                realWidth, realHeight,	NULL, NULL, lhInstance, NULL);

        if(!temporary_wnd)
        {
            os::Printer::log("Cannot create a temporary window.", ELL_ERROR);
            return false;
        }

        HDc = GetDC(temporary_wnd);
        PixelFormat = ChoosePixelFormat(HDc, &pfd);
        if(!PixelFormat)
        {
            // Disable the stencil bits?
            stencilBuffer=false;
            pfd.cStencilBits=0;
            PixelFormat = ChoosePixelFormat(HDc, &pfd);
            if(!PixelFormat)
            {
                // Reduce the bit depth?
                bits=24;
                pfd.cDepthBits=24;
                PixelFormat = ChoosePixelFormat(HDc, &pfd);
                if(!PixelFormat)
                {
                    // Reduce the bit depth again?
                    bits=16;
                    pfd.cDepthBits=16;
                    PixelFormat = ChoosePixelFormat(HDc, &pfd);
                    if(!PixelFormat)
                    {
                        // Give up!  We can not find an acceptable format!
                        os::Printer::log("Cannot find a temporary pixel format.", ELL_ERROR);
                        ReleaseDC(temporary_wnd, HDc);
                        DestroyWindow(temporary_wnd);
                        return false;
                    }
                }
            }
        }

        SetPixelFormat(HDc, PixelFormat, &pfd);
        HRc=wglCreateContext(HDc);
        if(!HRc)
        {
            os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR);
            ReleaseDC(temporary_wnd, HDc);
            DestroyWindow(temporary_wnd);
            return false;
        }

        if(!wglMakeCurrent(HDc, HRc))
        {
            os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR);
            wglDeleteContext(HRc);
            ReleaseDC(temporary_wnd, HDc);
            DestroyWindow(temporary_wnd);
            return false;
        }

        PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
        if(wglChoosePixelFormat_ARB)
        {
            // This value determines the number of samples used for antialiasing
            // valid numbers are 2, 4, 8.  My experience is that 8 does not
            // show a big improvement over 4, but 4 shows a big improvement over
            // 2.
            const s32 numSamples = 4;
            f32 fAttributes[] =
            {
                0.0, 0.0
            };

            s32 iAttributes[] =
            {
                WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
                WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
                WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
                WGL_COLOR_BITS_ARB,(bits==32) ? 24 : 15,
                WGL_ALPHA_BITS_ARB,(bits==32) ? 8 : 1,
                WGL_DEPTH_BITS_ARB,(bits==32) ? 24 : 16,
                WGL_STENCIL_BITS_ARB,(stencilBuffer) ? 1 : 0,
                WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
                WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
                WGL_SAMPLES_ARB,numSamples,
                0,0
            };
            s32 pixelFormat=0, valid=0;
            u32 numFormats=0;
            s32 rv=0;

            // Try to get an acceptable pixel format
            while(rv==0 && iAttributes[19]>1)
            {
                valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);

                if(valid && numFormats>0)
                {
                    rv = pixelFormat;
                }
                else
                {
                    iAttributes[19] >>= 1;
                }
            }
            if(rv) PixelFormat=rv;
        }

        wglMakeCurrent(HDc, NULL);
        wglDeleteContext(HRc);
        ReleaseDC(temporary_wnd, HDc);
        DestroyWindow(temporary_wnd);

        if (!(HDc=GetDC(window)))
        {
            os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
            return false;
        }
    }
    else
    {
        HDc = GetDC(window);
        PixelFormat = ChoosePixelFormat(HDc, &pfd);
        if(!PixelFormat)
        {
            // Disable the stencil bits?
            stencilBuffer=false;
            pfd.cStencilBits=0;
            PixelFormat = ChoosePixelFormat(HDc, &pfd);
            if(!PixelFormat)
            {
                // Reduce the bit depth?
                pfd.cDepthBits=24;
                PixelFormat = ChoosePixelFormat(HDc, &pfd);
                if(!PixelFormat)
                {
                    // Reduce the bit depth again?
                    pfd.cDepthBits=16;
                    PixelFormat = ChoosePixelFormat(HDc, &pfd);
                    if(!PixelFormat)
                    {
                        // Give up!  We can not find an acceptable format!
                        os::Printer::log("Cannot find a temporary pixel format.", ELL_ERROR);
                        return false;
                    }
                }
            }
        }
    }

    // Set pixel format on real window
    if(!SetPixelFormat(HDc, PixelFormat, &pfd))
    {
        os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
        return false;
    }

    // create rendering context
    if (!(HRc=wglCreateContext(HDc)))
    {
        os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR);
        return false;
    }

    // activate rendering context
    if(!wglMakeCurrent(HDc, HRc))
    {
        wglDeleteContext(HRc);
        os::Printer::log("Cannot activate GL rendering context", ELL_ERROR);
        return false;
    }

	genericDriverInit(screenSize, stencilBuffer);

	// set vsync
	if (wglSwapIntervalEXT)
		wglSwapIntervalEXT(vsync ? 1 : 0);

	// set exposed data
	ExposedData.OpenGLWin32.HDc = reinterpret_cast<s32>(HDc);
	ExposedData.OpenGLWin32.HRc = reinterpret_cast<s32>(HRc);
	ExposedData.OpenGLWin32.HWnd = reinterpret_cast<s32>(Window);

    return true;
}
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

If you'll compile and and give a link I'll be more then happy to test it on two (GeForce 2, Radeon 9200) low-end graphic cards and even more (my friends's cards).
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

I know this post is old but maybe it can still be used? Can it add AA in OpenGL in Windows?
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, the init code didn't change recently, so it should still work without major hassle. Unfortunately, the original author became very quiet very fast. Too bad. But once we intensivy the win32 work more again it should also go into the library...
Dorth
Posts: 931
Joined: Sat May 26, 2007 11:03 pm

Post by Dorth »

It works 99% out of the box with Irrlicht SVN. All you need to do is add the wglext.h to the header and that's it. ^^
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

Dorth wrote:It works 99% out of the box with Irrlicht SVN. All you need to do is add the wglext.h to the header and that's it. ^^
So how about doing us all a big favor and provide a patch? :wink:
Me and many others would like that feature ASAP.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Dorth
Posts: 931
Joined: Sat May 26, 2007 11:03 pm

Post by Dorth »

Why not do it yourself?
Anyway, I was thinking about putting a patch but I'll fix the Draw2dImage on OpenGL first which does not do -0.5f on the texture coordinates, leaving a slight border of whatever's around. But honestly MasterGod, if you want it so bad, do it yourself and put the patch. The fix is already here. Stop depending on others so much.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

Dorth wrote:Why not do it yourself?
Anyway, I was thinking about putting a patch but I'll fix the Draw2dImage on OpenGL first which does not do -0.5f on the texture coordinates, leaving a slight border of whatever's around. But honestly MasterGod, if you want it so bad, do it yourself and put the patch. The fix is already here.
Wooho..Chill out man.
If you don't want to do it it's o.k and if it were that important to me I would have done it already so chill, man..
Dorth wrote:Stop depending on others so much.
You obviously don't know what you're talking about so I'll just ignore it.

P.S
lol I just noticed you registered to the forums 2 days after me :P

Edit:
Dorth wrote:Why not do it yourself?
Cause I don't understand that code.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Dorth
Posts: 931
Joined: Sat May 26, 2007 11:03 pm

Post by Dorth »

Yes, and yet I have helped you plenty of time. Also, registering is when lurking is no longer good enough, you know?

here:
http://sourceforge.net/tracker/index.ph ... tid=540678
Have a field trip, junior.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

I didn't mean to imply anything when I mentioned the registration date but never mind..
Well, thanks for the patch :wink:

Edit:
Dorth wrote:Have a field trip, junior.
Quite patronizing -_-.. <- Ignore that please..

Edit 2:
I'm Sorry, it seems I didn't understood you. :wink:
Last edited by MasterGod on Sun Mar 30, 2008 9:14 pm, edited 1 time in total.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

I tried it and it seems I don't have the following file:
MSVC wrote:COpenGLDriver.h(22) : fatal error C1083: Cannot open include file: 'wglext.h': No such file or directory
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Dorth
Posts: 931
Joined: Sat May 26, 2007 11:03 pm

Post by Dorth »

Seems the raging irish didn't spend enough time with you to point you out to google.

Whether you have it or not depend of what OpenGL extensions you have installed. Google, google, google.
Post Reply