Index: CIrrDeviceSDL.cpp =================================================================== --- CIrrDeviceSDL.cpp (revision 5070) +++ CIrrDeviceSDL.cpp (working copy) @@ -17,11 +17,7 @@ #include #include #include "SIrrCreationParameters.h" -#include -#include - #ifdef _MSC_VER -#pragma comment(lib, "SDL.lib") #endif // _MSC_VER namespace irr @@ -54,7 +50,7 @@ //! constructor CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param) : CIrrDeviceStub(param), - Screen((SDL_Surface*)param.WindowId), SDL_Flags(SDL_ANYFORMAT), + gWindow(0), gContext(0), MouseX(0), MouseY(0), MouseButtonStates(0), Width(param.WindowSize.Width), Height(param.WindowSize.Height), Resizable(false), WindowHasFocus(false), WindowMinimized(false) @@ -75,48 +71,15 @@ Close = true; } -#if defined(_IRR_WINDOWS_) - SDL_putenv("SDL_VIDEODRIVER=directx"); -#elif defined(_IRR_OSX_PLATFORM_) - SDL_putenv("SDL_VIDEODRIVER=Quartz"); -#else - SDL_putenv("SDL_VIDEODRIVER=x11"); +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + SDL_JoystickEventState(SDL_IGNORE); #endif -// SDL_putenv("SDL_WINDOWID="); - SDL_VERSION(&Info.version); + createWindow(); - SDL_GetWMInfo(&Info); - core::stringc sdlversion = "SDL Version "; - sdlversion += Info.version.major; - sdlversion += "."; - sdlversion += Info.version.minor; - sdlversion += "."; - sdlversion += Info.version.patch; - - Operator = new COSOperator(sdlversion); - os::Printer::log(sdlversion.c_str(), ELL_INFORMATION); - // create keymap createKeyMap(); - // enable key to character translation - SDL_EnableUNICODE(1); - (void)SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - - if ( CreationParams.Fullscreen ) - SDL_Flags |= SDL_FULLSCREEN; - if (CreationParams.DriverType == video::EDT_OPENGL) - SDL_Flags |= SDL_OPENGL; - else if (CreationParams.Doublebuffer) - SDL_Flags |= SDL_DOUBLEBUF; - // create window - if (CreationParams.DriverType != video::EDT_NULL) - { - // create the window, only if we do not use the null device - createWindow(); - } - // create cursor control CursorControl = new CCursorControl(this); @@ -136,6 +99,10 @@ for (u32 i=0; i1) + if (CreationParams.AntiAlias>1 && (!CreationParams.WindowNoBorder || (Width == desktop.w && Height == desktop.h))) { SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias ); } - if ( !Screen ) - Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); - if ( !Screen && CreationParams.AntiAlias>1) + if ( !gWindow ) + gWindow = SDL_CreateWindow( "SDLIrrlicht", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Width,Height, SDL_Flags ); + if ( !gWindow && CreationParams.AntiAlias>1) { while (--CreationParams.AntiAlias>1) { SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias ); - Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); - if (Screen) + gWindow = SDL_CreateWindow( "SDLIrrlicht", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Width,Height, SDL_Flags ); + if (gWindow) break; } - if ( !Screen ) + if ( !gWindow ) { SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 ); - Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); - if (Screen) + gWindow = SDL_CreateWindow( "SDLIrrlicht", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Width,Height, SDL_Flags ); + if (gWindow) os::Printer::log("AntiAliasing disabled due to lack of support!" ); } } } - else if ( !Screen ) - Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + else if ( !gWindow ) + gWindow = SDL_CreateWindow( "SDLIrrlicht", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Width,Height, SDL_Flags ); - if ( !Screen && CreationParams.Doublebuffer) + if ( !gWindow && CreationParams.Doublebuffer) { // Try single buffer if (CreationParams.DriverType == video::EDT_OPENGL) SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - SDL_Flags &= ~SDL_DOUBLEBUF; - Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + //SDL_Flags &= ~SDL_DOUBLEBUF; + gWindow = SDL_CreateWindow( "SDLIrrlicht", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Width,Height, SDL_Flags ); } - if ( !Screen ) + + //Width = CreationParams.WindowSize.Width; + //Height = CreationParams.WindowSize.Height; + if ( !gWindow ) { os::Printer::log( "Could not initialize display!" ); return false; } + gContext = SDL_GL_CreateContext(gWindow); + + if (CreationParams.WindowNoBorder) + { + SDL_GetWindowSize(gWindow, (int*)&Width, (int*)&Height); + } + return true; } @@ -281,6 +273,7 @@ } + //! runs the device. Returns false if device wants to be deleted bool CIrrDeviceSDL::run() { @@ -291,15 +284,123 @@ while ( !Close && SDL_PollEvent( &SDL_event ) ) { + switch (SDL_event.window.event) + { + case SDL_WINDOWEVENT_SHOWN: + WindowMinimized=false; + // SDL_Log("Window %d shown", event->window.windowID); + break; + case SDL_WINDOWEVENT_HIDDEN: + WindowMinimized=true; + // SDL_Log("Window %d hidden", event->window.windowID); + break; + case SDL_WINDOWEVENT_EXPOSED: + //SDL_Log("Window %d exposed", event->window.windowID); + break; + case SDL_WINDOWEVENT_MOVED: + // SDL_Log("Window %d moved to %d,%d", + // event->window.windowID, event->window.data1, + // event->window.data2); + break; + case SDL_WINDOWEVENT_RESIZED: + if ((SDL_event.window.data1 != (int)Width) || (SDL_event.window.data2 != (int)Height)) + { + Width = SDL_event.window.data1; + Height = SDL_event.window.data2; + + if (VideoDriver) + VideoDriver->OnResize(core::dimension2d(Width, Height)); + } + break; + case SDL_WINDOWEVENT_MINIMIZED: + WindowMinimized=true; + // SDL_Log("Window %d minimized", event->window.windowID); + break; + case SDL_WINDOWEVENT_MAXIMIZED: + WindowMinimized=false; + // SDL_Log("Window %d maximized", event->window.windowID); + break; + case SDL_WINDOWEVENT_RESTORED: + //SDL_Log("Window %d restored", event->window.windowID); + break; + case SDL_WINDOWEVENT_ENTER: + // SDL_Log("Mouse entered window %d", + // event->window.windowID); + break; + case SDL_WINDOWEVENT_LEAVE: + // SDL_Log("Mouse left window %d", event->window.windowID); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + WindowHasFocus=true; + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + WindowHasFocus=false; + // SDL_Log("Window %d lost keyboard focus", + // event->window.windowID); + break; + case SDL_WINDOWEVENT_CLOSE: + // SDL_Log("Window %d closed", event->window.windowID); + break; + } + switch ( SDL_event.type ) { + + /* case SDL_FINGERMOTION: + irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT; + irrevent.TouchInput.Event = irr::ETIE_MOVED; + MouseX = irrevent.TouchInput.X = SDL_event.tfinger.x; + MouseY = irrevent.TouchInput.Y = SDL_event.tfinger.y; + postEventFromUser(irrevent); + break; + case SDL_FINGERDOWN: + irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT; + irrevent.TouchInput.Event = irr::ETIE_PRESSED_DOWN; + MouseX = irrevent.TouchInput.X = SDL_event.tfinger.x; + MouseY = irrevent.TouchInput.Y = SDL_event.tfinger.y; + postEventFromUser(irrevent); + + break; + case SDL_FINGERUP: + irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT; + irrevent.TouchInput.Event = irr::ETIE_LEFT_UP; + MouseX = irrevent.TouchInput.X = SDL_event.tfinger.x; + MouseY = irrevent.TouchInput.Y = SDL_event.tfinger.y; + postEventFromUser(irrevent); + break; + + case SDL_MULTIGESTURE: + irrevent.EventType = irr::EET_TOUCH_INPUT_EVENT; + for (s32 i=0;iisVisible()) + { + MouseX = irrevent.MouseInput.X = SDL_event.motion.x; + MouseY = irrevent.MouseInput.Y = SDL_event.motion.y; + } + else + { + irrevent.MouseInput.X = SDL_event.motion.xrel; + irrevent.MouseInput.Y = SDL_event.motion.yrel; + } irrevent.MouseInput.ButtonStates = MouseButtonStates; - postEventFromUser(irrevent); break; @@ -353,17 +454,7 @@ } break; - case SDL_BUTTON_WHEELUP: - irrevent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; - irrevent.MouseInput.Wheel = 1.0f; - break; - - case SDL_BUTTON_WHEELDOWN: - irrevent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; - irrevent.MouseInput.Wheel = -1.0f; - break; } - irrevent.MouseInput.ButtonStates = MouseButtonStates; if (irrevent.MouseInput.Event != irr::EMIE_MOUSE_MOVED) @@ -386,6 +477,21 @@ } } break; + case SDL_MOUSEWHEEL: + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.ButtonStates = MouseButtonStates; + if(SDL_event.wheel.y > 0) + { + irrevent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = 1.0f; + } + else if(SDL_event.wheel.y <0 ) + { + irrevent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = -1.0f; + } + postEventFromUser(irrevent); + break; case SDL_KEYDOWN: case SDL_KEYUP: @@ -400,16 +506,9 @@ else key = (EKEY_CODE)KeyMap[idx].Win32Key; -#ifdef _IRR_WINDOWS_API_ - // handle alt+f4 in Windows, because SDL seems not to - if ( (SDL_event.key.keysym.mod & KMOD_LALT) && key == KEY_F4) - { - Close = true; - break; - } -#endif + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; - irrevent.KeyInput.Char = SDL_event.key.keysym.unicode; + irrevent.KeyInput.Char = SDL_event.key.keysym.scancode; irrevent.KeyInput.Key = key; irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN); irrevent.KeyInput.Shift = (SDL_event.key.keysym.mod & KMOD_SHIFT) != 0; @@ -422,30 +521,12 @@ Close = true; break; - case SDL_ACTIVEEVENT: - if ((SDL_event.active.state == SDL_APPMOUSEFOCUS) || - (SDL_event.active.state == SDL_APPINPUTFOCUS)) - WindowHasFocus = (SDL_event.active.gain==1); - else - if (SDL_event.active.state == SDL_APPACTIVE) - WindowMinimized = (SDL_event.active.gain!=1); - break; + - case SDL_VIDEORESIZE: - if ((SDL_event.resize.w != (int)Width) || (SDL_event.resize.h != (int)Height)) - { - Width = SDL_event.resize.w; - Height = SDL_event.resize.h; - Screen = SDL_SetVideoMode( Width, Height, 0, SDL_Flags ); - if (VideoDriver) - VideoDriver->OnResize(core::dimension2d(Width, Height)); - } - break; - case SDL_USEREVENT: irrevent.EventType = irr::EET_USER_EVENT; - irrevent.UserEvent.UserData1 = *(reinterpret_cast(&SDL_event.user.data1)); - irrevent.UserEvent.UserData2 = *(reinterpret_cast(&SDL_event.user.data2)); + irrevent.UserEvent.UserData1 = (reinterpret_cast(SDL_event.user.data1)); + irrevent.UserEvent.UserData2 = (reinterpret_cast(SDL_event.user.data2)); postEventFromUser(irrevent); break; @@ -478,7 +559,7 @@ joyevent.JoystickEvent.ButtonStates |= (SDL_JoystickGetButton(joystick, j)< 0) - ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; + info.Joystick = joystick; + info.Axes = SDL_JoystickNumAxes(joy); + info.Buttons = SDL_JoystickNumButtons(joy); + info.Name = SDL_JoystickNameForIndex(joystick); + info.PovHat = (SDL_JoystickNumHats(joy) > 0) + ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; - joystickInfo.push_back(info); + joystickInfo.push_back(info); + + } } for(joystick = 0; joystick < (int)joystickInfo.size(); ++joystick) @@ -582,8 +676,6 @@ return false; } - - //! pause execution temporarily void CIrrDeviceSDL::yield() { @@ -609,7 +701,7 @@ void CIrrDeviceSDL::setWindowCaption(const wchar_t* text) { core::stringc textc = text; - SDL_WM_SetCaption( textc.c_str( ), textc.c_str( ) ); + SDL_SetWindowTitle(gWindow, textc.c_str( )); } @@ -616,87 +708,22 @@ //! presents a surface in the client area bool CIrrDeviceSDL::present(video::IImage* surface, void* windowId, core::rect* srcClip) { - SDL_Surface *sdlSurface = SDL_CreateRGBSurfaceFrom( - surface->lock(), surface->getDimension().Width, surface->getDimension().Height, - surface->getBitsPerPixel(), surface->getPitch(), - surface->getRedMask(), surface->getGreenMask(), surface->getBlueMask(), surface->getAlphaMask()); - if (!sdlSurface) - return false; - SDL_SetAlpha(sdlSurface, 0, 0); - SDL_SetColorKey(sdlSurface, 0, 0); - sdlSurface->format->BitsPerPixel=surface->getBitsPerPixel(); - sdlSurface->format->BytesPerPixel=surface->getBytesPerPixel(); - if ((surface->getColorFormat()==video::ECF_R8G8B8) || - (surface->getColorFormat()==video::ECF_A8R8G8B8)) - { - sdlSurface->format->Rloss=0; - sdlSurface->format->Gloss=0; - sdlSurface->format->Bloss=0; - sdlSurface->format->Rshift=16; - sdlSurface->format->Gshift=8; - sdlSurface->format->Bshift=0; - if (surface->getColorFormat()==video::ECF_R8G8B8) - { - sdlSurface->format->Aloss=8; - sdlSurface->format->Ashift=32; - } - else - { - sdlSurface->format->Aloss=0; - sdlSurface->format->Ashift=24; - } - } - else if (surface->getColorFormat()==video::ECF_R5G6B5) - { - sdlSurface->format->Rloss=3; - sdlSurface->format->Gloss=2; - sdlSurface->format->Bloss=3; - sdlSurface->format->Aloss=8; - sdlSurface->format->Rshift=11; - sdlSurface->format->Gshift=5; - sdlSurface->format->Bshift=0; - sdlSurface->format->Ashift=16; - } - else if (surface->getColorFormat()==video::ECF_A1R5G5B5) - { - sdlSurface->format->Rloss=3; - sdlSurface->format->Gloss=3; - sdlSurface->format->Bloss=3; - sdlSurface->format->Aloss=7; - sdlSurface->format->Rshift=10; - sdlSurface->format->Gshift=5; - sdlSurface->format->Bshift=0; - sdlSurface->format->Ashift=15; - } + + return false; +} - SDL_Surface* scr = (SDL_Surface* )windowId; - if (!scr) - scr = Screen; - if (scr) - { - if (srcClip) - { - SDL_Rect sdlsrcClip; - sdlsrcClip.x = srcClip->UpperLeftCorner.X; - sdlsrcClip.y = srcClip->UpperLeftCorner.Y; - sdlsrcClip.w = srcClip->getWidth(); - sdlsrcClip.h = srcClip->getHeight(); - SDL_BlitSurface(sdlSurface, &sdlsrcClip, scr, NULL); - } - else - SDL_BlitSurface(sdlSurface, NULL, scr, NULL); - SDL_Flip(scr); - } - - SDL_FreeSurface(sdlSurface); - surface->unlock(); - return (scr != 0); +core::position2di CIrrDeviceSDL::getWindowPosition() +{ + + return core::position2di(0, 0); + } - //! notifies the device that it should close itself void CIrrDeviceSDL::closeDevice() { + + Close = true; } @@ -704,24 +731,30 @@ //! \return Pointer to a list with all video modes supported video::IVideoModeList* CIrrDeviceSDL::getVideoModeList() { - if (!VideoModeList->getVideoModeCount()) + if (!VideoModeList.getVideoModeCount()) { + int display_count = 0, display_index = 0, mode_index = 0; + SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; + // enumerate video modes. - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - SDL_Rect **modes = SDL_ListModes(vi->vfmt, SDL_Flags); - if (modes != 0) + display_count = SDL_GetNumVideoDisplays(); + SDL_GetCurrentDisplayMode(0, &mode); + VideoModeList.setDesktop(SDL_BITSPERPIXEL(mode.format), core::dimension2d(mode.w, mode.h)); + + if (display_count > 0) { - if (modes == (SDL_Rect **)-1) - os::Printer::log("All modes available.\n"); - else + for (; display_index < display_count; ++display_index) { - for (u32 i=0; modes[i]; ++i) - VideoModeList->addMode(core::dimension2d(modes[i]->w, modes[i]->h), vi->vfmt->BitsPerPixel); - } + for (; mode_index < SDL_GetNumDisplayModes(display_index); ++mode_index) + { + SDL_GetDisplayMode(display_index, mode_index, &mode); + VideoModeList.addMode(core::dimension2d(mode.w, mode.h), SDL_BITSPERPIXEL(mode.format)); + } + } } } - return VideoModeList; + return &VideoModeList; } @@ -728,15 +761,7 @@ //! Sets if the window should be resizable in windowed mode. void CIrrDeviceSDL::setResizable(bool resize) { - if (resize != Resizable) - { - if (resize) - SDL_Flags |= SDL_RESIZABLE; - else - SDL_Flags &= ~SDL_RESIZABLE; - Screen = SDL_SetVideoMode( 0, 0, 0, SDL_Flags ); - Resizable = resize; - } + } @@ -743,7 +768,7 @@ //! Minimizes window if possible void CIrrDeviceSDL::minimizeWindow() { - SDL_WM_IconifyWindow(); +// SDL_WM_IconifyWindow(); } @@ -753,7 +778,13 @@ // do nothing } +//! Get the position of this window on screen +core::position2di getWindowPosition() +{ + return core::position2di(-1, -1); +} + //! Restore original window size void CIrrDeviceSDL::restoreWindow() { @@ -804,24 +835,7 @@ //! returns color format of the window. video::ECOLOR_FORMAT CIrrDeviceSDL::getColorFormat() const { - if (Screen) - { - if (Screen->format->BitsPerPixel==16) - { - if (Screen->format->Amask != 0) - return video::ECF_A1R5G5B5; - else - return video::ECF_R5G6B5; - } - else - { - if (Screen->format->Amask != 0) - return video::ECF_A8R8G8B8; - else - return video::ECF_R8G8B8; - } - } - else + return CIrrDeviceStub::getColorFormat(); } @@ -863,9 +877,9 @@ KeyMap.push_back(SKeyMap(SDLK_DOWN, KEY_DOWN)); // select missing - KeyMap.push_back(SKeyMap(SDLK_PRINT, KEY_PRINT)); + KeyMap.push_back(SKeyMap(SDLK_PRINTSCREEN, KEY_PRINT)); // execute missing - KeyMap.push_back(SKeyMap(SDLK_PRINT, KEY_SNAPSHOT)); + KeyMap.push_back(SKeyMap(SDLK_PRINTSCREEN, KEY_SNAPSHOT)); KeyMap.push_back(SKeyMap(SDLK_INSERT, KEY_INSERT)); KeyMap.push_back(SKeyMap(SDLK_DELETE, KEY_DELETE)); @@ -909,21 +923,21 @@ KeyMap.push_back(SKeyMap(SDLK_y, KEY_KEY_Y)); KeyMap.push_back(SKeyMap(SDLK_z, KEY_KEY_Z)); - KeyMap.push_back(SKeyMap(SDLK_LSUPER, KEY_LWIN)); - KeyMap.push_back(SKeyMap(SDLK_RSUPER, KEY_RWIN)); + KeyMap.push_back(SKeyMap(SDLK_LCTRL, KEY_LWIN)); + KeyMap.push_back(SKeyMap(SDLK_RCTRL, KEY_RWIN)); // apps missing KeyMap.push_back(SKeyMap(SDLK_POWER, KEY_SLEEP)); //?? - KeyMap.push_back(SKeyMap(SDLK_KP0, KEY_NUMPAD0)); - KeyMap.push_back(SKeyMap(SDLK_KP1, KEY_NUMPAD1)); - KeyMap.push_back(SKeyMap(SDLK_KP2, KEY_NUMPAD2)); - KeyMap.push_back(SKeyMap(SDLK_KP3, KEY_NUMPAD3)); - KeyMap.push_back(SKeyMap(SDLK_KP4, KEY_NUMPAD4)); - KeyMap.push_back(SKeyMap(SDLK_KP5, KEY_NUMPAD5)); - KeyMap.push_back(SKeyMap(SDLK_KP6, KEY_NUMPAD6)); - KeyMap.push_back(SKeyMap(SDLK_KP7, KEY_NUMPAD7)); - KeyMap.push_back(SKeyMap(SDLK_KP8, KEY_NUMPAD8)); - KeyMap.push_back(SKeyMap(SDLK_KP9, KEY_NUMPAD9)); + KeyMap.push_back(SKeyMap(SDLK_KP_0, KEY_NUMPAD0)); + KeyMap.push_back(SKeyMap(SDLK_KP_1, KEY_NUMPAD1)); + KeyMap.push_back(SKeyMap(SDLK_KP_2, KEY_NUMPAD2)); + KeyMap.push_back(SKeyMap(SDLK_KP_3, KEY_NUMPAD3)); + KeyMap.push_back(SKeyMap(SDLK_KP_4, KEY_NUMPAD4)); + KeyMap.push_back(SKeyMap(SDLK_KP_5, KEY_NUMPAD5)); + KeyMap.push_back(SKeyMap(SDLK_KP_6, KEY_NUMPAD6)); + KeyMap.push_back(SKeyMap(SDLK_KP_7, KEY_NUMPAD7)); + KeyMap.push_back(SKeyMap(SDLK_KP_8, KEY_NUMPAD8)); + KeyMap.push_back(SKeyMap(SDLK_KP_9, KEY_NUMPAD9)); KeyMap.push_back(SKeyMap(SDLK_KP_MULTIPLY, KEY_MULTIPLY)); KeyMap.push_back(SKeyMap(SDLK_KP_PLUS, KEY_ADD)); // KeyMap.push_back(SKeyMap(SDLK_KP_, KEY_SEPARATOR)); @@ -948,8 +962,8 @@ KeyMap.push_back(SKeyMap(SDLK_F15, KEY_F15)); // no higher F-keys - KeyMap.push_back(SKeyMap(SDLK_NUMLOCK, KEY_NUMLOCK)); - KeyMap.push_back(SKeyMap(SDLK_SCROLLOCK, KEY_SCROLL)); + KeyMap.push_back(SKeyMap(SDLK_NUMLOCKCLEAR, KEY_NUMLOCK)); + KeyMap.push_back(SKeyMap(SDLK_SCROLLLOCK, KEY_SCROLL)); KeyMap.push_back(SKeyMap(SDLK_LSHIFT, KEY_LSHIFT)); KeyMap.push_back(SKeyMap(SDLK_RSHIFT, KEY_RSHIFT)); KeyMap.push_back(SKeyMap(SDLK_LCTRL, KEY_LCONTROL)); Index: CIrrDeviceSDL.h =================================================================== --- CIrrDeviceSDL.h (revision 5070) +++ CIrrDeviceSDL.h (working copy) @@ -16,8 +16,8 @@ #include "IImagePresenter.h" #include "ICursorControl.h" -#include -#include +#include +//#include namespace irr { @@ -33,19 +33,19 @@ virtual ~CIrrDeviceSDL(); //! runs the device. Returns false if device wants to be deleted - virtual bool run(); + virtual bool run() _IRR_OVERRIDE_; //! pause execution temporarily - virtual void yield(); + virtual void yield() _IRR_OVERRIDE_; //! pause execution for a specified time - virtual void sleep(u32 timeMs, bool pauseTimer); + virtual void sleep(u32 timeMs, bool pauseTimer) _IRR_OVERRIDE_; //! sets the caption of the window - virtual void setWindowCaption(const wchar_t* text); + virtual void setWindowCaption(const wchar_t* text) _IRR_OVERRIDE_; //! returns if window is active. if not, nothing need to be drawn - virtual bool isWindowActive() const; + virtual bool isWindowActive() const _IRR_OVERRIDE_; //! returns if window has focus. bool isWindowFocused() const; @@ -57,37 +57,40 @@ video::ECOLOR_FORMAT getColorFormat() const; //! presents a surface in the client area - virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0); + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0) _IRR_OVERRIDE_; //! notifies the device that it should close itself - virtual void closeDevice(); + virtual void closeDevice() _IRR_OVERRIDE_; //! \return Returns a pointer to a list with all video modes supported - video::IVideoModeList* getVideoModeList(); + virtual video::IVideoModeList* getVideoModeList() _IRR_OVERRIDE_; //! Sets if the window should be resizable in windowed mode. - virtual void setResizable(bool resize=false); + virtual void setResizable(bool resize=false) _IRR_OVERRIDE_; //! Minimizes the window. - virtual void minimizeWindow(); + virtual void minimizeWindow() _IRR_OVERRIDE_; //! Maximizes the window. - virtual void maximizeWindow(); + virtual void maximizeWindow() _IRR_OVERRIDE_; //! Restores the window size. - virtual void restoreWindow(); + virtual void restoreWindow() _IRR_OVERRIDE_; + //! Get the position of this window on screen + virtual core::position2di getWindowPosition() _IRR_OVERRIDE_; + //! Activate any joysticks, and generate events for them. - virtual bool activateJoysticks(core::array & joystickInfo); + virtual bool activateJoysticks(core::array & joystickInfo) _IRR_OVERRIDE_; //! Set the current Gamma Value for the Display - virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ); + virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) _IRR_OVERRIDE_; //! Get the current Gamma Value for the Display - virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ); + virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) _IRR_OVERRIDE_; //! Get the device type - virtual E_DEVICE_TYPE getType() const + virtual E_DEVICE_TYPE getType() const _IRR_OVERRIDE_ { return EIDT_SDL; } @@ -103,7 +106,7 @@ } //! Changes the visible state of the mouse cursor. - virtual void setVisible(bool visible) + virtual void setVisible(bool visible) _IRR_OVERRIDE_ { IsVisible = visible; if ( visible ) @@ -113,37 +116,40 @@ } //! Returns if the cursor is currently visible. - virtual bool isVisible() const + virtual bool isVisible() const _IRR_OVERRIDE_ { return IsVisible; } //! Sets the new position of the cursor. - virtual void setPosition(const core::position2d &pos) + virtual void setPosition(const core::position2d &pos) _IRR_OVERRIDE_ { setPosition(pos.X, pos.Y); } //! Sets the new position of the cursor. - virtual void setPosition(f32 x, f32 y) + virtual void setPosition(f32 x, f32 y) _IRR_OVERRIDE_ { setPosition((s32)(x*Device->Width), (s32)(y*Device->Height)); } //! Sets the new position of the cursor. - virtual void setPosition(const core::position2d &pos) + virtual void setPosition(const core::position2d &pos) _IRR_OVERRIDE_ { setPosition(pos.X, pos.Y); } //! Sets the new position of the cursor. - virtual void setPosition(s32 x, s32 y) + virtual void setPosition(s32 x, s32 y) _IRR_OVERRIDE_ { - SDL_WarpMouse( x, y ); + //SDL_WarpMouse( x, y ); + SDL_WarpMouseInWindow(Device->gWindow, x,y); + Device->MouseX=x; + Device->MouseY=y; } //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() + virtual const core::position2d& getPosition() _IRR_OVERRIDE_ { updateCursorPos(); return CursorPos; @@ -150,7 +156,7 @@ } //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() + virtual core::position2d getRelativePosition() _IRR_OVERRIDE_ { updateCursorPos(); return core::position2d(CursorPos.X / (f32)Device->Width, @@ -157,7 +163,7 @@ CursorPos.Y / (f32)Device->Height); } - virtual void setReferenceRect(core::rect* rect=0) + virtual void setReferenceRect(core::rect* rect=0) _IRR_OVERRIDE_ { } @@ -183,6 +189,11 @@ bool IsVisible; }; + public : + SDL_Window* gWindow ; + SDL_GLContext gContext; + SDL_Renderer* Renderer; + s32 MouseX, MouseY; private: //! create the driver @@ -192,13 +203,12 @@ void createKeyMap(); - SDL_Surface* Screen; - int SDL_Flags; + void pollJoysticks(); + #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) core::array Joysticks; #endif - - s32 MouseX, MouseY; + u32 MouseButtonStates; u32 Width, Height; @@ -225,7 +235,7 @@ }; core::array KeyMap; - SDL_SysWMinfo Info; + //SDL_SysWMinfo Info; }; } // end namespace irr Index: COpenGLDriver.cpp =================================================================== --- COpenGLDriver.cpp (revision 5070) +++ COpenGLDriver.cpp (working copy) @@ -17,12 +17,11 @@ #include "COpenGLParallaxMapRenderer.h" #include "os.h" -#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ -#include "MacOSX/CIrrDeviceMacOSX.h" -#endif +const irr::f32 UV_OFFSET_HACK = 0.5f; #ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ -#include +#include +#include "CIrrDeviceSDL.h" #endif namespace irr @@ -304,7 +303,7 @@ }; int iAttrSize = sizeof(iAttributes)/sizeof(int); const bool framebuffer_srgb_supported = ((wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1) || - (wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1)); + (wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1)) && Params.HandleSRGB; if (!framebuffer_srgb_supported) { memmove(&iAttributes[24],&iAttributes[26],sizeof(int)*(iAttrSize-26)); @@ -326,6 +325,8 @@ if (valid && numFormats) rv = pixelFormat; + else if (iAttributes[11] > 24) + iAttributes[11] = 24; else iAttributes[21] -= 1; } @@ -333,7 +334,10 @@ if (rv) { PixelFormat=rv; + Params.ZBufferBits=iAttributes[11]; AntiAlias=iAttributes[21]; + if (framebuffer_srgb_supported) + Params.HandleSRGB = iAttributes[25] ? true : false; } } else @@ -394,15 +398,14 @@ if (PixelFormat) break; } + } - // set pixel format - if (!SetPixelFormat(HDc, PixelFormat, &pfd)) - { - os::Printer::log("Cannot set the pixel format.", ELL_ERROR); - return false; - } + // set pixel format + if (!SetPixelFormat(HDc, PixelFormat, &pfd)) + { + os::Printer::log("Cannot set the pixel format.", ELL_ERROR); + return false; } - os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG); // create rendering context @@ -599,7 +602,7 @@ Transformation3DChanged(true), AntiAlias(params.AntiAlias), RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), CurrentTarget(ERT_FRAME_BUFFER), Params(params), - SDLDevice(device), DeviceType(EIDT_SDL) + SDLDevice(device), DeviceType(EIDT_SDL), AARenderTarget(0), AAFinalTexture(0), EnableAA(false) { #ifdef _DEBUG setDebugName("COpenGLDriver"); @@ -609,9 +612,93 @@ CgContext = 0; #endif + core::dimension2du renderSize = params.WindowSize; + if (Params.WindowNoBorder) + { + SDL_GetWindowSize(device->gWindow, (int*)&ScreenSize.Width, (int*)&ScreenSize.Height); + } + Params.WindowSize.Width = ScreenSize.Width; + Params.WindowSize.Height = ScreenSize.Height; + genericDriverInit(); + +#if defined(GL_EXT_framebuffer_object) + if (params.WindowNoBorder && renderSize != Params.WindowSize && FeatureAvailable[IRR_ARB_framebuffer_object]) + { + if (!FeatureAvailable[IRR_EXT_framebuffer_multisample] || !FeatureAvailable[IRR_EXT_framebuffer_blit]) + AntiAlias = 0; + AARenderTarget = new COpenGLFBOTexture(renderSize, "AATarget", this, ColorFormat, AntiAlias); + if (AARenderTarget) + { + addTexture(AARenderTarget); + ITexture* tex = new COpenGLFBODepthTexture(AARenderTarget->getSize(), "AADepth", this, false, AntiAlias); + if (tex) + { + static_cast(tex)->attach(AARenderTarget); + tex->drop(); + } + if (AntiAlias > 0) + { + AAFinalTexture = new COpenGLFBOTexture(AARenderTarget->getSize(), "AAFinal", this, ColorFormat); + if (AAFinalTexture) + { + addTexture(AAFinalTexture); + AAFinalTexture->drop(); + } + } + } + } +#endif + } +void COpenGLDriver::drawAA() +{ + EnableAA = false; +#if defined(GL_ARB_framebuffer_object) || defined(GL_EXT_framebuffer_blit) + if (AARenderTarget && AAFinalTexture) + { + // Resolve RenderTarget into FinalTexture + extGlBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, AAFinalTexture->ColorFrameBuffer); + extGlBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, AARenderTarget->ColorFrameBuffer); + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + extGLBlitFramebuffer(0, 0, AARenderTarget->getSize().Width, AARenderTarget->getSize().Height, 0, 0, AAFinalTexture->getSize().Width, AAFinalTexture->getSize().Height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Draw Final Texture to screen buffer + extGlBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); + extGlBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, AAFinalTexture->ColorFrameBuffer); + glDrawBuffer(GL_BACK); + extGLBlitFramebuffer(0, 0, AAFinalTexture->getSize().Width, AAFinalTexture->getSize().Height, 0, 0, ScreenSize.Width, ScreenSize.Height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + extGlBindFramebuffer( GL_FRAMEBUFFER_EXT, 0 ); + glViewport(0,0,ScreenSize.Width,ScreenSize.Height); + } + else +#endif + // Draw non antialiased render target if AA not enabled + +#if defined(GL_EXT_framebuffer_object) + if (AARenderTarget) + { + SColor Color = SColor(255,255,255,255); + const video::SColor Colors[] = {Color,Color,Color,Color}; + extGlBindFramebuffer( GL_FRAMEBUFFER_EXT, 0 ); + glViewport(0,0,ScreenSize.Width,ScreenSize.Height); + glDrawBuffer(GL_BACK); + draw2DImage(AARenderTarget, core::recti(core::position2di(0), ScreenSize), + core::rect(core::position2d(0,0), core::dimension2di(AARenderTarget->getOriginalSize())), + 0, Colors, false); + } +#endif +} + +void COpenGLDriver::setAA(s32 aa) +{ + if (aa > 0 && AARenderTarget) + EnableAA = true; + else + EnableAA = false; +} + #endif // _IRR_COMPILE_WITH_SDL_DEVICE_ @@ -829,11 +916,12 @@ { CNullDriver::endScene(); - glFlush(); - #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ if (DeviceType == EIDT_WIN32) + { + glFlush(); return SwapBuffers(HDc) == TRUE; + } #endif #ifdef _IRR_COMPILE_WITH_X11_DEVICE_ @@ -855,7 +943,9 @@ #ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ if (DeviceType == EIDT_SDL) { - SDL_GL_SwapBuffers(); + drawAA(); + setAA(0); + SDL_GL_SwapWindow(SDLDevice->gWindow);//SDL_GL_SwapBuffers(); return true; } #endif @@ -922,7 +1012,9 @@ { // todo: SDL sets glFrontFace(GL_CCW) after driver creation, // it would be better if this was fixed elsewhere. - glFrontFace(GL_CW); + glFrontFace(GL_CW); + setAA(AARenderTarget ? 1 : 0); + setRenderTarget((ITexture*)0, true, true, SColor(255,0,0,0)); } #endif @@ -1261,12 +1353,12 @@ SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer; if (HWBuffer->vbo_verticesID) { - extGlDeleteBuffers(1, &HWBuffer->vbo_verticesID); + //extGlDeleteBuffers(1, &HWBuffer->vbo_verticesID); HWBuffer->vbo_verticesID=0; } if (HWBuffer->vbo_indicesID) { - extGlDeleteBuffers(1, &HWBuffer->vbo_indicesID); + //extGlDeleteBuffers(1, &HWBuffer->vbo_indicesID); HWBuffer->vbo_indicesID=0; } #endif @@ -1580,7 +1672,14 @@ glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Binormal); else glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48)); - } + + extGlClientActiveTexture(GL_TEXTURE3_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(1, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Weight); + else + glTexCoordPointer(1, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(60)); + } break; } @@ -2020,10 +2119,10 @@ // now draw it. const core::rect tcoords( - sourcePos.X * invW, - sourcePos.Y * invH, - (sourcePos.X + sourceSize.Width) * invW, - (sourcePos.Y + sourceSize.Height) * invH); + (sourcePos.X + UV_OFFSET_HACK) * invW, + (sourcePos.Y + UV_OFFSET_HACK) * invH, + (sourcePos.X + sourceSize.Width + UV_OFFSET_HACK) * invW, + (sourcePos.Y + sourceSize.Height + UV_OFFSET_HACK) * invH); const core::rect poss(targetPos, sourceSize); @@ -2143,11 +2242,12 @@ const core::dimension2d& ss = texture->getOriginalSize(); const f32 invW = 1.f / static_cast(ss.Width); const f32 invH = 1.f / static_cast(ss.Height); + const core::rect tcoords( - sourcePos.X * invW, - sourcePos.Y * invH, - (sourcePos.X + sourceSize.Width) * invW, - (sourcePos.Y + sourceSize.Height) * invH); + (sourcePos.X + UV_OFFSET_HACK) * invW, + (sourcePos.Y + UV_OFFSET_HACK) * invH, + (sourcePos.X + sourceSize.Width + UV_OFFSET_HACK) * invW, + (sourcePos.Y + sourceSize.Height + UV_OFFSET_HACK) * invH); const core::rect poss(targetPos, sourceSize); @@ -2186,11 +2286,12 @@ const core::dimension2d& ss = texture->getOriginalSize(); const f32 invW = 1.f / static_cast(ss.Width); const f32 invH = 1.f / static_cast(ss.Height); + const core::rect tcoords( - sourceRect.UpperLeftCorner.X * invW, - sourceRect.UpperLeftCorner.Y * invH, - sourceRect.LowerRightCorner.X * invW, - sourceRect.LowerRightCorner.Y *invH); + (sourceRect.UpperLeftCorner.X + UV_OFFSET_HACK) * invW, + (sourceRect.UpperLeftCorner.Y + UV_OFFSET_HACK) * invH, + (sourceRect.LowerRightCorner.X + UV_OFFSET_HACK) * invW, + (sourceRect.LowerRightCorner.Y + UV_OFFSET_HACK) * invH); const video::SColor temp[4] = { @@ -2208,7 +2309,11 @@ useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, true, useAlphaChannelOfTexture); - if (clipRect) + if (clipRect +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + && (RenderTargetTexture) // bit of a hack because we need scissor for ties, but scissor not working right for menu images. +#endif + ) { if (!clipRect->isValid()) return; @@ -2240,7 +2345,10 @@ glEnd(); if (clipRect) - glDisable(GL_SCISSOR_TEST); + { + glScissor(0,0,ScreenSize.Width,ScreenSize.Height); + glDisable(GL_SCISSOR_TEST); + } } @@ -2288,10 +2396,10 @@ break; const core::rect tcoords( - sourceRects[currentIndex].UpperLeftCorner.X * invW, - sourceRects[currentIndex].UpperLeftCorner.Y * invH, - sourceRects[currentIndex].LowerRightCorner.X * invW, - sourceRects[currentIndex].LowerRightCorner.Y * invH); + (sourceRects[currentIndex].UpperLeftCorner.X + UV_OFFSET_HACK) * invW, + (sourceRects[currentIndex].UpperLeftCorner.Y + UV_OFFSET_HACK) * invH, + (sourceRects[currentIndex].LowerRightCorner.X + UV_OFFSET_HACK)* invW, + (sourceRects[currentIndex].LowerRightCorner.Y + UV_OFFSET_HACK) * invH); const core::rect poss(targetPos, sourceRects[currentIndex].getSize()); @@ -2313,7 +2421,10 @@ targetPos.X += sourceRects[currentIndex].getWidth(); } if (clipRect) + { + glScissor(0,0,ScreenSize.Width,ScreenSize.Height); glDisable(GL_SCISSOR_TEST); + } } @@ -4116,7 +4227,6 @@ bool clearZBuffer, SColor color) { // check for right driver type - if (texture && texture->getDriverType() != EDT_OPENGL) { os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); @@ -4139,12 +4249,19 @@ } #endif + // check if we should set the previous RT back if ((RenderTargetTexture != texture) || - (CurrentTarget==ERT_MULTI_RENDER_TEXTURES)) + (CurrentTarget==ERT_MULTI_RENDER_TEXTURES) +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + || !texture +#endif + ) { setActiveTexture(0, 0); ResetRenderStates=true; + + if (RenderTargetTexture!=0) { RenderTargetTexture->unbindRTT(); @@ -4161,17 +4278,32 @@ CurrentTarget=ERT_RENDER_TEXTURE; } else +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (!EnableAA && !AARenderTarget) +#endif { - glViewport(0,0,ScreenSize.Width,ScreenSize.Height); - RenderTargetTexture = 0; - CurrentRendertargetSize = core::dimension2d(0,0); - CurrentTarget=ERT_FRAME_BUFFER; - glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT); + glViewport(0,0,ScreenSize.Width,ScreenSize.Height); + RenderTargetTexture = 0; + CurrentRendertargetSize = core::dimension2d(0,0); + CurrentTarget=ERT_FRAME_BUFFER; + glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT); } // we need to update the matrices due to the rendersize change. Transformation3DChanged=true; } +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (AARenderTarget && !texture) + { + glViewport(0, 0, AARenderTarget->getSize().Width, AARenderTarget->getSize().Height); + RenderTargetTexture = 0; + CurrentRendertargetSize = core::dimension2d(0,0); + CurrentTarget=ERT_FRAME_BUFFER; + AARenderTarget->bindRTT(); + Transformation3DChanged=true; + } +#endif + clearBuffers(clearBackBuffer, clearZBuffer, false, color); return true; Index: COpenGLDriver.h =================================================================== --- COpenGLDriver.h (revision 5070) +++ COpenGLDriver.h (working copy) @@ -34,6 +34,7 @@ namespace video { class COpenGLTexture; + class COpenGLFBOTexture; class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler { @@ -405,12 +406,24 @@ //! Get ZBuffer bits. GLenum getZBufferBits() const; + virtual SMaterial& getLastMaterial() {return LastMaterial;} + //! Get Cg context #ifdef _IRR_COMPILE_WITH_CG_ const CGcontext& getCgContext(); #endif +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + virtual void drawAA(); + virtual void setAA(s32 aa); +#endif + private: +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + COpenGLFBOTexture* AARenderTarget; + COpenGLFBOTexture* AAFinalTexture; + bool EnableAA; +#endif //! clears the zbuffer and color buffer void clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color); Index: COpenGLExtensionHandler.cpp =================================================================== --- COpenGLExtensionHandler.cpp (revision 5070) +++ COpenGLExtensionHandler.cpp (working copy) @@ -50,13 +50,15 @@ pGlPointParameterfARB(0), pGlPointParameterfvARB(0), pGlStencilFuncSeparate(0), pGlStencilOpSeparate(0), pGlStencilFuncSeparateATI(0), pGlStencilOpSeparateATI(0), - pGlCompressedTexImage2D(0), + pGlCompressedTexImage2D(0), pGlCompressedTexSubImage2D(0), // ARB framebuffer object pGlBindFramebuffer(0), pGlDeleteFramebuffers(0), pGlGenFramebuffers(0), pGlCheckFramebufferStatus(0), pGlFramebufferTexture2D(0), pGlBindRenderbuffer(0), pGlDeleteRenderbuffers(0), pGlGenRenderbuffers(0), pGlRenderbufferStorage(0), pGlFramebufferRenderbuffer(0), pGlGenerateMipmap(0), + /*pGlTexImage2DMultisample(0),*/ pGlRenderbufferStorageMultisample(0), pGlBlitFramebuffer(0), // EXT framebuffer object + pGlRenderbufferStorageMultisampleEXT(0), pGlBlitFramebufferEXT(0), pGlBindFramebufferEXT(0), pGlDeleteFramebuffersEXT(0), pGlGenFramebuffersEXT(0), pGlCheckFramebufferStatusEXT(0), pGlFramebufferTexture2DEXT(0), pGlBindRenderbufferEXT(0), pGlDeleteRenderbuffersEXT(0), pGlGenRenderbuffersEXT(0), @@ -473,6 +475,7 @@ // compressed textures pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D"); + pGlCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexSubImage2D"); // ARB FrameBufferObjects pGlBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebuffer"); @@ -486,8 +489,13 @@ pGlRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorage"); pGlFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferRenderbuffer"); pGlGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) IRR_OGL_LOAD_EXTENSION("glGenerateMipmap"); + //pGlTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) IRR_OGL_LOAD_EXTENSION("glTexImage2DMultisample"); + pGlRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorageMultisample"); + pGlBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBlitFramebuffer"); // EXT FrameBufferObjects + pGlRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorageMultisampleEXT"); + pGlBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glBlitFramebufferEXT"); pGlBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebufferEXT"); pGlDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffersEXT"); pGlGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenFramebuffersEXT"); @@ -545,7 +553,12 @@ // blend equation pGlBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationEXT"); + +#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_) + pGlBlendEquation = (PFNGLBLENDEQUATIONEXTPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationEXT"); +#else pGlBlendEquation = (PFNGLBLENDEQUATIONPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquation"); +#endif // get vsync extension #if defined(WGL_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_) @@ -787,11 +800,9 @@ return (Version>=120) || FeatureAvailable[IRR_EXT_blend_minmax] || FeatureAvailable[IRR_EXT_blend_subtract] || FeatureAvailable[IRR_EXT_blend_logic_op]; case EVDF_TEXTURE_MATRIX: -#ifdef _IRR_COMPILE_WITH_CG_ - // available iff. define is present - case EVDF_CG: -#endif return true; + case EVDF_TEXTURE_COMPRESSED_DXT: + return FeatureAvailable[IRR_EXT_texture_compression_s3tc]; default: return false; }; Index: COpenGLExtensionHandler.h =================================================================== --- COpenGLExtensionHandler.h (revision 5070) +++ COpenGLExtensionHandler.h (working copy) @@ -30,6 +30,7 @@ #endif #elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) + #include "CIrrDeviceMacOSX.h" #if defined(_IRR_OPENGL_USE_EXTPOINTER_) #define GL_GLEXT_LEGACY 1 #endif @@ -46,8 +47,8 @@ #define GLX_GLXEXT_PROTOTYPES 1 #endif #define NO_SDL_GLEXT - #include - #include + #include + #include #include "glext.h" #else #if defined(_IRR_OPENGL_USE_EXTPOINTER_) @@ -83,7 +84,6 @@ namespace video { - static const char* const OpenGLFeatureStrings[] = { "GL_3DFX_multisample", "GL_3DFX_tbuffer", @@ -96,12 +96,19 @@ "GL_AMD_multi_draw_indirect", "GL_AMD_name_gen_delete", "GL_AMD_performance_monitor", + "GL_AMD_pinned_memory", + "GL_AMD_query_buffer_object", "GL_AMD_sample_positions", "GL_AMD_seamless_cubemap_per_texture", "GL_AMD_shader_stencil_export", + "GL_AMD_shader_trinary_minmax", + "GL_AMD_sparse_texture", + "GL_AMD_stencil_operation_extended", "GL_AMD_texture_texture4", "GL_AMD_transform_feedback3_lines_triangles", - "GL_AMD_vertex_shader_tesselator", + "GL_AMD_vertex_shader_layer", + "GL_AMD_vertex_shader_tessellator", + "GL_AMD_vertex_shader_viewport_index", "GL_APPLE_aux_depth_stencil", "GL_APPLE_client_storage", "GL_APPLE_element_array", @@ -118,14 +125,19 @@ "GL_APPLE_vertex_array_range", "GL_APPLE_vertex_program_evaluators", "GL_APPLE_ycbcr_422", + "GL_ARB_ES3_compatibility", + "GL_ARB_arrays_of_arrays", "GL_ARB_base_instance", "GL_ARB_blend_func_extended", "GL_ARB_cl_event", + "GL_ARB_clear_buffer_object", "GL_ARB_color_buffer_float", "GL_ARB_compatibility", "GL_ARB_compressed_texture_pixel_storage", + "GL_ARB_compute_shader", "GL_ARB_conservative_depth", "GL_ARB_copy_buffer", + "GL_ARB_copy_image", "GL_ARB_debug_output", "GL_ARB_depth_buffer_float", "GL_ARB_depth_clamp", @@ -137,14 +149,17 @@ "GL_ARB_draw_instanced", "GL_ARB_ES2_compatibility", "GL_ARB_explicit_attrib_location", + "GL_ARB_explicit_uniform_location", "GL_ARB_fragment_coord_conventions", + "GL_ARB_fragment_layer_viewport", "GL_ARB_fragment_program", "GL_ARB_fragment_program_shadow", "GL_ARB_fragment_shader", + "GL_ARB_framebuffer_no_attachments", "GL_ARB_framebuffer_object", "GL_ARB_framebuffer_sRGB", + "GL_ARB_geometry_shader4", "GL_ARB_get_program_binary", - "GL_ARB_geometry_shader4", "GL_ARB_gpu_shader5", "GL_ARB_gpu_shader_fp64", "GL_ARB_half_float_pixel", @@ -152,9 +167,12 @@ "GL_ARB_imaging", "GL_ARB_instanced_arrays", "GL_ARB_internalformat_query", + "GL_ARB_internalformat_query2", + "GL_ARB_invalidate_subdata", "GL_ARB_map_buffer_alignment", "GL_ARB_map_buffer_range", "GL_ARB_matrix_palette", + "GL_ARB_multi_draw_indirect", "GL_ARB_multisample", "GL_ARB_multitexture", "GL_ARB_occlusion_query", @@ -162,8 +180,11 @@ "GL_ARB_pixel_buffer_object", "GL_ARB_point_parameters", "GL_ARB_point_sprite", + "GL_ARB_program_interface_query", "GL_ARB_provoking_vertex", + "GL_ARB_robust_buffer_access_behavior", "GL_ARB_robustness", + "GL_ARB_robustness_isolation", "GL_ARB_sample_shading", "GL_ARB_sampler_objects", "GL_ARB_seamless_cube_map", @@ -171,9 +192,11 @@ "GL_ARB_shader_atomic_counters", "GL_ARB_shader_bit_encoding", "GL_ARB_shader_image_load_store", + "GL_ARB_shader_image_size", "GL_ARB_shader_objects", "GL_ARB_shader_precision", "GL_ARB_shader_stencil_export", + "GL_ARB_shader_storage_buffer_object", "GL_ARB_shader_subroutine", "GL_ARB_shader_texture_lod", "GL_ARB_shading_language_100", @@ -182,11 +205,13 @@ "GL_ARB_shading_language_packing", "GL_ARB_shadow", "GL_ARB_shadow_ambient", + "GL_ARB_stencil_texturing", "GL_ARB_sync", "GL_ARB_tessellation_shader", "GL_ARB_texture_border_clamp", "GL_ARB_texture_buffer_object", "GL_ARB_texture_buffer_object_rgb32", + "GL_ARB_texture_buffer_range", "GL_ARB_texture_compression", "GL_ARB_texture_compression_bptc", "GL_ARB_texture_compression_rgtc", @@ -201,12 +226,15 @@ "GL_ARB_texture_mirrored_repeat", "GL_ARB_texture_multisample", "GL_ARB_texture_non_power_of_two", + "GL_ARB_texture_query_levels", "GL_ARB_texture_query_lod", "GL_ARB_texture_rectangle", "GL_ARB_texture_rg", "GL_ARB_texture_rgb10_a2ui", "GL_ARB_texture_storage", + "GL_ARB_texture_storage_multisample", "GL_ARB_texture_swizzle", + "GL_ARB_texture_view", "GL_ARB_timer_query", "GL_ARB_transform_feedback2", "GL_ARB_transform_feedback3", @@ -216,6 +244,7 @@ "GL_ARB_vertex_array_bgra", "GL_ARB_vertex_array_object", "GL_ARB_vertex_attrib_64bit", + "GL_ARB_vertex_attrib_binding", "GL_ARB_vertex_blend", "GL_ARB_vertex_buffer_object", "GL_ARB_vertex_program", @@ -331,7 +360,6 @@ "GL_EXT_vertex_shader", "GL_EXT_vertex_weighting", "GL_EXT_x11_sync_object", - "GL_FfdMaskSGIX", "GL_GREMEDY_frame_terminator", "GL_GREMEDY_string_marker", "GL_HP_convolution_border_modes", @@ -341,6 +369,7 @@ "GL_IBM_cull_vertex", "GL_IBM_multimode_draw_arrays", "GL_IBM_rasterpos_clip", + "GL_IBM_static_data", "GL_IBM_texture_mirrored_repeat", "GL_IBM_vertex_array_lists", "GL_INGR_blend_func_separate", @@ -347,19 +376,27 @@ "GL_INGR_color_clamp", "GL_INGR_interlace_read", "GL_INGR_palette_buffer", + "GL_INTEL_map_texture", "GL_INTEL_parallel_arrays", "GL_INTEL_texture_scissor", + "GL_KHR_debug", + "GL_KHR_texture_compression_astc_ldr", "GL_MESA_pack_invert", "GL_MESA_resize_buffers", "GL_MESA_window_pos", "GL_MESAX_texture_stack", "GL_MESA_ycbcr_texture", + "GL_NVX_conditional_render", + "GL_NV_bindless_texture", "GL_NV_blend_square", + "GL_NV_compute_program5", "GL_NV_conditional_render", "GL_NV_copy_depth_to_color", "GL_NV_copy_image", + "GL_NV_deep_texture3D", "GL_NV_depth_buffer_float", "GL_NV_depth_clamp", + "GL_NV_draw_texture", "GL_NV_evaluators", "GL_NV_explicit_multisample", "GL_NV_fence", @@ -383,6 +420,7 @@ "GL_NV_packed_depth_stencil", "GL_NV_parameter_buffer_object", "GL_NV_parameter_buffer_object2", + "GL_NV_path_rendering", "GL_NV_pixel_data_range", "GL_NV_point_sprite", "GL_NV_present_video", @@ -389,8 +427,11 @@ "GL_NV_primitive_restart", "GL_NV_register_combiners", "GL_NV_register_combiners2", + "GL_NV_shader_atomic_counters", + "GL_NV_shader_atomic_float", "GL_NV_shader_buffer_load", "GL_NV_shader_buffer_store", + "GL_NV_shader_storage_buffer_object", "GL_NV_tessellation_program5", "GL_NV_texgen_emboss", "GL_NV_texgen_reflection", @@ -417,7 +458,12 @@ "GL_NV_vertex_program3", "GL_NV_vertex_program4", "GL_NV_video_capture", + "GL_OES_byte_coordinates", + "GL_OES_compressed_paletted_texture", + "GL_OES_fixed_point", + "GL_OES_query_matrix", "GL_OES_read_format", + "GL_OES_single_precision", "GL_OML_interlace", "GL_OML_resample", "GL_OML_subsample", @@ -427,7 +473,7 @@ "GL_S3_s3tc", "GL_SGI_color_matrix", "GL_SGI_color_table", - "GL_SGI_depth_pass_instrument", + "GL_SGI_texture_color_table", "GL_SGIS_detail_texture", "GL_SGIS_fog_function", "GL_SGIS_generate_mipmap", @@ -443,7 +489,6 @@ "GL_SGIS_texture_filter4", "GL_SGIS_texture_lod", "GL_SGIS_texture_select", - "GL_SGI_texture_color_table", "GL_SGIX_async", "GL_SGIX_async_histogram", "GL_SGIX_async_pixel", @@ -459,7 +504,6 @@ "GL_SGIX_fragment_lighting", "GL_SGIX_framezoom", "GL_SGIX_igloo_interface", - "GL_SGIX_impact_pixel_texture", "GL_SGIX_instruments", "GL_SGIX_interlace", "GL_SGIX_ir_instrument1", @@ -480,7 +524,6 @@ "GL_SGIX_texture_lod_bias", "GL_SGIX_texture_multi_buffer", "GL_SGIX_texture_scale_bias", - "GL_SGIX_texture_select", "GL_SGIX_vertex_preclip", "GL_SGIX_ycrcb", "GL_SGIX_ycrcba", @@ -514,12 +557,19 @@ IRR_AMD_multi_draw_indirect, IRR_AMD_name_gen_delete, IRR_AMD_performance_monitor, + IRR_AMD_pinned_memory, + IRR_AMD_query_buffer_object, IRR_AMD_sample_positions, IRR_AMD_seamless_cubemap_per_texture, IRR_AMD_shader_stencil_export, + IRR_AMD_shader_trinary_minmax, + IRR_AMD_sparse_texture, + IRR_AMD_stencil_operation_extended, IRR_AMD_texture_texture4, IRR_AMD_transform_feedback3_lines_triangles, - IRR_AMD_vertex_shader_tesselator, + IRR_AMD_vertex_shader_layer, + IRR_AMD_vertex_shader_tessellator, + IRR_AMD_vertex_shader_viewport_index, IRR_APPLE_aux_depth_stencil, IRR_APPLE_client_storage, IRR_APPLE_element_array, @@ -536,14 +586,19 @@ IRR_APPLE_vertex_array_range, IRR_APPLE_vertex_program_evaluators, IRR_APPLE_ycbcr_422, + IRR_ARB_ES3_compatibility, + IRR_ARB_arrays_of_arrays, IRR_ARB_base_instance, IRR_ARB_blend_func_extended, IRR_ARB_cl_event, + IRR_ARB_clear_buffer_object, IRR_ARB_color_buffer_float, IRR_ARB_compatibility, IRR_ARB_compressed_texture_pixel_storage, + IRR_ARB_compute_shader, IRR_ARB_conservative_depth, IRR_ARB_copy_buffer, + IRR_ARB_copy_image, IRR_ARB_debug_output, IRR_ARB_depth_buffer_float, IRR_ARB_depth_clamp, @@ -555,10 +610,13 @@ IRR_ARB_draw_instanced, IRR_ARB_ES2_compatibility, IRR_ARB_explicit_attrib_location, + IRR_ARB_explicit_uniform_location, IRR_ARB_fragment_coord_conventions, + IRR_ARB_fragment_layer_viewport, IRR_ARB_fragment_program, IRR_ARB_fragment_program_shadow, IRR_ARB_fragment_shader, + IRR_ARB_framebuffer_no_attachments, IRR_ARB_framebuffer_object, IRR_ARB_framebuffer_sRGB, IRR_ARB_geometry_shader4, @@ -570,9 +628,12 @@ IRR_ARB_imaging, IRR_ARB_instanced_arrays, IRR_ARB_internalformat_query, + IRR_ARB_internalformat_query2, + IRR_ARB_invalidate_subdata, IRR_ARB_map_buffer_alignment, IRR_ARB_map_buffer_range, IRR_ARB_matrix_palette, + IRR_ARB_multi_draw_indirect, IRR_ARB_multisample, IRR_ARB_multitexture, IRR_ARB_occlusion_query, @@ -580,8 +641,11 @@ IRR_ARB_pixel_buffer_object, IRR_ARB_point_parameters, IRR_ARB_point_sprite, + IRR_ARB_program_interface_query, IRR_ARB_provoking_vertex, + IRR_ARB_robust_buffer_access_behavior, IRR_ARB_robustness, + IRR_ARB_robustness_isolation, IRR_ARB_sample_shading, IRR_ARB_sampler_objects, IRR_ARB_seamless_cube_map, @@ -589,9 +653,11 @@ IRR_ARB_shader_atomic_counters, IRR_ARB_shader_bit_encoding, IRR_ARB_shader_image_load_store, + IRR_ARB_shader_image_size, IRR_ARB_shader_objects, IRR_ARB_shader_precision, IRR_ARB_shader_stencil_export, + IRR_ARB_shader_storage_buffer_object, IRR_ARB_shader_subroutine, IRR_ARB_shader_texture_lod, IRR_ARB_shading_language_100, @@ -600,11 +666,13 @@ IRR_ARB_shading_language_packing, IRR_ARB_shadow, IRR_ARB_shadow_ambient, + IRR_ARB_stencil_texturing, IRR_ARB_sync, IRR_ARB_tessellation_shader, IRR_ARB_texture_border_clamp, IRR_ARB_texture_buffer_object, IRR_ARB_texture_buffer_object_rgb32, + IRR_ARB_texture_buffer_range, IRR_ARB_texture_compression, IRR_ARB_texture_compression_bptc, IRR_ARB_texture_compression_rgtc, @@ -619,12 +687,15 @@ IRR_ARB_texture_mirrored_repeat, IRR_ARB_texture_multisample, IRR_ARB_texture_non_power_of_two, + IRR_ARB_texture_query_levels, IRR_ARB_texture_query_lod, IRR_ARB_texture_rectangle, IRR_ARB_texture_rg, IRR_ARB_texture_rgb10_a2ui, IRR_ARB_texture_storage, + IRR_ARB_texture_storage_multisample, IRR_ARB_texture_swizzle, + IRR_ARB_texture_view, IRR_ARB_timer_query, IRR_ARB_transform_feedback2, IRR_ARB_transform_feedback3, @@ -634,6 +705,7 @@ IRR_ARB_vertex_array_bgra, IRR_ARB_vertex_array_object, IRR_ARB_vertex_attrib_64bit, + IRR_ARB_vertex_attrib_binding, IRR_ARB_vertex_blend, IRR_ARB_vertex_buffer_object, IRR_ARB_vertex_program, @@ -749,7 +821,6 @@ IRR_EXT_vertex_shader, IRR_EXT_vertex_weighting, IRR_EXT_x11_sync_object, - IRR_FfdMaskSGIX, IRR_GREMEDY_frame_terminator, IRR_GREMEDY_string_marker, IRR_HP_convolution_border_modes, @@ -759,6 +830,7 @@ IRR_IBM_cull_vertex, IRR_IBM_multimode_draw_arrays, IRR_IBM_rasterpos_clip, + IRR_IBM_static_data, IRR_IBM_texture_mirrored_repeat, IRR_IBM_vertex_array_lists, IRR_INGR_blend_func_separate, @@ -765,19 +837,27 @@ IRR_INGR_color_clamp, IRR_INGR_interlace_read, IRR_INGR_palette_buffer, + IRR_INTEL_map_texture, IRR_INTEL_parallel_arrays, IRR_INTEL_texture_scissor, + IRR_KHR_debug, + IRR_KHR_texture_compression_astc_ldr, IRR_MESA_pack_invert, IRR_MESA_resize_buffers, IRR_MESA_window_pos, IRR_MESAX_texture_stack, IRR_MESA_ycbcr_texture, + IRR_NVX_conditional_render, + IRR_NV_bindless_texture, IRR_NV_blend_square, + IRR_NV_compute_program5, IRR_NV_conditional_render, IRR_NV_copy_depth_to_color, IRR_NV_copy_image, + IRR_NV_deep_texture3D, IRR_NV_depth_buffer_float, IRR_NV_depth_clamp, + IRR_NV_draw_texture, IRR_NV_evaluators, IRR_NV_explicit_multisample, IRR_NV_fence, @@ -801,6 +881,7 @@ IRR_NV_packed_depth_stencil, IRR_NV_parameter_buffer_object, IRR_NV_parameter_buffer_object2, + IRR_NV_path_rendering, IRR_NV_pixel_data_range, IRR_NV_point_sprite, IRR_NV_present_video, @@ -807,8 +888,11 @@ IRR_NV_primitive_restart, IRR_NV_register_combiners, IRR_NV_register_combiners2, + IRR_NV_shader_atomic_counters, + IRR_NV_shader_atomic_float, IRR_NV_shader_buffer_load, IRR_NV_shader_buffer_store, + IRR_NV_shader_storage_buffer_object, IRR_NV_tessellation_program5, IRR_NV_texgen_emboss, IRR_NV_texgen_reflection, @@ -835,7 +919,12 @@ IRR_NV_vertex_program3, IRR_NV_vertex_program4, IRR_NV_video_capture, + IRR_OES_byte_coordinates, + IRR_OES_compressed_paletted_texture, + IRR_OES_fixed_point, + IRR_OES_query_matrix, IRR_OES_read_format, + IRR_OES_single_precision, IRR_OML_interlace, IRR_OML_resample, IRR_OML_subsample, @@ -845,7 +934,7 @@ IRR_S3_s3tc, IRR_SGI_color_matrix, IRR_SGI_color_table, - IRR_SGI_depth_pass_instrument, + IRR_SGI_texture_color_table, IRR_SGIS_detail_texture, IRR_SGIS_fog_function, IRR_SGIS_generate_mipmap, @@ -861,7 +950,6 @@ IRR_SGIS_texture_filter4, IRR_SGIS_texture_lod, IRR_SGIS_texture_select, - IRR_SGI_texture_color_table, IRR_SGIX_async, IRR_SGIX_async_histogram, IRR_SGIX_async_pixel, @@ -877,7 +965,6 @@ IRR_SGIX_fragment_lighting, IRR_SGIX_framezoom, IRR_SGIX_igloo_interface, - IRR_SGIX_impact_pixel_texture, IRR_SGIX_instruments, IRR_SGIX_interlace, IRR_SGIX_ir_instrument1, @@ -898,7 +985,6 @@ IRR_SGIX_texture_lod_bias, IRR_SGIX_texture_multi_buffer, IRR_SGIX_texture_scale_bias, - IRR_SGIX_texture_select, IRR_SGIX_vertex_preclip, IRR_SGIX_ycrcb, IRR_SGIX_ycrcba, @@ -992,6 +1078,9 @@ void extGlCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); + void extGlCompressedTexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const void* data); // shader programming void extGlGenPrograms(GLsizei n, GLuint *programs); @@ -1068,6 +1157,9 @@ void extGlGenerateMipmap(GLenum target); void extGlActiveStencilFace(GLenum face); void extGlDrawBuffers(GLsizei n, const GLenum *bufs); + //void extGlTexImage2DMultisample(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void extGlRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height); + void extGLBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); // vertex buffer object void extGlGenBuffers(GLsizei n, GLuint *buffers); @@ -1087,7 +1179,7 @@ void extGlDisableIndexed(GLenum target, GLuint index); void extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst); void extGlBlendEquationIndexed(GLuint buf, GLenum mode); - void extGlProgramParameteri(GLuint program, GLenum pname, GLint value); + void extGlProgramParameteri(GLhandleARB program, GLenum pname, GLint value); // occlusion query void extGlGenQueries(GLsizei n, GLuint *ids); @@ -1168,6 +1260,7 @@ PFNGLSTENCILFUNCSEPARATEATIPROC pGlStencilFuncSeparateATI; PFNGLSTENCILOPSEPARATEATIPROC pGlStencilOpSeparateATI; PFNGLCOMPRESSEDTEXIMAGE2DPROC pGlCompressedTexImage2D; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC pGlCompressedTexSubImage2D; // ARB framebuffer object PFNGLBINDFRAMEBUFFERPROC pGlBindFramebuffer; PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers; @@ -1180,7 +1273,12 @@ PFNGLRENDERBUFFERSTORAGEPROC pGlRenderbufferStorage; PFNGLFRAMEBUFFERRENDERBUFFERPROC pGlFramebufferRenderbuffer; PFNGLGENERATEMIPMAPPROC pGlGenerateMipmap; + //PFNGLTEXIMAGE2DMULTISAMPLEPROC pGlTexImage2DMultisample; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC pGlRenderbufferStorageMultisample; + PFNGLBLITFRAMEBUFFERPROC pGlBlitFramebuffer; // EXT framebuffer object + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC pGlRenderbufferStorageMultisampleEXT; + PFNGLBLITFRAMEBUFFEREXTPROC pGlBlitFramebufferEXT; PFNGLBINDFRAMEBUFFEREXTPROC pGlBindFramebufferEXT; PFNGLDELETEFRAMEBUFFERSEXTPROC pGlDeleteFramebuffersEXT; PFNGLGENFRAMEBUFFERSEXTPROC pGlGenFramebuffersEXT; @@ -1233,7 +1331,11 @@ PFNGLGETOCCLUSIONQUERYIVNVPROC pGlGetOcclusionQueryivNV; PFNGLGETOCCLUSIONQUERYUIVNVPROC pGlGetOcclusionQueryuivNV; PFNGLBLENDEQUATIONEXTPROC pGlBlendEquationEXT; - PFNGLBLENDEQUATIONPROC pGlBlendEquation; +#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) || defined(_IRR_COMPILE_WITH_X11_DEVICE_) + PFNGLBLENDEQUATIONEXTPROC pGlBlendEquation; +#else + PFNGLBLENDEQUATIONPROC pGlBlendEquation; +#endif #if defined(WGL_EXT_swap_control) PFNWGLSWAPINTERVALEXTPROC pWglSwapIntervalEXT; #endif @@ -1934,6 +2036,19 @@ #endif } +inline void COpenGLExtensionHandler::extGlCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCompressedTexSubImage2D) + pGlCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); +#elif defined(GL_ARB_texture_compression) + glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); +#else + os::Printer::log("glCompressedTexSubImage2D not supported", ELL_ERROR); +#endif +} + inline void COpenGLExtensionHandler::extGlBindFramebuffer(GLenum target, GLuint framebuffer) { #ifdef _IRR_OPENGL_USE_EXTPOINTER_ @@ -2117,6 +2232,48 @@ #endif } +/*inline void COpenGLExtensionHandler::extGlTexImage2DMultisample(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlTexImage2DMultisample) + pGlTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); +#else + os::Printer::log("glTexImage2DMultisample not supported", ELL_ERROR); +#endif +}*/ + +inline void COpenGLExtensionHandler::extGlRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlRenderbufferStorageMultisample) + pGlRenderbufferStorageMultisample(target, samples, internalformat, width, height); + else if (pGlRenderbufferStorageMultisampleEXT) + pGlRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height); +#elif defined(GL_ARB_framebuffer_object) + glRenderbufferStorageMultisample(target, samples, internalformat, width, height); +#elif defined(GL_EXT_framebuffer_multisample) + glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height); +#else + os::Printer::log("glRenderbufferStorageMultisample not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGLBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBlitFramebuffer) + pGlBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + else if (pGlBlitFramebufferEXT) + pGlBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +#elif defined(GL_ARB_framebuffer_object) + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +#elif defined(GL_EXT_framebuffer_blit) + glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +#else + os::Printer::log("glBlitFramebuffer not supported", ELL_ERROR); +#endif +} + inline void COpenGLExtensionHandler::extGlActiveStencilFace(GLenum face) { #ifdef _IRR_OPENGL_USE_EXTPOINTER_ @@ -2373,7 +2530,7 @@ #endif } -inline void COpenGLExtensionHandler::extGlProgramParameteri(GLuint program, GLenum pname, GLint value) +inline void COpenGLExtensionHandler::extGlProgramParameteri(GLhandleARB program, GLenum pname, GLint value) { #if defined(_IRR_OPENGL_USE_EXTPOINTER_) if (queryFeature(EVDF_GEOMETRY_SHADER)) @@ -2386,7 +2543,7 @@ #elif defined(GL_ARB_geometry_shader4) glProgramParameteriARB(program, pname, value); #elif defined(GL_EXT_geometry_shader4) - glProgramParameteriEXT(program, pname, value); + glProgramParameteriEXT((long)program, pname, value); #elif defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4) glProgramParameteriNV(program, pname, value); #else Index: COpenGLSLMaterialRenderer.cpp =================================================================== --- COpenGLSLMaterialRenderer.cpp (revision 5070) +++ COpenGLSLMaterialRenderer.cpp (working copy) @@ -150,15 +150,24 @@ if (!createShader(GL_GEOMETRY_SHADER_EXT, geometryShaderProgram)) return; #if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_shader4) - if (Program2) // Geometry shaders are supported only in OGL2.x+ drivers. + if (Program2) { - Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType)); - Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType)); + Driver->extGlProgramParameteri((GLhandleARB)Program2, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType)); + Driver->extGlProgramParameteri((GLhandleARB)Program2, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType)); if (verticesOut==0) - Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut); + Driver->extGlProgramParameteri((GLhandleARB)Program2, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut); else - Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut)); + Driver->extGlProgramParameteri((GLhandleARB)Program2, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut)); } + else + { + Driver->extGlProgramParameteri(Program, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType)); + Driver->extGlProgramParameteri(Program, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType)); + if (verticesOut==0) + Driver->extGlProgramParameteri(Program, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut); + else + Driver->extGlProgramParameteri(Program, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut)); + } #elif defined(GL_NV_geometry_program4) if (verticesOut==0) Driver->extGlProgramVertexLimit(GL_GEOMETRY_PROGRAM_NV, Driver->MaxGeometryVerticesOut); @@ -521,11 +530,24 @@ return false; #if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects) + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + core::map:: Node* node = TableLookup.find(name); GLint Location=0; - if (Program2) - Location=Driver->extGlGetUniformLocation(Program2,name); + if (node) + { + Location = node->getValue(); + } else - Location=Driver->extGlGetUniformLocationARB(Program,name); + { + if (Program2) + Location=Driver->extGlGetUniformLocation(Program2,name); + else + Location=Driver->extGlGetUniformLocationARB(Program,name); + + TableLookup[name] = Location; + } bool status = true; @@ -532,15 +554,19 @@ switch (UniformInfo[i].type) { case GL_FLOAT: + case GL_BOOL: Driver->extGlUniform1fv(Location, count, floats); break; case GL_FLOAT_VEC2: + case GL_BOOL_VEC2: Driver->extGlUniform2fv(Location, count/2, floats); break; case GL_FLOAT_VEC3: + case GL_BOOL_VEC3: Driver->extGlUniform3fv(Location, count/3, floats); break; case GL_FLOAT_VEC4: + case GL_BOOL_VEC4: Driver->extGlUniform4fv(Location, count/4, floats); break; case GL_FLOAT_MAT2: @@ -588,11 +614,24 @@ return false; #if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects) + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + core::map:: Node* node = TableLookup.find(name); GLint Location=0; - if (Program2) - Location=Driver->extGlGetUniformLocation(Program2,name); + if (node) + { + Location = node->getValue(); + } else - Location=Driver->extGlGetUniformLocationARB(Program,name); + { + if (Program2) + Location=Driver->extGlGetUniformLocation(Program2,name); + else + Location=Driver->extGlGetUniformLocationARB(Program,name); + + TableLookup[name] = Location; + } bool status = true; @@ -635,11 +674,24 @@ return false; #if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects) + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + core::map:: Node* node = TableLookup.find(name); GLint Location=0; - if (Program2) - Location=Driver->extGlGetUniformLocation(Program2,name); + if (node) + { + Location = node->getValue(); + } else - Location=Driver->extGlGetUniformLocationARB(Program,name); + { + if (Program2) + Location=Driver->extGlGetUniformLocation(Program2,name); + else + Location=Driver->extGlGetUniformLocationARB(Program,name); + + TableLookup[name] = Location; + } bool status = true; Index: COpenGLSLMaterialRenderer.h =================================================================== --- COpenGLSLMaterialRenderer.h (revision 5070) +++ COpenGLSLMaterialRenderer.h (working copy) @@ -34,6 +34,7 @@ #include "IMaterialRendererServices.h" #include "IGPUProgrammingServices.h" #include "irrArray.h" +#include "irrMap.h" #include "irrString.h" namespace irr @@ -130,6 +131,8 @@ GLuint Program2; core::array UniformInfo; s32 UserData; + + core::map TableLookup; }; Index: COpenGLTexture.cpp =================================================================== --- COpenGLTexture.cpp (revision 5070) +++ COpenGLTexture.cpp (working copy) @@ -24,7 +24,7 @@ : ITexture(name), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0), TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true), - IsRenderTarget(false), AutomaticMipmapUpdate(false), + IsRenderTarget(false), IsCompressed(false), AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(true) { #ifdef _DEBUG @@ -34,9 +34,28 @@ HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); getImageValues(origImage); - glGenTextures(1, &TextureName); + if (ColorFormat == ECF_DXT1 || ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5) + { + if(!Driver->queryFeature(EVDF_TEXTURE_COMPRESSED_DXT)) + { + os::Printer::log("DXT texture compression not available.", ELL_ERROR); + return; + } - if (ImageSize==TextureSize) + if(ImageSize != TextureSize) + { + os::Printer::log("Invalid size of image for compressed texture, size of image must be POT.", ELL_ERROR); + return; + } + else + { + IsCompressed = true; + Image = origImage; + Image->grab(); + KeepImage = false; + } + } + else if (ImageSize==TextureSize) { Image = Driver->createImage(ColorFormat, ImageSize); origImage->copyTo(Image); @@ -47,6 +66,7 @@ // scale texture origImage->copyToScaling(Image); } + glGenTextures(1, &TextureName); uploadTexture(true, mipmapData); if (!KeepImage) { @@ -61,8 +81,8 @@ : ITexture(name), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0), TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), HasMipMaps(true), - MipmapLegacyMode(true), IsRenderTarget(false), AutomaticMipmapUpdate(false), - ReadOnlyLock(false), KeepImage(true) + MipmapLegacyMode(true), IsRenderTarget(false), IsCompressed(false), + AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(true) { #ifdef _DEBUG setDebugName("COpenGLTexture"); @@ -159,7 +179,23 @@ type=GL_UNSIGNED_INT_8_8_8_8_REV; internalformat = GL_RGBA; break; - // Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski. + case ECF_DXT1: + colorformat = GL_BGRA_EXT; + type = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + break; + case ECF_DXT2: + case ECF_DXT3: + colorformat = GL_BGRA_EXT; + type = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + internalformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case ECF_DXT4: + case ECF_DXT5: + colorformat = GL_BGRA_EXT; + type = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + internalformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; case ECF_R16F: { #ifdef GL_ARB_texture_rg @@ -293,7 +329,10 @@ } TextureSize=ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT)); - ColorFormat = getBestColorFormat(image->getColorFormat()); + if(image->getColorFormat() == ECF_DXT1 || image->getColorFormat() == ECF_DXT2 || image->getColorFormat() == ECF_DXT3 || image->getColorFormat() == ECF_DXT4 || image->getColorFormat() == ECF_DXT5) + ColorFormat = image->getColorFormat(); + else + ColorFormat = getBestColorFormat(image->getColorFormat()); } @@ -323,70 +362,109 @@ // mipmap handling for main texture if (!level && newTexture) { -#ifndef DISABLE_MIPMAPPING -#ifdef GL_SGIS_generate_mipmap // auto generate if possible and no mipmap data is given - if (HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) { - if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) - glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST); - else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) - glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); - else - glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_DONT_CARE); - - AutomaticMipmapUpdate=true; - if (!Driver->queryFeature(EVDF_FRAMEBUFFER_OBJECT)) { +#ifdef GL_SGIS_generate_mipmap + if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST); + else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); + else + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_DONT_CARE); + glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); MipmapLegacyMode=true; + AutomaticMipmapUpdate=true; +#endif } else + { + if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); + else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) + glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); + else + glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); + MipmapLegacyMode=false; + AutomaticMipmapUpdate=true; + } } + + // enable bilinear filter without mipmaps + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + StatesCache.BilinearFilter = true; + StatesCache.TrilinearFilter = false; + StatesCache.MipMapStatus = false; + } + + // now get image data and upload to GPU + u32 compressedDataSize = 0; + + void* source = image->lock(); + if (newTexture) + { + if (IsCompressed) + { + if(ColorFormat == ECF_DXT1) + compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 8; + else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5) + compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 16; + + Driver->extGlCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width, + image->getDimension().Height, 0, compressedDataSize, source); + } else -#endif + glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, + image->getDimension().Height, 0, PixelFormat, PixelType, source); + } + else + { + if (IsCompressed) { - // Either generate manually due to missing capability - // or use predefined mipmap data - AutomaticMipmapUpdate=false; - regenerateMipMapLevels(mipmapData); + if(ColorFormat == ECF_DXT1) + compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 8; + else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5) + compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 16; + + Driver->extGlCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, + image->getDimension().Height, PixelFormat, compressedDataSize, source); } + else + glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, + image->getDimension().Height, PixelFormat, PixelType, source); + } + image->unlock(); + + if (!level && newTexture) + { + if (IsCompressed && !mipmapData) + { + if (image->hasMipMaps()) + mipmapData = static_cast(image->lock())+compressedDataSize; + else + HasMipMaps = false; + } + + regenerateMipMapLevels(mipmapData); + if (HasMipMaps) // might have changed in regenerateMipMapLevels { // enable bilinear mipmap filter glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + StatesCache.BilinearFilter = true; + StatesCache.TrilinearFilter = false; + StatesCache.MipMapStatus = true; } - else -#else - HasMipMaps=false; - os::Printer::log("Did not create OpenGL texture mip maps.", ELL_INFORMATION); -#endif - { - // enable bilinear filter without mipmaps - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } } - // now get image data and upload to GPU - void* source = image->lock(); - if (newTexture) - glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, - image->getDimension().Height, 0, PixelFormat, PixelType, source); - else - glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, - image->getDimension().Height, PixelFormat, PixelType, source); - image->unlock(); - - if (!MipmapLegacyMode && AutomaticMipmapUpdate) - { - glEnable(GL_TEXTURE_2D); - Driver->extGlGenerateMipmap(GL_TEXTURE_2D); - } - if (Driver->testGLError()) os::Printer::log("Could not glTexImage2D", ELL_ERROR); } @@ -395,6 +473,9 @@ //! lock function void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) { + if (IsCompressed) // TO-DO + return 0; + // store info about which image is locked IImage* image = (mipmapLevel==0)?Image:MipImage; ReadOnlyLock |= (mode==ETLM_READ_ONLY); @@ -500,6 +581,9 @@ //! unlock function void COpenGLTexture::unlock() { + if (IsCompressed) // TO-DO + return; + // test if miplevel or main texture was locked IImage* image = MipImage?MipImage:Image; if (!image) @@ -585,12 +669,37 @@ //! modifying the texture void COpenGLTexture::regenerateMipMapLevels(void* mipmapData) { - if (AutomaticMipmapUpdate || !HasMipMaps || !Image) + // texture require mipmaps? + if (!HasMipMaps) return; - if ((Image->getDimension().Width==1) && (Image->getDimension().Height==1)) + + // we don't use custom data for mipmaps. + if (!mipmapData) + { + // compressed textures require custom data for prepare mipmaps. + if (IsCompressed) + return; + + // texture use legacy method for generate mipmaps? + if (AutomaticMipmapUpdate && MipmapLegacyMode) + return; + + // hardware doesn't support generate mipmaps for certain texture but image data doesn't exist or is wrong. + if (!AutomaticMipmapUpdate && (!Image || (Image && ((Image->getDimension().Width==1) && (Image->getDimension().Height==1))))) + return; + } + + // hardware moethods for generate mipmaps. + if (!mipmapData && AutomaticMipmapUpdate && !MipmapLegacyMode) + { + glEnable(GL_TEXTURE_2D); + Driver->extGlGenerateMipmap(GL_TEXTURE_2D); + return; + } // Manually create mipmaps or use prepared version + u32 compressedDataSize = 0; u32 width=Image->getDimension().Width; u32 height=Image->getDimension().Height; u32 i=0; @@ -601,18 +710,38 @@ width>>=1; if (height>1) height>>=1; + ++i; + if (!target) target = new u8[width*height*Image->getBytesPerPixel()]; + // create scaled version if no mipdata available if (!mipmapData) Image->copyToScaling(target, width, height, Image->getColorFormat()); - glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height, - 0, PixelFormat, PixelType, target); + + if (IsCompressed) + { + if(ColorFormat == ECF_DXT1) + compressedDataSize = ((width + 3) / 4) * ((height + 3) / 4) * 8; + else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5) + compressedDataSize = ((width + 3) / 4) * ((height + 3) / 4) * 16; + + Driver->extGlCompressedTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, + height, 0, compressedDataSize, target); + } + else + glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height, + 0, PixelFormat, PixelType, target); + // get next prepared mipmap data if available if (mipmapData) { - mipmapData = static_cast(mipmapData)+width*height*Image->getBytesPerPixel(); + if (IsCompressed) + mipmapData = static_cast(mipmapData)+compressedDataSize; + else + mipmapData = static_cast(mipmapData)+width*height*Image->getBytesPerPixel(); + target = static_cast(mipmapData); } } @@ -657,6 +786,13 @@ } +//! Get an access to texture states cache. +COpenGLTexture::SStatesCache& COpenGLTexture::getStatesCache() const +{ + return StatesCache; +} + + /* FBO Textures */ // helper function for render to texture @@ -665,8 +801,8 @@ //! RTT ColorFrameBuffer constructor COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d& size, const io::path& name, COpenGLDriver* driver, - ECOLOR_FORMAT format) - : COpenGLTexture(name, driver), DepthTexture(0), ColorFrameBuffer(0) + ECOLOR_FORMAT format, s32 samples) + : COpenGLTexture(name, driver), DepthTexture(0), ColorFrameBuffer(0), ColorRenderBuffer(0) { #ifdef _DEBUG setDebugName("COpenGLTexture_FBO"); @@ -686,6 +822,33 @@ HasMipMaps = false; IsRenderTarget = true; + if (samples > 0) + { +#if defined(GL_ARB_framebuffer_object) || defined(GL_EXT_framebuffer_multisample) + Driver->extGlGenFramebuffers( 1, &ColorFrameBuffer ); + Driver->extGlGenRenderbuffers(1, &ColorRenderBuffer); + Driver->extGlBindRenderbuffer(GL_RENDERBUFFER_EXT, ColorRenderBuffer); + bindRTT(); + Driver->extGlRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT, samples, InternalFormat, ImageSize.Width, ImageSize.Height); + +#ifdef _DEBUG + driver->testGLError(); +#endif + + // attach color renderbuffer to frame buffer + Driver->extGlFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + ColorRenderBuffer); + + +#ifdef _DEBUG + checkFBOStatus(Driver); +#endif + } + else +#endif + { #ifdef GL_EXT_framebuffer_object // generate frame buffer Driver->extGlGenFramebuffers(1, &ColorFrameBuffer); @@ -697,6 +860,15 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if(FilteringType == GL_NEAREST) + StatesCache.BilinearFilter = false; + else + StatesCache.BilinearFilter = true; + + StatesCache.WrapU = ETC_CLAMP_TO_EDGE; + StatesCache.WrapV = ETC_CLAMP_TO_EDGE; + glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width, ImageSize.Height, 0, PixelFormat, PixelType, 0); #ifdef _DEBUG @@ -714,6 +886,7 @@ #endif #endif + } unbindRTT(); } @@ -726,6 +899,9 @@ Driver->removeDepthTexture(DepthTexture); if (ColorFrameBuffer) Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer); + + if (ColorRenderBuffer) + Driver->extGlDeleteRenderbuffers(1, &ColorRenderBuffer); } @@ -755,7 +931,6 @@ #endif } - /* FBO Depth Textures */ //! RTT DepthBuffer constructor @@ -763,7 +938,8 @@ const core::dimension2d& size, const io::path& name, COpenGLDriver* driver, - bool useStencil) + bool useStencil, + s32 samples) : COpenGLTexture(name, driver), DepthRenderBuffer(0), StencilRenderBuffer(0), UseStencil(useStencil) { @@ -816,6 +992,12 @@ // generate depth buffer Driver->extGlGenRenderbuffers(1, &DepthRenderBuffer); Driver->extGlBindRenderbuffer(GL_RENDERBUFFER_EXT, DepthRenderBuffer); + +#if defined(GL_ARB_framebuffer_object) || defined(GL_EXT_framebuffer_multisample) + if (samples > 0) + Driver->extGlRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT, samples, Driver->getZBufferBits(), ImageSize.Width, ImageSize.Height); + else +#endif Driver->extGlRenderbufferStorage(GL_RENDERBUFFER_EXT, Driver->getZBufferBits(), ImageSize.Width, ImageSize.Height); @@ -893,7 +1075,6 @@ { } - bool checkFBOStatus(COpenGLDriver* Driver) { #ifdef GL_EXT_framebuffer_object Index: COpenGLTexture.h =================================================================== --- COpenGLTexture.h (revision 5070) +++ COpenGLTexture.h (working copy) @@ -7,6 +7,7 @@ #include "ITexture.h" #include "IImage.h" +#include "SMaterialLayer.h" #include "IrrCompileConfig.h" #ifdef _IRR_COMPILE_WITH_OPENGL_ @@ -45,11 +46,32 @@ { class COpenGLDriver; + //! OpenGL texture. class COpenGLTexture : public ITexture { public: + //! Cache structure. + struct SStatesCache + { + SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT), + LODBias(0), AnisotropicFilter(0), + BilinearFilter(false), TrilinearFilter(false), + MipMapStatus(false), IsCached(false) + { + } + + u8 WrapU; + u8 WrapV; + s8 LODBias; + u8 AnisotropicFilter; + bool BilinearFilter; + bool TrilinearFilter; + bool MipMapStatus; + bool IsCached; + }; + //! constructor COpenGLTexture(IImage* surface, const io::path& name, void* mipmapData=0, COpenGLDriver* driver=0); @@ -57,39 +79,39 @@ virtual ~COpenGLTexture(); //! lock function - virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_; //! unlock function - virtual void unlock(); + virtual void unlock() _IRR_OVERRIDE_; //! Returns original size of the texture (image). - virtual const core::dimension2d& getOriginalSize() const; + virtual const core::dimension2d& getOriginalSize() const _IRR_OVERRIDE_; //! Returns size of the texture. - virtual const core::dimension2d& getSize() const; + virtual const core::dimension2d& getSize() const _IRR_OVERRIDE_; //! returns driver type of texture (=the driver, that created it) - virtual E_DRIVER_TYPE getDriverType() const; + virtual E_DRIVER_TYPE getDriverType() const _IRR_OVERRIDE_; //! returns color format of texture - virtual ECOLOR_FORMAT getColorFormat() const; + virtual ECOLOR_FORMAT getColorFormat() const _IRR_OVERRIDE_; //! returns pitch of texture (in bytes) - virtual u32 getPitch() const; + virtual u32 getPitch() const _IRR_OVERRIDE_; //! return open gl texture name GLuint getOpenGLTextureName() const; //! return whether this texture has mipmaps - virtual bool hasMipMaps() const; + virtual bool hasMipMaps() const _IRR_OVERRIDE_; //! Regenerates the mip map levels of the texture. /** Useful after locking and modifying the texture \param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image. If not set the mipmaps are derived from the main image. */ - virtual void regenerateMipMapLevels(void* mipmapData=0); + virtual void regenerateMipMapLevels(void* mipmapData=0) _IRR_OVERRIDE_; //! Is it a render target? - virtual bool isRenderTarget() const; + virtual bool isRenderTarget() const _IRR_OVERRIDE_; //! Is it a FrameBufferObject? virtual bool isFrameBufferObject() const; @@ -103,6 +125,9 @@ //! sets whether this texture is intended to be used as a render target. void setIsRenderTarget(bool isTarget); + //! Get an access to texture states cache. + SStatesCache& getStatesCache() const; + protected: //! protected constructor with basic setup, no GL texture name created, for derived classes @@ -140,9 +165,12 @@ bool HasMipMaps; bool MipmapLegacyMode; bool IsRenderTarget; + bool IsCompressed; bool AutomaticMipmapUpdate; bool ReadOnlyLock; bool KeepImage; + + mutable SStatesCache StatesCache; }; //! OpenGL FBO texture. @@ -152,41 +180,41 @@ //! FrameBufferObject constructor COpenGLFBOTexture(const core::dimension2d& size, const io::path& name, - COpenGLDriver* driver = 0, ECOLOR_FORMAT format = ECF_UNKNOWN); + COpenGLDriver* driver = 0, ECOLOR_FORMAT format = ECF_UNKNOWN, s32 samples = 0); //! destructor virtual ~COpenGLFBOTexture(); //! Is it a FrameBufferObject? - virtual bool isFrameBufferObject() const; + virtual bool isFrameBufferObject() const _IRR_OVERRIDE_; //! Bind RenderTargetTexture - virtual void bindRTT(); + virtual void bindRTT() _IRR_OVERRIDE_; //! Unbind RenderTargetTexture - virtual void unbindRTT(); + virtual void unbindRTT() _IRR_OVERRIDE_; ITexture* DepthTexture; -protected: + GLuint ColorFrameBuffer; + GLuint ColorRenderBuffer; }; - //! OpenGL FBO depth texture. class COpenGLFBODepthTexture : public COpenGLTexture { public: //! FrameBufferObject depth constructor - COpenGLFBODepthTexture(const core::dimension2d& size, const io::path& name, COpenGLDriver* driver=0, bool useStencil=false); + COpenGLFBODepthTexture(const core::dimension2d& size, const io::path& name, COpenGLDriver* driver=0, bool useStencil=false, s32 samples=0); //! destructor virtual ~COpenGLFBODepthTexture(); //! Bind RenderTargetTexture - virtual void bindRTT(); + virtual void bindRTT() _IRR_OVERRIDE_; //! Unbind RenderTargetTexture - virtual void unbindRTT(); + virtual void unbindRTT() _IRR_OVERRIDE_; bool attach(ITexture*);