aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp9652
1 files changed, 4826 insertions, 4826 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp b/libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp
index 1caa9c6..67c6b72 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/COpenGLDriver.cpp
@@ -1,4826 +1,4826 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "COpenGLDriver.h" 5#include "COpenGLDriver.h"
6// needed here also because of the create methods' parameters 6// needed here also because of the create methods' parameters
7#include "CNullDriver.h" 7#include "CNullDriver.h"
8 8
9#ifdef _IRR_COMPILE_WITH_OPENGL_ 9#ifdef _IRR_COMPILE_WITH_OPENGL_
10 10
11#include "COpenGLTexture.h" 11#include "COpenGLTexture.h"
12#include "COpenGLMaterialRenderer.h" 12#include "COpenGLMaterialRenderer.h"
13#include "COpenGLShaderMaterialRenderer.h" 13#include "COpenGLShaderMaterialRenderer.h"
14#include "COpenGLSLMaterialRenderer.h" 14#include "COpenGLSLMaterialRenderer.h"
15#include "COpenGLCgMaterialRenderer.h" 15#include "COpenGLCgMaterialRenderer.h"
16#include "COpenGLNormalMapRenderer.h" 16#include "COpenGLNormalMapRenderer.h"
17#include "COpenGLParallaxMapRenderer.h" 17#include "COpenGLParallaxMapRenderer.h"
18#include "os.h" 18#include "os.h"
19 19
20#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ 20#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
21#include <SDL/SDL.h> 21#include <SDL/SDL.h>
22#endif 22#endif
23 23
24namespace irr 24namespace irr
25{ 25{
26namespace video 26namespace video
27{ 27{
28 28
29// ----------------------------------------------------------------------- 29// -----------------------------------------------------------------------
30// WINDOWS CONSTRUCTOR 30// WINDOWS CONSTRUCTOR
31// ----------------------------------------------------------------------- 31// -----------------------------------------------------------------------
32#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 32#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
33//! Windows constructor and init code 33//! Windows constructor and init code
34COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params, 34COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
35 io::IFileSystem* io, CIrrDeviceWin32* device) 35 io::IFileSystem* io, CIrrDeviceWin32* device)
36: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), 36: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
37 CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), 37 CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
38 AntiAlias(params.AntiAlias), RenderTargetTexture(0), 38 AntiAlias(params.AntiAlias), RenderTargetTexture(0),
39 CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), 39 CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
40 CurrentTarget(ERT_FRAME_BUFFER), Params(params), 40 CurrentTarget(ERT_FRAME_BUFFER), Params(params),
41 HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device), 41 HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
42 DeviceType(EIDT_WIN32) 42 DeviceType(EIDT_WIN32)
43{ 43{
44 #ifdef _DEBUG 44 #ifdef _DEBUG
45 setDebugName("COpenGLDriver"); 45 setDebugName("COpenGLDriver");
46 #endif 46 #endif
47 47
48 #ifdef _IRR_COMPILE_WITH_CG_ 48 #ifdef _IRR_COMPILE_WITH_CG_
49 CgContext = 0; 49 CgContext = 0;
50 #endif 50 #endif
51} 51}
52 52
53 53
54bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device) 54bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device)
55{ 55{
56 if (videoData.OpenGLWin32.HWnd && videoData.OpenGLWin32.HDc && videoData.OpenGLWin32.HRc) 56 if (videoData.OpenGLWin32.HWnd && videoData.OpenGLWin32.HDc && videoData.OpenGLWin32.HRc)
57 { 57 {
58 if (!wglMakeCurrent((HDC)videoData.OpenGLWin32.HDc, (HGLRC)videoData.OpenGLWin32.HRc)) 58 if (!wglMakeCurrent((HDC)videoData.OpenGLWin32.HDc, (HGLRC)videoData.OpenGLWin32.HRc))
59 { 59 {
60 os::Printer::log("Render Context switch failed."); 60 os::Printer::log("Render Context switch failed.");
61 return false; 61 return false;
62 } 62 }
63 else 63 else
64 { 64 {
65 HDc = (HDC)videoData.OpenGLWin32.HDc; 65 HDc = (HDC)videoData.OpenGLWin32.HDc;
66 } 66 }
67 } 67 }
68 // set back to main context 68 // set back to main context
69 else if (HDc != ExposedData.OpenGLWin32.HDc) 69 else if (HDc != ExposedData.OpenGLWin32.HDc)
70 { 70 {
71 if (!wglMakeCurrent((HDC)ExposedData.OpenGLWin32.HDc, (HGLRC)ExposedData.OpenGLWin32.HRc)) 71 if (!wglMakeCurrent((HDC)ExposedData.OpenGLWin32.HDc, (HGLRC)ExposedData.OpenGLWin32.HRc))
72 { 72 {
73 os::Printer::log("Render Context switch failed."); 73 os::Printer::log("Render Context switch failed.");
74 return false; 74 return false;
75 } 75 }
76 else 76 else
77 { 77 {
78 HDc = (HDC)ExposedData.OpenGLWin32.HDc; 78 HDc = (HDC)ExposedData.OpenGLWin32.HDc;
79 } 79 }
80 } 80 }
81 return true; 81 return true;
82} 82}
83 83
84//! inits the open gl driver 84//! inits the open gl driver
85bool COpenGLDriver::initDriver(CIrrDeviceWin32* device) 85bool COpenGLDriver::initDriver(CIrrDeviceWin32* device)
86{ 86{
87 // Create a window to test antialiasing support 87 // Create a window to test antialiasing support
88 const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32"); 88 const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32");
89 HINSTANCE lhInstance = GetModuleHandle(0); 89 HINSTANCE lhInstance = GetModuleHandle(0);
90 90
91 // Register Class 91 // Register Class
92 WNDCLASSEX wcex; 92 WNDCLASSEX wcex;
93 wcex.cbSize = sizeof(WNDCLASSEX); 93 wcex.cbSize = sizeof(WNDCLASSEX);
94 wcex.style = CS_HREDRAW | CS_VREDRAW; 94 wcex.style = CS_HREDRAW | CS_VREDRAW;
95 wcex.lpfnWndProc = (WNDPROC)DefWindowProc; 95 wcex.lpfnWndProc = (WNDPROC)DefWindowProc;
96 wcex.cbClsExtra = 0; 96 wcex.cbClsExtra = 0;
97 wcex.cbWndExtra = 0; 97 wcex.cbWndExtra = 0;
98 wcex.hInstance = lhInstance; 98 wcex.hInstance = lhInstance;
99 wcex.hIcon = NULL; 99 wcex.hIcon = NULL;
100 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 100 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
101 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 101 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
102 wcex.lpszMenuName = 0; 102 wcex.lpszMenuName = 0;
103 wcex.lpszClassName = ClassName; 103 wcex.lpszClassName = ClassName;
104 wcex.hIconSm = 0; 104 wcex.hIconSm = 0;
105 wcex.hIcon = 0; 105 wcex.hIcon = 0;
106 RegisterClassEx(&wcex); 106 RegisterClassEx(&wcex);
107 107
108 RECT clientSize; 108 RECT clientSize;
109 clientSize.top = 0; 109 clientSize.top = 0;
110 clientSize.left = 0; 110 clientSize.left = 0;
111 clientSize.right = Params.WindowSize.Width; 111 clientSize.right = Params.WindowSize.Width;
112 clientSize.bottom = Params.WindowSize.Height; 112 clientSize.bottom = Params.WindowSize.Height;
113 113
114 DWORD style = WS_POPUP; 114 DWORD style = WS_POPUP;
115 if (!Params.Fullscreen) 115 if (!Params.Fullscreen)
116 style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; 116 style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
117 117
118 AdjustWindowRect(&clientSize, style, FALSE); 118 AdjustWindowRect(&clientSize, style, FALSE);
119 119
120 const s32 realWidth = clientSize.right - clientSize.left; 120 const s32 realWidth = clientSize.right - clientSize.left;
121 const s32 realHeight = clientSize.bottom - clientSize.top; 121 const s32 realHeight = clientSize.bottom - clientSize.top;
122 122
123 const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; 123 const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
124 const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; 124 const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;
125 125
126 HWND temporary_wnd=CreateWindow(ClassName, __TEXT(""), style, windowLeft, 126 HWND temporary_wnd=CreateWindow(ClassName, __TEXT(""), style, windowLeft,
127 windowTop, realWidth, realHeight, NULL, NULL, lhInstance, NULL); 127 windowTop, realWidth, realHeight, NULL, NULL, lhInstance, NULL);
128 128
129 if (!temporary_wnd) 129 if (!temporary_wnd)
130 { 130 {
131 os::Printer::log("Cannot create a temporary window.", ELL_ERROR); 131 os::Printer::log("Cannot create a temporary window.", ELL_ERROR);
132 UnregisterClass(ClassName, lhInstance); 132 UnregisterClass(ClassName, lhInstance);
133 return false; 133 return false;
134 } 134 }
135 135
136 HDc = GetDC(temporary_wnd); 136 HDc = GetDC(temporary_wnd);
137 137
138 // Set up pixel format descriptor with desired parameters 138 // Set up pixel format descriptor with desired parameters
139 PIXELFORMATDESCRIPTOR pfd = { 139 PIXELFORMATDESCRIPTOR pfd = {
140 sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 140 sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
141 1, // Version Number 141 1, // Version Number
142 PFD_DRAW_TO_WINDOW | // Format Must Support Window 142 PFD_DRAW_TO_WINDOW | // Format Must Support Window
143 PFD_SUPPORT_OPENGL | // Format Must Support OpenGL 143 PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
144 (Params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering 144 (Params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering
145 (Params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer 145 (Params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer
146 PFD_TYPE_RGBA, // Request An RGBA Format 146 PFD_TYPE_RGBA, // Request An RGBA Format
147 Params.Bits, // Select Our Color Depth 147 Params.Bits, // Select Our Color Depth
148 0, 0, 0, 0, 0, 0, // Color Bits Ignored 148 0, 0, 0, 0, 0, 0, // Color Bits Ignored
149 0, // No Alpha Buffer 149 0, // No Alpha Buffer
150 0, // Shift Bit Ignored 150 0, // Shift Bit Ignored
151 0, // No Accumulation Buffer 151 0, // No Accumulation Buffer
152 0, 0, 0, 0, // Accumulation Bits Ignored 152 0, 0, 0, 0, // Accumulation Bits Ignored
153 Params.ZBufferBits, // Z-Buffer (Depth Buffer) 153 Params.ZBufferBits, // Z-Buffer (Depth Buffer)
154 BYTE(Params.Stencilbuffer ? 1 : 0), // Stencil Buffer Depth 154 BYTE(Params.Stencilbuffer ? 1 : 0), // Stencil Buffer Depth
155 0, // No Auxiliary Buffer 155 0, // No Auxiliary Buffer
156 PFD_MAIN_PLANE, // Main Drawing Layer 156 PFD_MAIN_PLANE, // Main Drawing Layer
157 0, // Reserved 157 0, // Reserved
158 0, 0, 0 // Layer Masks Ignored 158 0, 0, 0 // Layer Masks Ignored
159 }; 159 };
160 160
161 GLuint PixelFormat; 161 GLuint PixelFormat;
162 162
163 for (u32 i=0; i<6; ++i) 163 for (u32 i=0; i<6; ++i)
164 { 164 {
165 if (i == 1) 165 if (i == 1)
166 { 166 {
167 if (Params.Stencilbuffer) 167 if (Params.Stencilbuffer)
168 { 168 {
169 os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); 169 os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
170 Params.Stencilbuffer = false; 170 Params.Stencilbuffer = false;
171 pfd.cStencilBits = 0; 171 pfd.cStencilBits = 0;
172 } 172 }
173 else 173 else
174 continue; 174 continue;
175 } 175 }
176 else 176 else
177 if (i == 2) 177 if (i == 2)
178 { 178 {
179 pfd.cDepthBits = 24; 179 pfd.cDepthBits = 24;
180 } 180 }
181 else 181 else
182 if (i == 3) 182 if (i == 3)
183 { 183 {
184 if (Params.Bits!=16) 184 if (Params.Bits!=16)
185 pfd.cDepthBits = 16; 185 pfd.cDepthBits = 16;
186 else 186 else
187 continue; 187 continue;
188 } 188 }
189 else 189 else
190 if (i == 4) 190 if (i == 4)
191 { 191 {
192 // try single buffer 192 // try single buffer
193 if (Params.Doublebuffer) 193 if (Params.Doublebuffer)
194 pfd.dwFlags &= ~PFD_DOUBLEBUFFER; 194 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
195 else 195 else
196 continue; 196 continue;
197 } 197 }
198 else 198 else
199 if (i == 5) 199 if (i == 5)
200 { 200 {
201 os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR); 201 os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR);
202 ReleaseDC(temporary_wnd, HDc); 202 ReleaseDC(temporary_wnd, HDc);
203 DestroyWindow(temporary_wnd); 203 DestroyWindow(temporary_wnd);
204 UnregisterClass(ClassName, lhInstance); 204 UnregisterClass(ClassName, lhInstance);
205 return false; 205 return false;
206 } 206 }
207 207
208 // choose pixelformat 208 // choose pixelformat
209 PixelFormat = ChoosePixelFormat(HDc, &pfd); 209 PixelFormat = ChoosePixelFormat(HDc, &pfd);
210 if (PixelFormat) 210 if (PixelFormat)
211 break; 211 break;
212 } 212 }
213 213
214 SetPixelFormat(HDc, PixelFormat, &pfd); 214 SetPixelFormat(HDc, PixelFormat, &pfd);
215 HGLRC hrc=wglCreateContext(HDc); 215 HGLRC hrc=wglCreateContext(HDc);
216 if (!hrc) 216 if (!hrc)
217 { 217 {
218 os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR); 218 os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR);
219 ReleaseDC(temporary_wnd, HDc); 219 ReleaseDC(temporary_wnd, HDc);
220 DestroyWindow(temporary_wnd); 220 DestroyWindow(temporary_wnd);
221 UnregisterClass(ClassName, lhInstance); 221 UnregisterClass(ClassName, lhInstance);
222 return false; 222 return false;
223 } 223 }
224 224
225 SExposedVideoData data; 225 SExposedVideoData data;
226 data.OpenGLWin32.HDc = HDc; 226 data.OpenGLWin32.HDc = HDc;
227 data.OpenGLWin32.HRc = hrc; 227 data.OpenGLWin32.HRc = hrc;
228 data.OpenGLWin32.HWnd = temporary_wnd; 228 data.OpenGLWin32.HWnd = temporary_wnd;
229 229
230 230
231 if (!changeRenderContext(data, device)) 231 if (!changeRenderContext(data, device))
232 { 232 {
233 os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR); 233 os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR);
234 wglDeleteContext(hrc); 234 wglDeleteContext(hrc);
235 ReleaseDC(temporary_wnd, HDc); 235 ReleaseDC(temporary_wnd, HDc);
236 DestroyWindow(temporary_wnd); 236 DestroyWindow(temporary_wnd);
237 UnregisterClass(ClassName, lhInstance); 237 UnregisterClass(ClassName, lhInstance);
238 return false; 238 return false;
239 } 239 }
240 240
241 core::stringc wglExtensions; 241 core::stringc wglExtensions;
242#ifdef WGL_ARB_extensions_string 242#ifdef WGL_ARB_extensions_string
243 PFNWGLGETEXTENSIONSSTRINGARBPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); 243 PFNWGLGETEXTENSIONSSTRINGARBPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
244 if (irrGetExtensionsString) 244 if (irrGetExtensionsString)
245 wglExtensions = irrGetExtensionsString(HDc); 245 wglExtensions = irrGetExtensionsString(HDc);
246#elif defined(WGL_EXT_extensions_string) 246#elif defined(WGL_EXT_extensions_string)
247 PFNWGLGETEXTENSIONSSTRINGEXTPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT"); 247 PFNWGLGETEXTENSIONSSTRINGEXTPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
248 if (irrGetExtensionsString) 248 if (irrGetExtensionsString)
249 wglExtensions = irrGetExtensionsString(HDc); 249 wglExtensions = irrGetExtensionsString(HDc);
250#endif 250#endif
251 const bool pixel_format_supported = (wglExtensions.find("WGL_ARB_pixel_format") != -1); 251 const bool pixel_format_supported = (wglExtensions.find("WGL_ARB_pixel_format") != -1);
252 const bool multi_sample_supported = ((wglExtensions.find("WGL_ARB_multisample") != -1) || 252 const bool multi_sample_supported = ((wglExtensions.find("WGL_ARB_multisample") != -1) ||
253 (wglExtensions.find("WGL_EXT_multisample") != -1) || (wglExtensions.find("WGL_3DFX_multisample") != -1) ); 253 (wglExtensions.find("WGL_EXT_multisample") != -1) || (wglExtensions.find("WGL_3DFX_multisample") != -1) );
254#ifdef _DEBUG 254#ifdef _DEBUG
255 os::Printer::log("WGL_extensions", wglExtensions); 255 os::Printer::log("WGL_extensions", wglExtensions);
256#endif 256#endif
257 257
258#ifdef WGL_ARB_pixel_format 258#ifdef WGL_ARB_pixel_format
259 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); 259 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
260 if (pixel_format_supported && wglChoosePixelFormat_ARB) 260 if (pixel_format_supported && wglChoosePixelFormat_ARB)
261 { 261 {
262 // This value determines the number of samples used for antialiasing 262 // This value determines the number of samples used for antialiasing
263 // My experience is that 8 does not show a big 263 // My experience is that 8 does not show a big
264 // improvement over 4, but 4 shows a big improvement 264 // improvement over 4, but 4 shows a big improvement
265 // over 2. 265 // over 2.
266 266
267 if(AntiAlias > 32) 267 if(AntiAlias > 32)
268 AntiAlias = 32; 268 AntiAlias = 32;
269 269
270 f32 fAttributes[] = {0.0, 0.0}; 270 f32 fAttributes[] = {0.0, 0.0};
271 s32 iAttributes[] = 271 s32 iAttributes[] =
272 { 272 {
273 WGL_DRAW_TO_WINDOW_ARB,1, 273 WGL_DRAW_TO_WINDOW_ARB,1,
274 WGL_SUPPORT_OPENGL_ARB,1, 274 WGL_SUPPORT_OPENGL_ARB,1,
275 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, 275 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
276 WGL_COLOR_BITS_ARB,(Params.Bits==32) ? 24 : 15, 276 WGL_COLOR_BITS_ARB,(Params.Bits==32) ? 24 : 15,
277 WGL_ALPHA_BITS_ARB,(Params.Bits==32) ? 8 : 1, 277 WGL_ALPHA_BITS_ARB,(Params.Bits==32) ? 8 : 1,
278 WGL_DEPTH_BITS_ARB,Params.ZBufferBits, // 10,11 278 WGL_DEPTH_BITS_ARB,Params.ZBufferBits, // 10,11
279 WGL_STENCIL_BITS_ARB,Params.Stencilbuffer ? 1 : 0, 279 WGL_STENCIL_BITS_ARB,Params.Stencilbuffer ? 1 : 0,
280 WGL_DOUBLE_BUFFER_ARB,Params.Doublebuffer ? 1 : 0, 280 WGL_DOUBLE_BUFFER_ARB,Params.Doublebuffer ? 1 : 0,
281 WGL_STEREO_ARB,Params.Stereobuffer ? 1 : 0, 281 WGL_STEREO_ARB,Params.Stereobuffer ? 1 : 0,
282 WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, 282 WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
283#ifdef WGL_ARB_multisample 283#ifdef WGL_ARB_multisample
284 WGL_SAMPLES_ARB,AntiAlias, // 20,21 284 WGL_SAMPLES_ARB,AntiAlias, // 20,21
285 WGL_SAMPLE_BUFFERS_ARB, 1, 285 WGL_SAMPLE_BUFFERS_ARB, 1,
286#elif defined(WGL_EXT_multisample) 286#elif defined(WGL_EXT_multisample)
287 WGL_SAMPLES_EXT,AntiAlias, // 20,21 287 WGL_SAMPLES_EXT,AntiAlias, // 20,21
288 WGL_SAMPLE_BUFFERS_EXT, 1, 288 WGL_SAMPLE_BUFFERS_EXT, 1,
289#elif defined(WGL_3DFX_multisample) 289#elif defined(WGL_3DFX_multisample)
290 WGL_SAMPLES_3DFX,AntiAlias, // 20,21 290 WGL_SAMPLES_3DFX,AntiAlias, // 20,21
291 WGL_SAMPLE_BUFFERS_3DFX, 1, 291 WGL_SAMPLE_BUFFERS_3DFX, 1,
292#endif 292#endif
293#ifdef WGL_ARB_framebuffer_sRGB 293#ifdef WGL_ARB_framebuffer_sRGB
294 WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB ? 1:0, 294 WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB ? 1:0,
295#elif defined(WGL_EXT_framebuffer_sRGB) 295#elif defined(WGL_EXT_framebuffer_sRGB)
296 WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB ? 1:0, 296 WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB ? 1:0,
297#endif 297#endif
298// WGL_DEPTH_FLOAT_EXT, 1, 298// WGL_DEPTH_FLOAT_EXT, 1,
299 0,0,0,0 299 0,0,0,0
300 }; 300 };
301 int iAttrSize = sizeof(iAttributes)/sizeof(int); 301 int iAttrSize = sizeof(iAttributes)/sizeof(int);
302 const bool framebuffer_srgb_supported = ((wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1) || 302 const bool framebuffer_srgb_supported = ((wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1) ||
303 (wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1)); 303 (wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1));
304 if (!framebuffer_srgb_supported) 304 if (!framebuffer_srgb_supported)
305 { 305 {
306 memmove(&iAttributes[24],&iAttributes[26],sizeof(int)*(iAttrSize-26)); 306 memmove(&iAttributes[24],&iAttributes[26],sizeof(int)*(iAttrSize-26));
307 iAttrSize -= 2; 307 iAttrSize -= 2;
308 } 308 }
309 if (!multi_sample_supported) 309 if (!multi_sample_supported)
310 { 310 {
311 memmove(&iAttributes[20],&iAttributes[24],sizeof(int)*(iAttrSize-24)); 311 memmove(&iAttributes[20],&iAttributes[24],sizeof(int)*(iAttrSize-24));
312 iAttrSize -= 4; 312 iAttrSize -= 4;
313 } 313 }
314 314
315 s32 rv=0; 315 s32 rv=0;
316 // Try to get an acceptable pixel format 316 // Try to get an acceptable pixel format
317 do 317 do
318 { 318 {
319 int pixelFormat=0; 319 int pixelFormat=0;
320 UINT numFormats=0; 320 UINT numFormats=0;
321 const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats); 321 const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
322 322
323 if (valid && numFormats) 323 if (valid && numFormats)
324 rv = pixelFormat; 324 rv = pixelFormat;
325 else 325 else
326 iAttributes[21] -= 1; 326 iAttributes[21] -= 1;
327 } 327 }
328 while(rv==0 && iAttributes[21]>1); 328 while(rv==0 && iAttributes[21]>1);
329 if (rv) 329 if (rv)
330 { 330 {
331 PixelFormat=rv; 331 PixelFormat=rv;
332 AntiAlias=iAttributes[21]; 332 AntiAlias=iAttributes[21];
333 } 333 }
334 } 334 }
335 else 335 else
336#endif 336#endif
337 AntiAlias=0; 337 AntiAlias=0;
338 338
339 wglMakeCurrent(HDc, NULL); 339 wglMakeCurrent(HDc, NULL);
340 wglDeleteContext(hrc); 340 wglDeleteContext(hrc);
341 ReleaseDC(temporary_wnd, HDc); 341 ReleaseDC(temporary_wnd, HDc);
342 DestroyWindow(temporary_wnd); 342 DestroyWindow(temporary_wnd);
343 UnregisterClass(ClassName, lhInstance); 343 UnregisterClass(ClassName, lhInstance);
344 344
345 // get hdc 345 // get hdc
346 HDc=GetDC(Window); 346 HDc=GetDC(Window);
347 if (!HDc) 347 if (!HDc)
348 { 348 {
349 os::Printer::log("Cannot create a GL device context.", ELL_ERROR); 349 os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
350 return false; 350 return false;
351 } 351 }
352 352
353 // search for pixel format the simple way 353 // search for pixel format the simple way
354 if (PixelFormat==0 || (!SetPixelFormat(HDc, PixelFormat, &pfd))) 354 if (PixelFormat==0 || (!SetPixelFormat(HDc, PixelFormat, &pfd)))
355 { 355 {
356 for (u32 i=0; i<5; ++i) 356 for (u32 i=0; i<5; ++i)
357 { 357 {
358 if (i == 1) 358 if (i == 1)
359 { 359 {
360 if (Params.Stencilbuffer) 360 if (Params.Stencilbuffer)
361 { 361 {
362 os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); 362 os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
363 Params.Stencilbuffer = false; 363 Params.Stencilbuffer = false;
364 pfd.cStencilBits = 0; 364 pfd.cStencilBits = 0;
365 } 365 }
366 else 366 else
367 continue; 367 continue;
368 } 368 }
369 else 369 else
370 if (i == 2) 370 if (i == 2)
371 { 371 {
372 pfd.cDepthBits = 24; 372 pfd.cDepthBits = 24;
373 } 373 }
374 if (i == 3) 374 if (i == 3)
375 { 375 {
376 if (Params.Bits!=16) 376 if (Params.Bits!=16)
377 pfd.cDepthBits = 16; 377 pfd.cDepthBits = 16;
378 else 378 else
379 continue; 379 continue;
380 } 380 }
381 else 381 else
382 if (i == 4) 382 if (i == 4)
383 { 383 {
384 os::Printer::log("Cannot create a GL device context", "No suitable format.", ELL_ERROR); 384 os::Printer::log("Cannot create a GL device context", "No suitable format.", ELL_ERROR);
385 return false; 385 return false;
386 } 386 }
387 387
388 // choose pixelformat 388 // choose pixelformat
389 PixelFormat = ChoosePixelFormat(HDc, &pfd); 389 PixelFormat = ChoosePixelFormat(HDc, &pfd);
390 if (PixelFormat) 390 if (PixelFormat)
391 break; 391 break;
392 } 392 }
393 } 393 }
394 394
395 // set pixel format 395 // set pixel format
396 if (!SetPixelFormat(HDc, PixelFormat, &pfd)) 396 if (!SetPixelFormat(HDc, PixelFormat, &pfd))
397 { 397 {
398 os::Printer::log("Cannot set the pixel format.", ELL_ERROR); 398 os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
399 return false; 399 return false;
400 } 400 }
401 os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG); 401 os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG);
402 402
403 // create rendering context 403 // create rendering context
404#ifdef WGL_ARB_create_context 404#ifdef WGL_ARB_create_context
405 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); 405 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
406 if (wglCreateContextAttribs_ARB) 406 if (wglCreateContextAttribs_ARB)
407 { 407 {
408 int iAttribs[] = 408 int iAttribs[] =
409 { 409 {
410 WGL_CONTEXT_MAJOR_VERSION_ARB, 3, 410 WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
411 WGL_CONTEXT_MINOR_VERSION_ARB, 1, 411 WGL_CONTEXT_MINOR_VERSION_ARB, 1,
412 0 412 0
413 }; 413 };
414 hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs); 414 hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs);
415 } 415 }
416 else 416 else
417#endif 417#endif
418 hrc=wglCreateContext(HDc); 418 hrc=wglCreateContext(HDc);
419 419
420 if (!hrc) 420 if (!hrc)
421 { 421 {
422 os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR); 422 os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR);
423 return false; 423 return false;
424 } 424 }
425 425
426 // set exposed data 426 // set exposed data
427 ExposedData.OpenGLWin32.HDc = HDc; 427 ExposedData.OpenGLWin32.HDc = HDc;
428 ExposedData.OpenGLWin32.HRc = hrc; 428 ExposedData.OpenGLWin32.HRc = hrc;
429 ExposedData.OpenGLWin32.HWnd = Window; 429 ExposedData.OpenGLWin32.HWnd = Window;
430 430
431 // activate rendering context 431 // activate rendering context
432 432
433 if (!changeRenderContext(ExposedData, device)) 433 if (!changeRenderContext(ExposedData, device))
434 { 434 {
435 os::Printer::log("Cannot activate GL rendering context", ELL_ERROR); 435 os::Printer::log("Cannot activate GL rendering context", ELL_ERROR);
436 wglDeleteContext(hrc); 436 wglDeleteContext(hrc);
437 return false; 437 return false;
438 } 438 }
439 439
440 int pf = GetPixelFormat(HDc); 440 int pf = GetPixelFormat(HDc);
441 DescribePixelFormat(HDc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); 441 DescribePixelFormat(HDc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
442 if (pfd.cAlphaBits != 0) 442 if (pfd.cAlphaBits != 0)
443 { 443 {
444 if (pfd.cRedBits == 8) 444 if (pfd.cRedBits == 8)
445 ColorFormat = ECF_A8R8G8B8; 445 ColorFormat = ECF_A8R8G8B8;
446 else 446 else
447 ColorFormat = ECF_A1R5G5B5; 447 ColorFormat = ECF_A1R5G5B5;
448 } 448 }
449 else 449 else
450 { 450 {
451 if (pfd.cRedBits == 8) 451 if (pfd.cRedBits == 8)
452 ColorFormat = ECF_R8G8B8; 452 ColorFormat = ECF_R8G8B8;
453 else 453 else
454 ColorFormat = ECF_R5G6B5; 454 ColorFormat = ECF_R5G6B5;
455 } 455 }
456 456
457 genericDriverInit(); 457 genericDriverInit();
458 458
459 extGlSwapInterval(Params.Vsync ? 1 : 0); 459 extGlSwapInterval(Params.Vsync ? 1 : 0);
460 return true; 460 return true;
461} 461}
462 462
463#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 463#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_
464 464
465// ----------------------------------------------------------------------- 465// -----------------------------------------------------------------------
466// MacOSX CONSTRUCTOR 466// MacOSX CONSTRUCTOR
467// ----------------------------------------------------------------------- 467// -----------------------------------------------------------------------
468#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ 468#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
469//! Windows constructor and init code 469//! Windows constructor and init code
470COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, 470COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
471 io::IFileSystem* io, CIrrDeviceMacOSX *device) 471 io::IFileSystem* io, CIrrDeviceMacOSX *device)
472: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), 472: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
473 CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), 473 CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
474 AntiAlias(params.AntiAlias), RenderTargetTexture(0), 474 AntiAlias(params.AntiAlias), RenderTargetTexture(0),
475 CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), 475 CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
476 CurrentTarget(ERT_FRAME_BUFFER), Params(params), 476 CurrentTarget(ERT_FRAME_BUFFER), Params(params),
477 OSXDevice(device), DeviceType(EIDT_OSX) 477 OSXDevice(device), DeviceType(EIDT_OSX)
478{ 478{
479 #ifdef _DEBUG 479 #ifdef _DEBUG
480 setDebugName("COpenGLDriver"); 480 setDebugName("COpenGLDriver");
481 #endif 481 #endif
482 482
483 #ifdef _IRR_COMPILE_WITH_CG_ 483 #ifdef _IRR_COMPILE_WITH_CG_
484 CgContext = 0; 484 CgContext = 0;
485 #endif 485 #endif
486 486
487 genericDriverInit(); 487 genericDriverInit();
488} 488}
489 489
490#endif 490#endif
491 491
492// ----------------------------------------------------------------------- 492// -----------------------------------------------------------------------
493// LINUX CONSTRUCTOR 493// LINUX CONSTRUCTOR
494// ----------------------------------------------------------------------- 494// -----------------------------------------------------------------------
495#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ 495#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
496//! Linux constructor and init code 496//! Linux constructor and init code
497COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, 497COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
498 io::IFileSystem* io, CIrrDeviceLinux* device) 498 io::IFileSystem* io, CIrrDeviceLinux* device)
499: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), 499: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
500 CurrentRenderMode(ERM_NONE), ResetRenderStates(true), 500 CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
501 Transformation3DChanged(true), AntiAlias(params.AntiAlias), 501 Transformation3DChanged(true), AntiAlias(params.AntiAlias),
502 RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), 502 RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
503 CurrentTarget(ERT_FRAME_BUFFER), Params(params), 503 CurrentTarget(ERT_FRAME_BUFFER), Params(params),
504 X11Device(device), DeviceType(EIDT_X11) 504 X11Device(device), DeviceType(EIDT_X11)
505{ 505{
506 #ifdef _DEBUG 506 #ifdef _DEBUG
507 setDebugName("COpenGLDriver"); 507 setDebugName("COpenGLDriver");
508 #endif 508 #endif
509 509
510 #ifdef _IRR_COMPILE_WITH_CG_ 510 #ifdef _IRR_COMPILE_WITH_CG_
511 CgContext = 0; 511 CgContext = 0;
512 #endif 512 #endif
513} 513}
514 514
515 515
516bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device) 516bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device)
517{ 517{
518 if (videoData.OpenGLLinux.X11Window) 518 if (videoData.OpenGLLinux.X11Window)
519 { 519 {
520 if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context) 520 if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context)
521 { 521 {
522 if (!glXMakeCurrent((Display*)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.X11Window, (GLXContext)videoData.OpenGLLinux.X11Context)) 522 if (!glXMakeCurrent((Display*)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.X11Window, (GLXContext)videoData.OpenGLLinux.X11Context))
523 { 523 {
524 os::Printer::log("Render Context switch failed."); 524 os::Printer::log("Render Context switch failed.");
525 return false; 525 return false;
526 } 526 }
527 else 527 else
528 { 528 {
529 Drawable = videoData.OpenGLLinux.X11Window; 529 Drawable = videoData.OpenGLLinux.X11Window;
530 X11Display = (Display*)videoData.OpenGLLinux.X11Display; 530 X11Display = (Display*)videoData.OpenGLLinux.X11Display;
531 } 531 }
532 } 532 }
533 else 533 else
534 { 534 {
535 // in case we only got a window ID, try with the existing values for display and context 535 // in case we only got a window ID, try with the existing values for display and context
536 if (!glXMakeCurrent((Display*)ExposedData.OpenGLLinux.X11Display, videoData.OpenGLLinux.X11Window, (GLXContext)ExposedData.OpenGLLinux.X11Context)) 536 if (!glXMakeCurrent((Display*)ExposedData.OpenGLLinux.X11Display, videoData.OpenGLLinux.X11Window, (GLXContext)ExposedData.OpenGLLinux.X11Context))
537 { 537 {
538 os::Printer::log("Render Context switch failed."); 538 os::Printer::log("Render Context switch failed.");
539 return false; 539 return false;
540 } 540 }
541 else 541 else
542 { 542 {
543 Drawable = videoData.OpenGLLinux.X11Window; 543 Drawable = videoData.OpenGLLinux.X11Window;
544 X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; 544 X11Display = (Display*)ExposedData.OpenGLLinux.X11Display;
545 } 545 }
546 } 546 }
547 } 547 }
548 // set back to main context 548 // set back to main context
549 else if (X11Display != ExposedData.OpenGLLinux.X11Display) 549 else if (X11Display != ExposedData.OpenGLLinux.X11Display)
550 { 550 {
551 if (!glXMakeCurrent((Display*)ExposedData.OpenGLLinux.X11Display, ExposedData.OpenGLLinux.X11Window, (GLXContext)ExposedData.OpenGLLinux.X11Context)) 551 if (!glXMakeCurrent((Display*)ExposedData.OpenGLLinux.X11Display, ExposedData.OpenGLLinux.X11Window, (GLXContext)ExposedData.OpenGLLinux.X11Context))
552 { 552 {
553 os::Printer::log("Render Context switch failed."); 553 os::Printer::log("Render Context switch failed.");
554 return false; 554 return false;
555 } 555 }
556 else 556 else
557 { 557 {
558 Drawable = ExposedData.OpenGLLinux.X11Window; 558 Drawable = ExposedData.OpenGLLinux.X11Window;
559 X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; 559 X11Display = (Display*)ExposedData.OpenGLLinux.X11Display;
560 } 560 }
561 } 561 }
562 return true; 562 return true;
563} 563}
564 564
565 565
566//! inits the open gl driver 566//! inits the open gl driver
567bool COpenGLDriver::initDriver(CIrrDeviceLinux* device) 567bool COpenGLDriver::initDriver(CIrrDeviceLinux* device)
568{ 568{
569 ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext(); 569 ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext();
570 ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay(); 570 ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay();
571 ExposedData.OpenGLLinux.X11Window = (unsigned long)Params.WindowId; 571 ExposedData.OpenGLLinux.X11Window = (unsigned long)Params.WindowId;
572 Drawable = glXGetCurrentDrawable(); 572 Drawable = glXGetCurrentDrawable();
573 X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; 573 X11Display = (Display*)ExposedData.OpenGLLinux.X11Display;
574 574
575 genericDriverInit(); 575 genericDriverInit();
576 576
577 // set vsync 577 // set vsync
578 extGlSwapInterval(Params.Vsync ? 1 : 0); 578 extGlSwapInterval(Params.Vsync ? 1 : 0);
579 return true; 579 return true;
580} 580}
581 581
582#endif // _IRR_COMPILE_WITH_X11_DEVICE_ 582#endif // _IRR_COMPILE_WITH_X11_DEVICE_
583 583
584 584
585// ----------------------------------------------------------------------- 585// -----------------------------------------------------------------------
586// SDL CONSTRUCTOR 586// SDL CONSTRUCTOR
587// ----------------------------------------------------------------------- 587// -----------------------------------------------------------------------
588#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ 588#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
589//! SDL constructor and init code 589//! SDL constructor and init code
590COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, 590COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
591 io::IFileSystem* io, CIrrDeviceSDL* device) 591 io::IFileSystem* io, CIrrDeviceSDL* device)
592: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), 592: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
593 CurrentRenderMode(ERM_NONE), ResetRenderStates(true), 593 CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
594 Transformation3DChanged(true), AntiAlias(params.AntiAlias), 594 Transformation3DChanged(true), AntiAlias(params.AntiAlias),
595 RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), 595 RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
596 CurrentTarget(ERT_FRAME_BUFFER), Params(params), 596 CurrentTarget(ERT_FRAME_BUFFER), Params(params),
597 SDLDevice(device), DeviceType(EIDT_SDL) 597 SDLDevice(device), DeviceType(EIDT_SDL)
598{ 598{
599 #ifdef _DEBUG 599 #ifdef _DEBUG
600 setDebugName("COpenGLDriver"); 600 setDebugName("COpenGLDriver");
601 #endif 601 #endif
602 602
603 #ifdef _IRR_COMPILE_WITH_CG_ 603 #ifdef _IRR_COMPILE_WITH_CG_
604 CgContext = 0; 604 CgContext = 0;
605 #endif 605 #endif
606 606
607 genericDriverInit(); 607 genericDriverInit();
608} 608}
609 609
610#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ 610#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
611 611
612 612
613//! destructor 613//! destructor
614COpenGLDriver::~COpenGLDriver() 614COpenGLDriver::~COpenGLDriver()
615{ 615{
616 #ifdef _IRR_COMPILE_WITH_CG_ 616 #ifdef _IRR_COMPILE_WITH_CG_
617 if (CgContext) 617 if (CgContext)
618 cgDestroyContext(CgContext); 618 cgDestroyContext(CgContext);
619 #endif 619 #endif
620 620
621 RequestedLights.clear(); 621 RequestedLights.clear();
622 622
623 deleteMaterialRenders(); 623 deleteMaterialRenders();
624 624
625 CurrentTexture.clear(); 625 CurrentTexture.clear();
626 // I get a blue screen on my laptop, when I do not delete the 626 // I get a blue screen on my laptop, when I do not delete the
627 // textures manually before releasing the dc. Oh how I love this. 627 // textures manually before releasing the dc. Oh how I love this.
628 deleteAllTextures(); 628 deleteAllTextures();
629 removeAllOcclusionQueries(); 629 removeAllOcclusionQueries();
630 removeAllHardwareBuffers(); 630 removeAllHardwareBuffers();
631 631
632#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 632#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
633 if (DeviceType == EIDT_WIN32) 633 if (DeviceType == EIDT_WIN32)
634 { 634 {
635 635
636 if (ExposedData.OpenGLWin32.HRc) 636 if (ExposedData.OpenGLWin32.HRc)
637 { 637 {
638 if (!wglMakeCurrent(HDc, 0)) 638 if (!wglMakeCurrent(HDc, 0))
639 os::Printer::log("Release of dc and rc failed.", ELL_WARNING); 639 os::Printer::log("Release of dc and rc failed.", ELL_WARNING);
640 640
641 if (!wglDeleteContext((HGLRC)ExposedData.OpenGLWin32.HRc)) 641 if (!wglDeleteContext((HGLRC)ExposedData.OpenGLWin32.HRc))
642 os::Printer::log("Release of rendering context failed.", ELL_WARNING); 642 os::Printer::log("Release of rendering context failed.", ELL_WARNING);
643 } 643 }
644 644
645 if (HDc) 645 if (HDc)
646 ReleaseDC(Window, HDc); 646 ReleaseDC(Window, HDc);
647 } 647 }
648#endif 648#endif
649} 649}
650 650
651// ----------------------------------------------------------------------- 651// -----------------------------------------------------------------------
652// METHODS 652// METHODS
653// ----------------------------------------------------------------------- 653// -----------------------------------------------------------------------
654 654
655bool COpenGLDriver::genericDriverInit() 655bool COpenGLDriver::genericDriverInit()
656{ 656{
657 Name=L"OpenGL "; 657 Name=L"OpenGL ";
658 Name.append(glGetString(GL_VERSION)); 658 Name.append(glGetString(GL_VERSION));
659 s32 pos=Name.findNext(L' ', 7); 659 s32 pos=Name.findNext(L' ', 7);
660 if (pos != -1) 660 if (pos != -1)
661 Name=Name.subString(0, pos); 661 Name=Name.subString(0, pos);
662 printVersion(); 662 printVersion();
663 663
664 // print renderer information 664 // print renderer information
665 const GLubyte* renderer = glGetString(GL_RENDERER); 665 const GLubyte* renderer = glGetString(GL_RENDERER);
666 const GLubyte* vendor = glGetString(GL_VENDOR); 666 const GLubyte* vendor = glGetString(GL_VENDOR);
667 if (renderer && vendor) 667 if (renderer && vendor)
668 { 668 {
669 os::Printer::log(reinterpret_cast<const c8*>(renderer), reinterpret_cast<const c8*>(vendor), ELL_INFORMATION); 669 os::Printer::log(reinterpret_cast<const c8*>(renderer), reinterpret_cast<const c8*>(vendor), ELL_INFORMATION);
670 VendorName = reinterpret_cast<const c8*>(vendor); 670 VendorName = reinterpret_cast<const c8*>(vendor);
671 } 671 }
672 672
673 u32 i; 673 u32 i;
674 CurrentTexture.clear(); 674 CurrentTexture.clear();
675 // load extensions 675 // load extensions
676 initExtensions(Params.Stencilbuffer); 676 initExtensions(Params.Stencilbuffer);
677 if (queryFeature(EVDF_ARB_GLSL)) 677 if (queryFeature(EVDF_ARB_GLSL))
678 { 678 {
679 char buf[32]; 679 char buf[32];
680 const u32 maj = ShaderLanguageVersion/100; 680 const u32 maj = ShaderLanguageVersion/100;
681 snprintf(buf, 32, "%u.%u", maj, ShaderLanguageVersion-maj*100); 681 snprintf(buf, 32, "%u.%u", maj, ShaderLanguageVersion-maj*100);
682 os::Printer::log("GLSL version", buf, ELL_INFORMATION); 682 os::Printer::log("GLSL version", buf, ELL_INFORMATION);
683 } 683 }
684 else 684 else
685 os::Printer::log("GLSL not available.", ELL_INFORMATION); 685 os::Printer::log("GLSL not available.", ELL_INFORMATION);
686 DriverAttributes->setAttribute("MaxTextures", MaxTextureUnits); 686 DriverAttributes->setAttribute("MaxTextures", MaxTextureUnits);
687 DriverAttributes->setAttribute("MaxSupportedTextures", MaxSupportedTextures); 687 DriverAttributes->setAttribute("MaxSupportedTextures", MaxSupportedTextures);
688 DriverAttributes->setAttribute("MaxLights", MaxLights); 688 DriverAttributes->setAttribute("MaxLights", MaxLights);
689 DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy); 689 DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy);
690 DriverAttributes->setAttribute("MaxUserClipPlanes", MaxUserClipPlanes); 690 DriverAttributes->setAttribute("MaxUserClipPlanes", MaxUserClipPlanes);
691 DriverAttributes->setAttribute("MaxAuxBuffers", MaxAuxBuffers); 691 DriverAttributes->setAttribute("MaxAuxBuffers", MaxAuxBuffers);
692 DriverAttributes->setAttribute("MaxMultipleRenderTargets", MaxMultipleRenderTargets); 692 DriverAttributes->setAttribute("MaxMultipleRenderTargets", MaxMultipleRenderTargets);
693 DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices); 693 DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices);
694 DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize); 694 DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize);
695 DriverAttributes->setAttribute("MaxGeometryVerticesOut", (s32)MaxGeometryVerticesOut); 695 DriverAttributes->setAttribute("MaxGeometryVerticesOut", (s32)MaxGeometryVerticesOut);
696 DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias); 696 DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias);
697 DriverAttributes->setAttribute("Version", Version); 697 DriverAttributes->setAttribute("Version", Version);
698 DriverAttributes->setAttribute("ShaderLanguageVersion", ShaderLanguageVersion); 698 DriverAttributes->setAttribute("ShaderLanguageVersion", ShaderLanguageVersion);
699 DriverAttributes->setAttribute("AntiAlias", AntiAlias); 699 DriverAttributes->setAttribute("AntiAlias", AntiAlias);
700 700
701 glPixelStorei(GL_PACK_ALIGNMENT, 1); 701 glPixelStorei(GL_PACK_ALIGNMENT, 1);
702 702
703 // Reset The Current Viewport 703 // Reset The Current Viewport
704 glViewport(0, 0, Params.WindowSize.Width, Params.WindowSize.Height); 704 glViewport(0, 0, Params.WindowSize.Width, Params.WindowSize.Height);
705 705
706 UserClipPlanes.reallocate(MaxUserClipPlanes); 706 UserClipPlanes.reallocate(MaxUserClipPlanes);
707 for (i=0; i<MaxUserClipPlanes; ++i) 707 for (i=0; i<MaxUserClipPlanes; ++i)
708 UserClipPlanes.push_back(SUserClipPlane()); 708 UserClipPlanes.push_back(SUserClipPlane());
709 709
710 for (i=0; i<ETS_COUNT; ++i) 710 for (i=0; i<ETS_COUNT; ++i)
711 setTransform(static_cast<E_TRANSFORMATION_STATE>(i), core::IdentityMatrix); 711 setTransform(static_cast<E_TRANSFORMATION_STATE>(i), core::IdentityMatrix);
712 712
713 setAmbientLight(SColorf(0.0f,0.0f,0.0f,0.0f)); 713 setAmbientLight(SColorf(0.0f,0.0f,0.0f,0.0f));
714#ifdef GL_EXT_separate_specular_color 714#ifdef GL_EXT_separate_specular_color
715 if (FeatureAvailable[IRR_EXT_separate_specular_color]) 715 if (FeatureAvailable[IRR_EXT_separate_specular_color])
716 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); 716 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
717#endif 717#endif
718 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); 718 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
719 719
720 Params.HandleSRGB &= ((FeatureAvailable[IRR_ARB_framebuffer_sRGB] || FeatureAvailable[IRR_EXT_framebuffer_sRGB]) && 720 Params.HandleSRGB &= ((FeatureAvailable[IRR_ARB_framebuffer_sRGB] || FeatureAvailable[IRR_EXT_framebuffer_sRGB]) &&
721 FeatureAvailable[IRR_EXT_texture_sRGB]); 721 FeatureAvailable[IRR_EXT_texture_sRGB]);
722#if defined(GL_ARB_framebuffer_sRGB) 722#if defined(GL_ARB_framebuffer_sRGB)
723 if (Params.HandleSRGB) 723 if (Params.HandleSRGB)
724 glEnable(GL_FRAMEBUFFER_SRGB); 724 glEnable(GL_FRAMEBUFFER_SRGB);
725#elif defined(GL_EXT_framebuffer_sRGB) 725#elif defined(GL_EXT_framebuffer_sRGB)
726 if (Params.HandleSRGB) 726 if (Params.HandleSRGB)
727 glEnable(GL_FRAMEBUFFER_SRGB_EXT); 727 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
728#endif 728#endif
729 729
730// This is a fast replacement for NORMALIZE_NORMALS 730// This is a fast replacement for NORMALIZE_NORMALS
731// if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal]) 731// if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal])
732// glEnable(GL_RESCALE_NORMAL_EXT); 732// glEnable(GL_RESCALE_NORMAL_EXT);
733 733
734 glClearDepth(1.0); 734 glClearDepth(1.0);
735 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 735 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
736 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 736 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
737 glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); 737 glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
738 glDepthFunc(GL_LEQUAL); 738 glDepthFunc(GL_LEQUAL);
739 glFrontFace(GL_CW); 739 glFrontFace(GL_CW);
740 // adjust flat coloring scheme to DirectX version 740 // adjust flat coloring scheme to DirectX version
741#if defined(GL_ARB_provoking_vertex) || defined(GL_EXT_provoking_vertex) 741#if defined(GL_ARB_provoking_vertex) || defined(GL_EXT_provoking_vertex)
742 extGlProvokingVertex(GL_FIRST_VERTEX_CONVENTION_EXT); 742 extGlProvokingVertex(GL_FIRST_VERTEX_CONVENTION_EXT);
743#endif 743#endif
744 744
745 // create material renderers 745 // create material renderers
746 createMaterialRenderers(); 746 createMaterialRenderers();
747 747
748 // set the renderstates 748 // set the renderstates
749 setRenderStates3DMode(); 749 setRenderStates3DMode();
750 750
751 glAlphaFunc(GL_GREATER, 0.f); 751 glAlphaFunc(GL_GREATER, 0.f);
752 752
753 // set fog mode 753 // set fog mode
754 setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); 754 setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog);
755 755
756 // create matrix for flipping textures 756 // create matrix for flipping textures
757 TextureFlipMatrix.buildTextureTransform(0.0f, core::vector2df(0,0), core::vector2df(0,1.0f), core::vector2df(1.0f,-1.0f)); 757 TextureFlipMatrix.buildTextureTransform(0.0f, core::vector2df(0,0), core::vector2df(0,1.0f), core::vector2df(1.0f,-1.0f));
758 758
759 // We need to reset once more at the beginning of the first rendering. 759 // We need to reset once more at the beginning of the first rendering.
760 // This fixes problems with intermediate changes to the material during texture load. 760 // This fixes problems with intermediate changes to the material during texture load.
761 ResetRenderStates = true; 761 ResetRenderStates = true;
762 762
763 #ifdef _IRR_COMPILE_WITH_CG_ 763 #ifdef _IRR_COMPILE_WITH_CG_
764 CgContext = cgCreateContext(); 764 CgContext = cgCreateContext();
765 #endif 765 #endif
766 766
767 return true; 767 return true;
768} 768}
769 769
770 770
771void COpenGLDriver::createMaterialRenderers() 771void COpenGLDriver::createMaterialRenderers()
772{ 772{
773 // create OpenGL material renderers 773 // create OpenGL material renderers
774 774
775 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SOLID(this)); 775 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SOLID(this));
776 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SOLID_2_LAYER(this)); 776 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SOLID_2_LAYER(this));
777 777
778 // add the same renderer for all lightmap types 778 // add the same renderer for all lightmap types
779 COpenGLMaterialRenderer_LIGHTMAP* lmr = new COpenGLMaterialRenderer_LIGHTMAP(this); 779 COpenGLMaterialRenderer_LIGHTMAP* lmr = new COpenGLMaterialRenderer_LIGHTMAP(this);
780 addMaterialRenderer(lmr); // for EMT_LIGHTMAP: 780 addMaterialRenderer(lmr); // for EMT_LIGHTMAP:
781 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: 781 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD:
782 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: 782 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2:
783 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: 783 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4:
784 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: 784 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING:
785 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: 785 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2:
786 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: 786 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4:
787 lmr->drop(); 787 lmr->drop();
788 788
789 // add remaining material renderer 789 // add remaining material renderer
790 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_DETAIL_MAP(this)); 790 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_DETAIL_MAP(this));
791 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SPHERE_MAP(this)); 791 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SPHERE_MAP(this));
792 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_REFLECTION_2_LAYER(this)); 792 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_REFLECTION_2_LAYER(this));
793 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(this)); 793 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(this));
794 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(this)); 794 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(this));
795 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(this)); 795 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(this));
796 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(this)); 796 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(this));
797 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(this)); 797 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(this));
798 798
799 // add normal map renderers 799 // add normal map renderers
800 s32 tmp = 0; 800 s32 tmp = 0;
801 video::IMaterialRenderer* renderer = 0; 801 video::IMaterialRenderer* renderer = 0;
802 renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer); 802 renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer);
803 renderer->drop(); 803 renderer->drop();
804 renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); 804 renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer);
805 renderer->drop(); 805 renderer->drop();
806 renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); 806 renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer);
807 renderer->drop(); 807 renderer->drop();
808 808
809 // add parallax map renderers 809 // add parallax map renderers
810 renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer); 810 renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer);
811 renderer->drop(); 811 renderer->drop();
812 renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); 812 renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer);
813 renderer->drop(); 813 renderer->drop();
814 renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); 814 renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer);
815 renderer->drop(); 815 renderer->drop();
816 816
817 // add basic 1 texture blending 817 // add basic 1 texture blending
818 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_ONETEXTURE_BLEND(this)); 818 addAndDropMaterialRenderer(new COpenGLMaterialRenderer_ONETEXTURE_BLEND(this));
819} 819}
820 820
821 821
822//! presents the rendered scene on the screen, returns false if failed 822//! presents the rendered scene on the screen, returns false if failed
823bool COpenGLDriver::endScene() 823bool COpenGLDriver::endScene()
824{ 824{
825 CNullDriver::endScene(); 825 CNullDriver::endScene();
826 826
827 glFlush(); 827 glFlush();
828 828
829#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 829#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
830 if (DeviceType == EIDT_WIN32) 830 if (DeviceType == EIDT_WIN32)
831 return SwapBuffers(HDc) == TRUE; 831 return SwapBuffers(HDc) == TRUE;
832#endif 832#endif
833 833
834#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ 834#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
835 if (DeviceType == EIDT_X11) 835 if (DeviceType == EIDT_X11)
836 { 836 {
837 glXSwapBuffers(X11Display, Drawable); 837 glXSwapBuffers(X11Display, Drawable);
838 return true; 838 return true;
839 } 839 }
840#endif 840#endif
841 841
842#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ 842#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
843 if (DeviceType == EIDT_OSX) 843 if (DeviceType == EIDT_OSX)
844 { 844 {
845 OSXDevice->flush(); 845 OSXDevice->flush();
846 return true; 846 return true;
847 } 847 }
848#endif 848#endif
849 849
850#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ 850#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
851 if (DeviceType == EIDT_SDL) 851 if (DeviceType == EIDT_SDL)
852 { 852 {
853 SDL_GL_SwapBuffers(); 853 SDL_GL_SwapBuffers();
854 return true; 854 return true;
855 } 855 }
856#endif 856#endif
857 857
858 // todo: console device present 858 // todo: console device present
859 859
860 return false; 860 return false;
861} 861}
862 862
863 863
864//! clears the zbuffer and color buffer 864//! clears the zbuffer and color buffer
865void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color) 865void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color)
866{ 866{
867 GLbitfield mask = 0; 867 GLbitfield mask = 0;
868 if (backBuffer) 868 if (backBuffer)
869 { 869 {
870 const f32 inv = 1.0f / 255.0f; 870 const f32 inv = 1.0f / 255.0f;
871 glClearColor(color.getRed() * inv, color.getGreen() * inv, 871 glClearColor(color.getRed() * inv, color.getGreen() * inv,
872 color.getBlue() * inv, color.getAlpha() * inv); 872 color.getBlue() * inv, color.getAlpha() * inv);
873 873
874 mask |= GL_COLOR_BUFFER_BIT; 874 mask |= GL_COLOR_BUFFER_BIT;
875 } 875 }
876 876
877 if (zBuffer) 877 if (zBuffer)
878 { 878 {
879 glDepthMask(GL_TRUE); 879 glDepthMask(GL_TRUE);
880 LastMaterial.ZWriteEnable=true; 880 LastMaterial.ZWriteEnable=true;
881 mask |= GL_DEPTH_BUFFER_BIT; 881 mask |= GL_DEPTH_BUFFER_BIT;
882 } 882 }
883 883
884 if (stencilBuffer) 884 if (stencilBuffer)
885 mask |= GL_STENCIL_BUFFER_BIT; 885 mask |= GL_STENCIL_BUFFER_BIT;
886 886
887 if (mask) 887 if (mask)
888 glClear(mask); 888 glClear(mask);
889} 889}
890 890
891 891
892//! init call for rendering start 892//! init call for rendering start
893bool COpenGLDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, 893bool COpenGLDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
894 const SExposedVideoData& videoData, core::rect<s32>* sourceRect) 894 const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
895{ 895{
896 CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); 896 CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect);
897 897
898 switch (DeviceType) 898 switch (DeviceType)
899 { 899 {
900#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 900#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
901 case EIDT_WIN32: 901 case EIDT_WIN32:
902 changeRenderContext(videoData, Win32Device); 902 changeRenderContext(videoData, Win32Device);
903 break; 903 break;
904#endif 904#endif
905#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ 905#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
906 case EIDT_X11: 906 case EIDT_X11:
907 changeRenderContext(videoData, X11Device); 907 changeRenderContext(videoData, X11Device);
908 break; 908 break;
909#endif 909#endif
910 default: 910 default:
911 changeRenderContext(videoData, (void*)0); 911 changeRenderContext(videoData, (void*)0);
912 break; 912 break;
913 } 913 }
914 914
915#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) 915#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
916 if (DeviceType == EIDT_SDL) 916 if (DeviceType == EIDT_SDL)
917 { 917 {
918 // todo: SDL sets glFrontFace(GL_CCW) after driver creation, 918 // todo: SDL sets glFrontFace(GL_CCW) after driver creation,
919 // it would be better if this was fixed elsewhere. 919 // it would be better if this was fixed elsewhere.
920 glFrontFace(GL_CW); 920 glFrontFace(GL_CW);
921 } 921 }
922#endif 922#endif
923 923
924 clearBuffers(backBuffer, zBuffer, false, color); 924 clearBuffers(backBuffer, zBuffer, false, color);
925 return true; 925 return true;
926} 926}
927 927
928 928
929//! Returns the transformation set by setTransform 929//! Returns the transformation set by setTransform
930const core::matrix4& COpenGLDriver::getTransform(E_TRANSFORMATION_STATE state) const 930const core::matrix4& COpenGLDriver::getTransform(E_TRANSFORMATION_STATE state) const
931{ 931{
932 return Matrices[state]; 932 return Matrices[state];
933} 933}
934 934
935 935
936//! sets transformation 936//! sets transformation
937void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) 937void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
938{ 938{
939 Matrices[state] = mat; 939 Matrices[state] = mat;
940 Transformation3DChanged = true; 940 Transformation3DChanged = true;
941 941
942 switch (state) 942 switch (state)
943 { 943 {
944 case ETS_VIEW: 944 case ETS_VIEW:
945 case ETS_WORLD: 945 case ETS_WORLD:
946 { 946 {
947 // OpenGL only has a model matrix, view and world is not existent. so lets fake these two. 947 // OpenGL only has a model matrix, view and world is not existent. so lets fake these two.
948 glMatrixMode(GL_MODELVIEW); 948 glMatrixMode(GL_MODELVIEW);
949 949
950 // first load the viewing transformation for user clip planes 950 // first load the viewing transformation for user clip planes
951 glLoadMatrixf((Matrices[ETS_VIEW]).pointer()); 951 glLoadMatrixf((Matrices[ETS_VIEW]).pointer());
952 952
953 // we have to update the clip planes to the latest view matrix 953 // we have to update the clip planes to the latest view matrix
954 for (u32 i=0; i<MaxUserClipPlanes; ++i) 954 for (u32 i=0; i<MaxUserClipPlanes; ++i)
955 if (UserClipPlanes[i].Enabled) 955 if (UserClipPlanes[i].Enabled)
956 uploadClipPlane(i); 956 uploadClipPlane(i);
957 957
958 // now the real model-view matrix 958 // now the real model-view matrix
959 glMultMatrixf(Matrices[ETS_WORLD].pointer()); 959 glMultMatrixf(Matrices[ETS_WORLD].pointer());
960 } 960 }
961 break; 961 break;
962 case ETS_PROJECTION: 962 case ETS_PROJECTION:
963 { 963 {
964 glMatrixMode(GL_PROJECTION); 964 glMatrixMode(GL_PROJECTION);
965 glLoadMatrixf(mat.pointer()); 965 glLoadMatrixf(mat.pointer());
966 } 966 }
967 break; 967 break;
968 case ETS_COUNT: 968 case ETS_COUNT:
969 return; 969 return;
970 default: 970 default:
971 { 971 {
972 const u32 i = state - ETS_TEXTURE_0; 972 const u32 i = state - ETS_TEXTURE_0;
973 if (i >= MATERIAL_MAX_TEXTURES) 973 if (i >= MATERIAL_MAX_TEXTURES)
974 break; 974 break;
975 975
976 const bool isRTT = Material.getTexture(i) && Material.getTexture(i)->isRenderTarget(); 976 const bool isRTT = Material.getTexture(i) && Material.getTexture(i)->isRenderTarget();
977 977
978 if (MultiTextureExtension) 978 if (MultiTextureExtension)
979 extGlActiveTexture(GL_TEXTURE0_ARB + i); 979 extGlActiveTexture(GL_TEXTURE0_ARB + i);
980 980
981 glMatrixMode(GL_TEXTURE); 981 glMatrixMode(GL_TEXTURE);
982 if (!isRTT && mat.isIdentity() ) 982 if (!isRTT && mat.isIdentity() )
983 glLoadIdentity(); 983 glLoadIdentity();
984 else 984 else
985 { 985 {
986 GLfloat glmat[16]; 986 GLfloat glmat[16];
987 if (isRTT) 987 if (isRTT)
988 getGLTextureMatrix(glmat, mat * TextureFlipMatrix); 988 getGLTextureMatrix(glmat, mat * TextureFlipMatrix);
989 else 989 else
990 getGLTextureMatrix(glmat, mat); 990 getGLTextureMatrix(glmat, mat);
991 glLoadMatrixf(glmat); 991 glLoadMatrixf(glmat);
992 } 992 }
993 break; 993 break;
994 } 994 }
995 } 995 }
996} 996}
997 997
998 998
999bool COpenGLDriver::updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer) 999bool COpenGLDriver::updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer)
1000{ 1000{
1001 if (!HWBuffer) 1001 if (!HWBuffer)
1002 return false; 1002 return false;
1003 1003
1004 if (!FeatureAvailable[IRR_ARB_vertex_buffer_object]) 1004 if (!FeatureAvailable[IRR_ARB_vertex_buffer_object])
1005 return false; 1005 return false;
1006 1006
1007#if defined(GL_ARB_vertex_buffer_object) 1007#if defined(GL_ARB_vertex_buffer_object)
1008 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; 1008 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
1009 const void* vertices=mb->getVertices(); 1009 const void* vertices=mb->getVertices();
1010 const u32 vertexCount=mb->getVertexCount(); 1010 const u32 vertexCount=mb->getVertexCount();
1011 const E_VERTEX_TYPE vType=mb->getVertexType(); 1011 const E_VERTEX_TYPE vType=mb->getVertexType();
1012 const u32 vertexSize = getVertexPitchFromType(vType); 1012 const u32 vertexSize = getVertexPitchFromType(vType);
1013 1013
1014 const c8* vbuf = static_cast<const c8*>(vertices); 1014 const c8* vbuf = static_cast<const c8*>(vertices);
1015 core::array<c8> buffer; 1015 core::array<c8> buffer;
1016 if (!FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra]) 1016 if (!FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
1017 { 1017 {
1018 //buffer vertex data, and convert colors... 1018 //buffer vertex data, and convert colors...
1019 buffer.set_used(vertexSize * vertexCount); 1019 buffer.set_used(vertexSize * vertexCount);
1020 memcpy(buffer.pointer(), vertices, vertexSize * vertexCount); 1020 memcpy(buffer.pointer(), vertices, vertexSize * vertexCount);
1021 vbuf = buffer.const_pointer(); 1021 vbuf = buffer.const_pointer();
1022 1022
1023 // in order to convert the colors into opengl format (RGBA) 1023 // in order to convert the colors into opengl format (RGBA)
1024 switch (vType) 1024 switch (vType)
1025 { 1025 {
1026 case EVT_STANDARD: 1026 case EVT_STANDARD:
1027 { 1027 {
1028 S3DVertex* pb = reinterpret_cast<S3DVertex*>(buffer.pointer()); 1028 S3DVertex* pb = reinterpret_cast<S3DVertex*>(buffer.pointer());
1029 const S3DVertex* po = static_cast<const S3DVertex*>(vertices); 1029 const S3DVertex* po = static_cast<const S3DVertex*>(vertices);
1030 for (u32 i=0; i<vertexCount; i++) 1030 for (u32 i=0; i<vertexCount; i++)
1031 { 1031 {
1032 po[i].Color.toOpenGLColor((u8*)&(pb[i].Color)); 1032 po[i].Color.toOpenGLColor((u8*)&(pb[i].Color));
1033 } 1033 }
1034 } 1034 }
1035 break; 1035 break;
1036 case EVT_2TCOORDS: 1036 case EVT_2TCOORDS:
1037 { 1037 {
1038 S3DVertex2TCoords* pb = reinterpret_cast<S3DVertex2TCoords*>(buffer.pointer()); 1038 S3DVertex2TCoords* pb = reinterpret_cast<S3DVertex2TCoords*>(buffer.pointer());
1039 const S3DVertex2TCoords* po = static_cast<const S3DVertex2TCoords*>(vertices); 1039 const S3DVertex2TCoords* po = static_cast<const S3DVertex2TCoords*>(vertices);
1040 for (u32 i=0; i<vertexCount; i++) 1040 for (u32 i=0; i<vertexCount; i++)
1041 { 1041 {
1042 po[i].Color.toOpenGLColor((u8*)&(pb[i].Color)); 1042 po[i].Color.toOpenGLColor((u8*)&(pb[i].Color));
1043 } 1043 }
1044 } 1044 }
1045 break; 1045 break;
1046 case EVT_TANGENTS: 1046 case EVT_TANGENTS:
1047 { 1047 {
1048 S3DVertexTangents* pb = reinterpret_cast<S3DVertexTangents*>(buffer.pointer()); 1048 S3DVertexTangents* pb = reinterpret_cast<S3DVertexTangents*>(buffer.pointer());
1049 const S3DVertexTangents* po = static_cast<const S3DVertexTangents*>(vertices); 1049 const S3DVertexTangents* po = static_cast<const S3DVertexTangents*>(vertices);
1050 for (u32 i=0; i<vertexCount; i++) 1050 for (u32 i=0; i<vertexCount; i++)
1051 { 1051 {
1052 po[i].Color.toOpenGLColor((u8*)&(pb[i].Color)); 1052 po[i].Color.toOpenGLColor((u8*)&(pb[i].Color));
1053 } 1053 }
1054 } 1054 }
1055 break; 1055 break;
1056 default: 1056 default:
1057 { 1057 {
1058 return false; 1058 return false;
1059 } 1059 }
1060 } 1060 }
1061 } 1061 }
1062 1062
1063 //get or create buffer 1063 //get or create buffer
1064 bool newBuffer=false; 1064 bool newBuffer=false;
1065 if (!HWBuffer->vbo_verticesID) 1065 if (!HWBuffer->vbo_verticesID)
1066 { 1066 {
1067 extGlGenBuffers(1, &HWBuffer->vbo_verticesID); 1067 extGlGenBuffers(1, &HWBuffer->vbo_verticesID);
1068 if (!HWBuffer->vbo_verticesID) 1068 if (!HWBuffer->vbo_verticesID)
1069 return false; 1069 return false;
1070 newBuffer=true; 1070 newBuffer=true;
1071 } 1071 }
1072 else if (HWBuffer->vbo_verticesSize < vertexCount*vertexSize) 1072 else if (HWBuffer->vbo_verticesSize < vertexCount*vertexSize)
1073 { 1073 {
1074 newBuffer=true; 1074 newBuffer=true;
1075 } 1075 }
1076 1076
1077 extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID); 1077 extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID);
1078 1078
1079 //copy data to graphics card 1079 //copy data to graphics card
1080 glGetError(); // clear error storage 1080 glGetError(); // clear error storage
1081 if (!newBuffer) 1081 if (!newBuffer)
1082 extGlBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, vbuf); 1082 extGlBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, vbuf);
1083 else 1083 else
1084 { 1084 {
1085 HWBuffer->vbo_verticesSize = vertexCount*vertexSize; 1085 HWBuffer->vbo_verticesSize = vertexCount*vertexSize;
1086 1086
1087 if (HWBuffer->Mapped_Vertex==scene::EHM_STATIC) 1087 if (HWBuffer->Mapped_Vertex==scene::EHM_STATIC)
1088 extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STATIC_DRAW); 1088 extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STATIC_DRAW);
1089 else if (HWBuffer->Mapped_Vertex==scene::EHM_DYNAMIC) 1089 else if (HWBuffer->Mapped_Vertex==scene::EHM_DYNAMIC)
1090 extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_DYNAMIC_DRAW); 1090 extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_DYNAMIC_DRAW);
1091 else //scene::EHM_STREAM 1091 else //scene::EHM_STREAM
1092 extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STREAM_DRAW); 1092 extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STREAM_DRAW);
1093 } 1093 }
1094 1094
1095 extGlBindBuffer(GL_ARRAY_BUFFER, 0); 1095 extGlBindBuffer(GL_ARRAY_BUFFER, 0);
1096 1096
1097 return (glGetError() == GL_NO_ERROR); 1097 return (glGetError() == GL_NO_ERROR);
1098#else 1098#else
1099 return false; 1099 return false;
1100#endif 1100#endif
1101} 1101}
1102 1102
1103 1103
1104bool COpenGLDriver::updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer) 1104bool COpenGLDriver::updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer)
1105{ 1105{
1106 if (!HWBuffer) 1106 if (!HWBuffer)
1107 return false; 1107 return false;
1108 1108
1109 if (!FeatureAvailable[IRR_ARB_vertex_buffer_object]) 1109 if (!FeatureAvailable[IRR_ARB_vertex_buffer_object])
1110 return false; 1110 return false;
1111 1111
1112#if defined(GL_ARB_vertex_buffer_object) 1112#if defined(GL_ARB_vertex_buffer_object)
1113 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; 1113 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
1114 1114
1115 const void* indices=mb->getIndices(); 1115 const void* indices=mb->getIndices();
1116 u32 indexCount= mb->getIndexCount(); 1116 u32 indexCount= mb->getIndexCount();
1117 1117
1118 GLenum indexSize; 1118 GLenum indexSize;
1119 switch (mb->getIndexType()) 1119 switch (mb->getIndexType())
1120 { 1120 {
1121 case EIT_16BIT: 1121 case EIT_16BIT:
1122 { 1122 {
1123 indexSize=sizeof(u16); 1123 indexSize=sizeof(u16);
1124 break; 1124 break;
1125 } 1125 }
1126 case EIT_32BIT: 1126 case EIT_32BIT:
1127 { 1127 {
1128 indexSize=sizeof(u32); 1128 indexSize=sizeof(u32);
1129 break; 1129 break;
1130 } 1130 }
1131 default: 1131 default:
1132 { 1132 {
1133 return false; 1133 return false;
1134 } 1134 }
1135 } 1135 }
1136 1136
1137 1137
1138 //get or create buffer 1138 //get or create buffer
1139 bool newBuffer=false; 1139 bool newBuffer=false;
1140 if (!HWBuffer->vbo_indicesID) 1140 if (!HWBuffer->vbo_indicesID)
1141 { 1141 {
1142 extGlGenBuffers(1, &HWBuffer->vbo_indicesID); 1142 extGlGenBuffers(1, &HWBuffer->vbo_indicesID);
1143 if (!HWBuffer->vbo_indicesID) 1143 if (!HWBuffer->vbo_indicesID)
1144 return false; 1144 return false;
1145 newBuffer=true; 1145 newBuffer=true;
1146 } 1146 }
1147 else if (HWBuffer->vbo_indicesSize < indexCount*indexSize) 1147 else if (HWBuffer->vbo_indicesSize < indexCount*indexSize)
1148 { 1148 {
1149 newBuffer=true; 1149 newBuffer=true;
1150 } 1150 }
1151 1151
1152 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID); 1152 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
1153 1153
1154 //copy data to graphics card 1154 //copy data to graphics card
1155 glGetError(); // clear error storage 1155 glGetError(); // clear error storage
1156 if (!newBuffer) 1156 if (!newBuffer)
1157 extGlBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexCount * indexSize, indices); 1157 extGlBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexCount * indexSize, indices);
1158 else 1158 else
1159 { 1159 {
1160 HWBuffer->vbo_indicesSize = indexCount*indexSize; 1160 HWBuffer->vbo_indicesSize = indexCount*indexSize;
1161 1161
1162 if (HWBuffer->Mapped_Index==scene::EHM_STATIC) 1162 if (HWBuffer->Mapped_Index==scene::EHM_STATIC)
1163 extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW); 1163 extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW);
1164 else if (HWBuffer->Mapped_Index==scene::EHM_DYNAMIC) 1164 else if (HWBuffer->Mapped_Index==scene::EHM_DYNAMIC)
1165 extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_DYNAMIC_DRAW); 1165 extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_DYNAMIC_DRAW);
1166 else //scene::EHM_STREAM 1166 else //scene::EHM_STREAM
1167 extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STREAM_DRAW); 1167 extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STREAM_DRAW);
1168 } 1168 }
1169 1169
1170 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1170 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1171 1171
1172 return (glGetError() == GL_NO_ERROR); 1172 return (glGetError() == GL_NO_ERROR);
1173#else 1173#else
1174 return false; 1174 return false;
1175#endif 1175#endif
1176} 1176}
1177 1177
1178 1178
1179//! updates hardware buffer if needed 1179//! updates hardware buffer if needed
1180bool COpenGLDriver::updateHardwareBuffer(SHWBufferLink *HWBuffer) 1180bool COpenGLDriver::updateHardwareBuffer(SHWBufferLink *HWBuffer)
1181{ 1181{
1182 if (!HWBuffer) 1182 if (!HWBuffer)
1183 return false; 1183 return false;
1184 1184
1185 if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) 1185 if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER)
1186 { 1186 {
1187 if (HWBuffer->ChangedID_Vertex != HWBuffer->MeshBuffer->getChangedID_Vertex() 1187 if (HWBuffer->ChangedID_Vertex != HWBuffer->MeshBuffer->getChangedID_Vertex()
1188 || !((SHWBufferLink_opengl*)HWBuffer)->vbo_verticesID) 1188 || !((SHWBufferLink_opengl*)HWBuffer)->vbo_verticesID)
1189 { 1189 {
1190 1190
1191 HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex(); 1191 HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex();
1192 1192
1193 if (!updateVertexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer)) 1193 if (!updateVertexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer))
1194 return false; 1194 return false;
1195 } 1195 }
1196 } 1196 }
1197 1197
1198 if (HWBuffer->Mapped_Index!=scene::EHM_NEVER) 1198 if (HWBuffer->Mapped_Index!=scene::EHM_NEVER)
1199 { 1199 {
1200 if (HWBuffer->ChangedID_Index != HWBuffer->MeshBuffer->getChangedID_Index() 1200 if (HWBuffer->ChangedID_Index != HWBuffer->MeshBuffer->getChangedID_Index()
1201 || !((SHWBufferLink_opengl*)HWBuffer)->vbo_indicesID) 1201 || !((SHWBufferLink_opengl*)HWBuffer)->vbo_indicesID)
1202 { 1202 {
1203 1203
1204 HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index(); 1204 HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index();
1205 1205
1206 if (!updateIndexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer)) 1206 if (!updateIndexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer))
1207 return false; 1207 return false;
1208 } 1208 }
1209 } 1209 }
1210 1210
1211 return true; 1211 return true;
1212} 1212}
1213 1213
1214 1214
1215//! Create hardware buffer from meshbuffer 1215//! Create hardware buffer from meshbuffer
1216COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::IMeshBuffer* mb) 1216COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::IMeshBuffer* mb)
1217{ 1217{
1218#if defined(GL_ARB_vertex_buffer_object) 1218#if defined(GL_ARB_vertex_buffer_object)
1219 if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) 1219 if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER))
1220 return 0; 1220 return 0;
1221 1221
1222 SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb); 1222 SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb);
1223 1223
1224 //add to map 1224 //add to map
1225 HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer); 1225 HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer);
1226 1226
1227 HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex(); 1227 HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex();
1228 HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index(); 1228 HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index();
1229 HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); 1229 HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex();
1230 HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); 1230 HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index();
1231 HWBuffer->LastUsed=0; 1231 HWBuffer->LastUsed=0;
1232 HWBuffer->vbo_verticesID=0; 1232 HWBuffer->vbo_verticesID=0;
1233 HWBuffer->vbo_indicesID=0; 1233 HWBuffer->vbo_indicesID=0;
1234 HWBuffer->vbo_verticesSize=0; 1234 HWBuffer->vbo_verticesSize=0;
1235 HWBuffer->vbo_indicesSize=0; 1235 HWBuffer->vbo_indicesSize=0;
1236 1236
1237 if (!updateHardwareBuffer(HWBuffer)) 1237 if (!updateHardwareBuffer(HWBuffer))
1238 { 1238 {
1239 deleteHardwareBuffer(HWBuffer); 1239 deleteHardwareBuffer(HWBuffer);
1240 return 0; 1240 return 0;
1241 } 1241 }
1242 1242
1243 return HWBuffer; 1243 return HWBuffer;
1244#else 1244#else
1245 return 0; 1245 return 0;
1246#endif 1246#endif
1247} 1247}
1248 1248
1249 1249
1250void COpenGLDriver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) 1250void COpenGLDriver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer)
1251{ 1251{
1252 if (!_HWBuffer) 1252 if (!_HWBuffer)
1253 return; 1253 return;
1254 1254
1255#if defined(GL_ARB_vertex_buffer_object) 1255#if defined(GL_ARB_vertex_buffer_object)
1256 SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer; 1256 SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;
1257 if (HWBuffer->vbo_verticesID) 1257 if (HWBuffer->vbo_verticesID)
1258 { 1258 {
1259 extGlDeleteBuffers(1, &HWBuffer->vbo_verticesID); 1259 extGlDeleteBuffers(1, &HWBuffer->vbo_verticesID);
1260 HWBuffer->vbo_verticesID=0; 1260 HWBuffer->vbo_verticesID=0;
1261 } 1261 }
1262 if (HWBuffer->vbo_indicesID) 1262 if (HWBuffer->vbo_indicesID)
1263 { 1263 {
1264 extGlDeleteBuffers(1, &HWBuffer->vbo_indicesID); 1264 extGlDeleteBuffers(1, &HWBuffer->vbo_indicesID);
1265 HWBuffer->vbo_indicesID=0; 1265 HWBuffer->vbo_indicesID=0;
1266 } 1266 }
1267#endif 1267#endif
1268 1268
1269 CNullDriver::deleteHardwareBuffer(_HWBuffer); 1269 CNullDriver::deleteHardwareBuffer(_HWBuffer);
1270} 1270}
1271 1271
1272 1272
1273//! Draw hardware buffer 1273//! Draw hardware buffer
1274void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) 1274void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
1275{ 1275{
1276 if (!_HWBuffer) 1276 if (!_HWBuffer)
1277 return; 1277 return;
1278 1278
1279 updateHardwareBuffer(_HWBuffer); //check if update is needed 1279 updateHardwareBuffer(_HWBuffer); //check if update is needed
1280 _HWBuffer->LastUsed=0; //reset count 1280 _HWBuffer->LastUsed=0; //reset count
1281 1281
1282#if defined(GL_ARB_vertex_buffer_object) 1282#if defined(GL_ARB_vertex_buffer_object)
1283 SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer; 1283 SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;
1284 1284
1285 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; 1285 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
1286 const void *vertices=mb->getVertices(); 1286 const void *vertices=mb->getVertices();
1287 const void *indexList=mb->getIndices(); 1287 const void *indexList=mb->getIndices();
1288 1288
1289 if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) 1289 if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER)
1290 { 1290 {
1291 extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID); 1291 extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID);
1292 vertices=0; 1292 vertices=0;
1293 } 1293 }
1294 1294
1295 if (HWBuffer->Mapped_Index!=scene::EHM_NEVER) 1295 if (HWBuffer->Mapped_Index!=scene::EHM_NEVER)
1296 { 1296 {
1297 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID); 1297 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
1298 indexList=0; 1298 indexList=0;
1299 } 1299 }
1300 1300
1301 drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); 1301 drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType());
1302 1302
1303 if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) 1303 if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER)
1304 extGlBindBuffer(GL_ARRAY_BUFFER, 0); 1304 extGlBindBuffer(GL_ARRAY_BUFFER, 0);
1305 if (HWBuffer->Mapped_Index!=scene::EHM_NEVER) 1305 if (HWBuffer->Mapped_Index!=scene::EHM_NEVER)
1306 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1306 extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1307#endif 1307#endif
1308} 1308}
1309 1309
1310 1310
1311//! Create occlusion query. 1311//! Create occlusion query.
1312/** Use node for identification and mesh for occlusion test. */ 1312/** Use node for identification and mesh for occlusion test. */
1313void COpenGLDriver::addOcclusionQuery(scene::ISceneNode* node, 1313void COpenGLDriver::addOcclusionQuery(scene::ISceneNode* node,
1314 const scene::IMesh* mesh) 1314 const scene::IMesh* mesh)
1315{ 1315{
1316 if (!queryFeature(EVDF_OCCLUSION_QUERY)) 1316 if (!queryFeature(EVDF_OCCLUSION_QUERY))
1317 return; 1317 return;
1318 1318
1319 CNullDriver::addOcclusionQuery(node, mesh); 1319 CNullDriver::addOcclusionQuery(node, mesh);
1320 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1320 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1321 if ((index != -1) && (OcclusionQueries[index].UID == 0)) 1321 if ((index != -1) && (OcclusionQueries[index].UID == 0))
1322 extGlGenQueries(1, reinterpret_cast<GLuint*>(&OcclusionQueries[index].UID)); 1322 extGlGenQueries(1, reinterpret_cast<GLuint*>(&OcclusionQueries[index].UID));
1323} 1323}
1324 1324
1325 1325
1326//! Remove occlusion query. 1326//! Remove occlusion query.
1327void COpenGLDriver::removeOcclusionQuery(scene::ISceneNode* node) 1327void COpenGLDriver::removeOcclusionQuery(scene::ISceneNode* node)
1328{ 1328{
1329 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1329 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1330 if (index != -1) 1330 if (index != -1)
1331 { 1331 {
1332 if (OcclusionQueries[index].UID != 0) 1332 if (OcclusionQueries[index].UID != 0)
1333 extGlDeleteQueries(1, reinterpret_cast<GLuint*>(&OcclusionQueries[index].UID)); 1333 extGlDeleteQueries(1, reinterpret_cast<GLuint*>(&OcclusionQueries[index].UID));
1334 CNullDriver::removeOcclusionQuery(node); 1334 CNullDriver::removeOcclusionQuery(node);
1335 } 1335 }
1336} 1336}
1337 1337
1338 1338
1339//! Run occlusion query. Draws mesh stored in query. 1339//! Run occlusion query. Draws mesh stored in query.
1340/** If the mesh shall not be rendered visible, use 1340/** If the mesh shall not be rendered visible, use
1341overrideMaterial to disable the color and depth buffer. */ 1341overrideMaterial to disable the color and depth buffer. */
1342void COpenGLDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) 1342void COpenGLDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible)
1343{ 1343{
1344 if (!node) 1344 if (!node)
1345 return; 1345 return;
1346 1346
1347 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1347 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1348 if (index != -1) 1348 if (index != -1)
1349 { 1349 {
1350 if (OcclusionQueries[index].UID) 1350 if (OcclusionQueries[index].UID)
1351 extGlBeginQuery( 1351 extGlBeginQuery(
1352#ifdef GL_ARB_occlusion_query 1352#ifdef GL_ARB_occlusion_query
1353 GL_SAMPLES_PASSED_ARB, 1353 GL_SAMPLES_PASSED_ARB,
1354#else 1354#else
1355 0, 1355 0,
1356#endif 1356#endif
1357 OcclusionQueries[index].UID); 1357 OcclusionQueries[index].UID);
1358 CNullDriver::runOcclusionQuery(node,visible); 1358 CNullDriver::runOcclusionQuery(node,visible);
1359 if (OcclusionQueries[index].UID) 1359 if (OcclusionQueries[index].UID)
1360 extGlEndQuery( 1360 extGlEndQuery(
1361#ifdef GL_ARB_occlusion_query 1361#ifdef GL_ARB_occlusion_query
1362 GL_SAMPLES_PASSED_ARB); 1362 GL_SAMPLES_PASSED_ARB);
1363#else 1363#else
1364 0); 1364 0);
1365#endif 1365#endif
1366 testGLError(); 1366 testGLError();
1367 } 1367 }
1368} 1368}
1369 1369
1370 1370
1371//! Update occlusion query. Retrieves results from GPU. 1371//! Update occlusion query. Retrieves results from GPU.
1372/** If the query shall not block, set the flag to false. 1372/** If the query shall not block, set the flag to false.
1373Update might not occur in this case, though */ 1373Update might not occur in this case, though */
1374void COpenGLDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block) 1374void COpenGLDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block)
1375{ 1375{
1376 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1376 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1377 if (index != -1) 1377 if (index != -1)
1378 { 1378 {
1379 // not yet started 1379 // not yet started
1380 if (OcclusionQueries[index].Run==u32(~0)) 1380 if (OcclusionQueries[index].Run==u32(~0))
1381 return; 1381 return;
1382 GLint available = block?GL_TRUE:GL_FALSE; 1382 GLint available = block?GL_TRUE:GL_FALSE;
1383 if (!block) 1383 if (!block)
1384 extGlGetQueryObjectiv(OcclusionQueries[index].UID, 1384 extGlGetQueryObjectiv(OcclusionQueries[index].UID,
1385#ifdef GL_ARB_occlusion_query 1385#ifdef GL_ARB_occlusion_query
1386 GL_QUERY_RESULT_AVAILABLE_ARB, 1386 GL_QUERY_RESULT_AVAILABLE_ARB,
1387#elif defined(GL_NV_occlusion_query) 1387#elif defined(GL_NV_occlusion_query)
1388 GL_PIXEL_COUNT_AVAILABLE_NV, 1388 GL_PIXEL_COUNT_AVAILABLE_NV,
1389#else 1389#else
1390 0, 1390 0,
1391#endif 1391#endif
1392 &available); 1392 &available);
1393 testGLError(); 1393 testGLError();
1394 if (available==GL_TRUE) 1394 if (available==GL_TRUE)
1395 { 1395 {
1396 extGlGetQueryObjectiv(OcclusionQueries[index].UID, 1396 extGlGetQueryObjectiv(OcclusionQueries[index].UID,
1397#ifdef GL_ARB_occlusion_query 1397#ifdef GL_ARB_occlusion_query
1398 GL_QUERY_RESULT_ARB, 1398 GL_QUERY_RESULT_ARB,
1399#elif defined(GL_NV_occlusion_query) 1399#elif defined(GL_NV_occlusion_query)
1400 GL_PIXEL_COUNT_NV, 1400 GL_PIXEL_COUNT_NV,
1401#else 1401#else
1402 0, 1402 0,
1403#endif 1403#endif
1404 &available); 1404 &available);
1405 if (queryFeature(EVDF_OCCLUSION_QUERY)) 1405 if (queryFeature(EVDF_OCCLUSION_QUERY))
1406 OcclusionQueries[index].Result = available; 1406 OcclusionQueries[index].Result = available;
1407 } 1407 }
1408 testGLError(); 1408 testGLError();
1409 } 1409 }
1410} 1410}
1411 1411
1412 1412
1413//! Return query result. 1413//! Return query result.
1414/** Return value is the number of visible pixels/fragments. 1414/** Return value is the number of visible pixels/fragments.
1415The value is a safe approximation, i.e. can be larger than the 1415The value is a safe approximation, i.e. can be larger than the
1416actual value of pixels. */ 1416actual value of pixels. */
1417u32 COpenGLDriver::getOcclusionQueryResult(scene::ISceneNode* node) const 1417u32 COpenGLDriver::getOcclusionQueryResult(scene::ISceneNode* node) const
1418{ 1418{
1419 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1419 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1420 if (index != -1) 1420 if (index != -1)
1421 return OcclusionQueries[index].Result; 1421 return OcclusionQueries[index].Result;
1422 else 1422 else
1423 return ~0; 1423 return ~0;
1424} 1424}
1425 1425
1426 1426
1427// small helper function to create vertex buffer object adress offsets 1427// small helper function to create vertex buffer object adress offsets
1428static inline u8* buffer_offset(const long offset) 1428static inline u8* buffer_offset(const long offset)
1429{ 1429{
1430 return ((u8*)0 + offset); 1430 return ((u8*)0 + offset);
1431} 1431}
1432 1432
1433 1433
1434//! draws a vertex primitive list 1434//! draws a vertex primitive list
1435void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, 1435void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
1436 const void* indexList, u32 primitiveCount, 1436 const void* indexList, u32 primitiveCount,
1437 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) 1437 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
1438{ 1438{
1439 if (!primitiveCount || !vertexCount) 1439 if (!primitiveCount || !vertexCount)
1440 return; 1440 return;
1441 1441
1442 if (!checkPrimitiveCount(primitiveCount)) 1442 if (!checkPrimitiveCount(primitiveCount))
1443 return; 1443 return;
1444 1444
1445 CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); 1445 CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);
1446 1446
1447 if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra]) 1447 if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
1448 getColorBuffer(vertices, vertexCount, vType); 1448 getColorBuffer(vertices, vertexCount, vType);
1449 1449
1450 // draw everything 1450 // draw everything
1451 setRenderStates3DMode(); 1451 setRenderStates3DMode();
1452 1452
1453 if (MultiTextureExtension) 1453 if (MultiTextureExtension)
1454 extGlClientActiveTexture(GL_TEXTURE0_ARB); 1454 extGlClientActiveTexture(GL_TEXTURE0_ARB);
1455 1455
1456 glEnableClientState(GL_COLOR_ARRAY); 1456 glEnableClientState(GL_COLOR_ARRAY);
1457 glEnableClientState(GL_VERTEX_ARRAY); 1457 glEnableClientState(GL_VERTEX_ARRAY);
1458 if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) 1458 if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
1459 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1459 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1460 if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) 1460 if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
1461 glEnableClientState(GL_NORMAL_ARRAY); 1461 glEnableClientState(GL_NORMAL_ARRAY);
1462 1462
1463//due to missing defines in OSX headers, we have to be more specific with this check 1463//due to missing defines in OSX headers, we have to be more specific with this check
1464//#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra) 1464//#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra)
1465#ifdef GL_BGRA 1465#ifdef GL_BGRA
1466 const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4; 1466 const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4;
1467#else 1467#else
1468 const GLint colorSize=4; 1468 const GLint colorSize=4;
1469#endif 1469#endif
1470 if (vertices) 1470 if (vertices)
1471 { 1471 {
1472 if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) 1472 if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
1473 { 1473 {
1474 switch (vType) 1474 switch (vType)
1475 { 1475 {
1476 case EVT_STANDARD: 1476 case EVT_STANDARD:
1477 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Color); 1477 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Color);
1478 break; 1478 break;
1479 case EVT_2TCOORDS: 1479 case EVT_2TCOORDS:
1480 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Color); 1480 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Color);
1481 break; 1481 break;
1482 case EVT_TANGENTS: 1482 case EVT_TANGENTS:
1483 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color); 1483 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
1484 break; 1484 break;
1485 } 1485 }
1486 } 1486 }
1487 else 1487 else
1488 { 1488 {
1489 // avoid passing broken pointer to OpenGL 1489 // avoid passing broken pointer to OpenGL
1490 _IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0); 1490 _IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0);
1491 glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); 1491 glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
1492 } 1492 }
1493 } 1493 }
1494 1494
1495 switch (vType) 1495 switch (vType)
1496 { 1496 {
1497 case EVT_STANDARD: 1497 case EVT_STANDARD:
1498 if (vertices) 1498 if (vertices)
1499 { 1499 {
1500 glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Normal); 1500 glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Normal);
1501 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords); 1501 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords);
1502 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Pos); 1502 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Pos);
1503 } 1503 }
1504 else 1504 else
1505 { 1505 {
1506 glNormalPointer(GL_FLOAT, sizeof(S3DVertex), buffer_offset(12)); 1506 glNormalPointer(GL_FLOAT, sizeof(S3DVertex), buffer_offset(12));
1507 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24)); 1507 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24));
1508 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); 1508 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28));
1509 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), 0); 1509 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), 0);
1510 } 1510 }
1511 1511
1512 if (MultiTextureExtension && CurrentTexture[1]) 1512 if (MultiTextureExtension && CurrentTexture[1])
1513 { 1513 {
1514 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1514 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1515 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1515 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1516 if (vertices) 1516 if (vertices)
1517 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords); 1517 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords);
1518 else 1518 else
1519 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); 1519 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28));
1520 } 1520 }
1521 break; 1521 break;
1522 case EVT_2TCOORDS: 1522 case EVT_2TCOORDS:
1523 if (vertices) 1523 if (vertices)
1524 { 1524 {
1525 glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Normal); 1525 glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Normal);
1526 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords); 1526 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords);
1527 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Pos); 1527 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Pos);
1528 } 1528 }
1529 else 1529 else
1530 { 1530 {
1531 glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(12)); 1531 glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(12));
1532 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); 1532 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24));
1533 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); 1533 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28));
1534 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0)); 1534 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0));
1535 } 1535 }
1536 1536
1537 1537
1538 if (MultiTextureExtension) 1538 if (MultiTextureExtension)
1539 { 1539 {
1540 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1540 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1541 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1541 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1542 if (vertices) 1542 if (vertices)
1543 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords2); 1543 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords2);
1544 else 1544 else
1545 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36)); 1545 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36));
1546 } 1546 }
1547 break; 1547 break;
1548 case EVT_TANGENTS: 1548 case EVT_TANGENTS:
1549 if (vertices) 1549 if (vertices)
1550 { 1550 {
1551 glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Normal); 1551 glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Normal);
1552 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].TCoords); 1552 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].TCoords);
1553 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Pos); 1553 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Pos);
1554 } 1554 }
1555 else 1555 else
1556 { 1556 {
1557 glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(12)); 1557 glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(12));
1558 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24)); 1558 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24));
1559 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28)); 1559 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28));
1560 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); 1560 glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0));
1561 } 1561 }
1562 1562
1563 if (MultiTextureExtension) 1563 if (MultiTextureExtension)
1564 { 1564 {
1565 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1565 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1566 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1566 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1567 if (vertices) 1567 if (vertices)
1568 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Tangent); 1568 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Tangent);
1569 else 1569 else
1570 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(36)); 1570 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(36));
1571 1571
1572 extGlClientActiveTexture(GL_TEXTURE2_ARB); 1572 extGlClientActiveTexture(GL_TEXTURE2_ARB);
1573 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1573 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1574 if (vertices) 1574 if (vertices)
1575 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Binormal); 1575 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Binormal);
1576 else 1576 else
1577 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48)); 1577 glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48));
1578 } 1578 }
1579 break; 1579 break;
1580 } 1580 }
1581 1581
1582 renderArray(indexList, primitiveCount, pType, iType); 1582 renderArray(indexList, primitiveCount, pType, iType);
1583 1583
1584 if (MultiTextureExtension) 1584 if (MultiTextureExtension)
1585 { 1585 {
1586 if (vType==EVT_TANGENTS) 1586 if (vType==EVT_TANGENTS)
1587 { 1587 {
1588 extGlClientActiveTexture(GL_TEXTURE2_ARB); 1588 extGlClientActiveTexture(GL_TEXTURE2_ARB);
1589 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1589 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1590 } 1590 }
1591 if ((vType!=EVT_STANDARD) || CurrentTexture[1]) 1591 if ((vType!=EVT_STANDARD) || CurrentTexture[1])
1592 { 1592 {
1593 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1593 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1594 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1594 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1595 } 1595 }
1596 extGlClientActiveTexture(GL_TEXTURE0_ARB); 1596 extGlClientActiveTexture(GL_TEXTURE0_ARB);
1597 } 1597 }
1598 glDisableClientState(GL_COLOR_ARRAY); 1598 glDisableClientState(GL_COLOR_ARRAY);
1599 glDisableClientState(GL_VERTEX_ARRAY); 1599 glDisableClientState(GL_VERTEX_ARRAY);
1600 glDisableClientState(GL_NORMAL_ARRAY); 1600 glDisableClientState(GL_NORMAL_ARRAY);
1601 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1601 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1602} 1602}
1603 1603
1604 1604
1605void COpenGLDriver::getColorBuffer(const void* vertices, u32 vertexCount, E_VERTEX_TYPE vType) 1605void COpenGLDriver::getColorBuffer(const void* vertices, u32 vertexCount, E_VERTEX_TYPE vType)
1606{ 1606{
1607 // convert colors to gl color format. 1607 // convert colors to gl color format.
1608 vertexCount *= 4; //reused as color component count 1608 vertexCount *= 4; //reused as color component count
1609 ColorBuffer.set_used(vertexCount); 1609 ColorBuffer.set_used(vertexCount);
1610 u32 i; 1610 u32 i;
1611 1611
1612 switch (vType) 1612 switch (vType)
1613 { 1613 {
1614 case EVT_STANDARD: 1614 case EVT_STANDARD:
1615 { 1615 {
1616 const S3DVertex* p = static_cast<const S3DVertex*>(vertices); 1616 const S3DVertex* p = static_cast<const S3DVertex*>(vertices);
1617 for (i=0; i<vertexCount; i+=4) 1617 for (i=0; i<vertexCount; i+=4)
1618 { 1618 {
1619 p->Color.toOpenGLColor(&ColorBuffer[i]); 1619 p->Color.toOpenGLColor(&ColorBuffer[i]);
1620 ++p; 1620 ++p;
1621 } 1621 }
1622 } 1622 }
1623 break; 1623 break;
1624 case EVT_2TCOORDS: 1624 case EVT_2TCOORDS:
1625 { 1625 {
1626 const S3DVertex2TCoords* p = static_cast<const S3DVertex2TCoords*>(vertices); 1626 const S3DVertex2TCoords* p = static_cast<const S3DVertex2TCoords*>(vertices);
1627 for (i=0; i<vertexCount; i+=4) 1627 for (i=0; i<vertexCount; i+=4)
1628 { 1628 {
1629 p->Color.toOpenGLColor(&ColorBuffer[i]); 1629 p->Color.toOpenGLColor(&ColorBuffer[i]);
1630 ++p; 1630 ++p;
1631 } 1631 }
1632 } 1632 }
1633 break; 1633 break;
1634 case EVT_TANGENTS: 1634 case EVT_TANGENTS:
1635 { 1635 {
1636 const S3DVertexTangents* p = static_cast<const S3DVertexTangents*>(vertices); 1636 const S3DVertexTangents* p = static_cast<const S3DVertexTangents*>(vertices);
1637 for (i=0; i<vertexCount; i+=4) 1637 for (i=0; i<vertexCount; i+=4)
1638 { 1638 {
1639 p->Color.toOpenGLColor(&ColorBuffer[i]); 1639 p->Color.toOpenGLColor(&ColorBuffer[i]);
1640 ++p; 1640 ++p;
1641 } 1641 }
1642 } 1642 }
1643 break; 1643 break;
1644 } 1644 }
1645} 1645}
1646 1646
1647 1647
1648void COpenGLDriver::renderArray(const void* indexList, u32 primitiveCount, 1648void COpenGLDriver::renderArray(const void* indexList, u32 primitiveCount,
1649 scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) 1649 scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
1650{ 1650{
1651 GLenum indexSize=0; 1651 GLenum indexSize=0;
1652 1652
1653 switch (iType) 1653 switch (iType)
1654 { 1654 {
1655 case EIT_16BIT: 1655 case EIT_16BIT:
1656 { 1656 {
1657 indexSize=GL_UNSIGNED_SHORT; 1657 indexSize=GL_UNSIGNED_SHORT;
1658 break; 1658 break;
1659 } 1659 }
1660 case EIT_32BIT: 1660 case EIT_32BIT:
1661 { 1661 {
1662 indexSize=GL_UNSIGNED_INT; 1662 indexSize=GL_UNSIGNED_INT;
1663 break; 1663 break;
1664 } 1664 }
1665 } 1665 }
1666 1666
1667 switch (pType) 1667 switch (pType)
1668 { 1668 {
1669 case scene::EPT_POINTS: 1669 case scene::EPT_POINTS:
1670 case scene::EPT_POINT_SPRITES: 1670 case scene::EPT_POINT_SPRITES:
1671 { 1671 {
1672#ifdef GL_ARB_point_sprite 1672#ifdef GL_ARB_point_sprite
1673 if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) 1673 if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
1674 glEnable(GL_POINT_SPRITE_ARB); 1674 glEnable(GL_POINT_SPRITE_ARB);
1675#endif 1675#endif
1676 1676
1677 // prepare size and attenuation (where supported) 1677 // prepare size and attenuation (where supported)
1678 GLfloat particleSize=Material.Thickness; 1678 GLfloat particleSize=Material.Thickness;
1679// if (AntiAlias) 1679// if (AntiAlias)
1680// particleSize=core::clamp(particleSize, DimSmoothedPoint[0], DimSmoothedPoint[1]); 1680// particleSize=core::clamp(particleSize, DimSmoothedPoint[0], DimSmoothedPoint[1]);
1681// else 1681// else
1682 particleSize=core::clamp(particleSize, DimAliasedPoint[0], DimAliasedPoint[1]); 1682 particleSize=core::clamp(particleSize, DimAliasedPoint[0], DimAliasedPoint[1]);
1683#if defined(GL_VERSION_1_4) || defined(GL_ARB_point_parameters) || defined(GL_EXT_point_parameters) || defined(GL_SGIS_point_parameters) 1683#if defined(GL_VERSION_1_4) || defined(GL_ARB_point_parameters) || defined(GL_EXT_point_parameters) || defined(GL_SGIS_point_parameters)
1684 const float att[] = {1.0f, 1.0f, 0.0f}; 1684 const float att[] = {1.0f, 1.0f, 0.0f};
1685#if defined(GL_VERSION_1_4) 1685#if defined(GL_VERSION_1_4)
1686 extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, att); 1686 extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, att);
1687// extGlPointParameterf(GL_POINT_SIZE_MIN,1.f); 1687// extGlPointParameterf(GL_POINT_SIZE_MIN,1.f);
1688 extGlPointParameterf(GL_POINT_SIZE_MAX, particleSize); 1688 extGlPointParameterf(GL_POINT_SIZE_MAX, particleSize);
1689 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, 1.0f); 1689 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, 1.0f);
1690#elif defined(GL_ARB_point_parameters) 1690#elif defined(GL_ARB_point_parameters)
1691 extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION_ARB, att); 1691 extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1692// extGlPointParameterf(GL_POINT_SIZE_MIN_ARB,1.f); 1692// extGlPointParameterf(GL_POINT_SIZE_MIN_ARB,1.f);
1693 extGlPointParameterf(GL_POINT_SIZE_MAX_ARB, particleSize); 1693 extGlPointParameterf(GL_POINT_SIZE_MAX_ARB, particleSize);
1694 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0f); 1694 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0f);
1695#elif defined(GL_EXT_point_parameters) 1695#elif defined(GL_EXT_point_parameters)
1696 extGlPointParameterfv(GL_DISTANCE_ATTENUATION_EXT, att); 1696 extGlPointParameterfv(GL_DISTANCE_ATTENUATION_EXT, att);
1697// extGlPointParameterf(GL_POINT_SIZE_MIN_EXT,1.f); 1697// extGlPointParameterf(GL_POINT_SIZE_MIN_EXT,1.f);
1698 extGlPointParameterf(GL_POINT_SIZE_MAX_EXT, particleSize); 1698 extGlPointParameterf(GL_POINT_SIZE_MAX_EXT, particleSize);
1699 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1.0f); 1699 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1.0f);
1700#elif defined(GL_SGIS_point_parameters) 1700#elif defined(GL_SGIS_point_parameters)
1701 extGlPointParameterfv(GL_DISTANCE_ATTENUATION_SGIS, att); 1701 extGlPointParameterfv(GL_DISTANCE_ATTENUATION_SGIS, att);
1702// extGlPointParameterf(GL_POINT_SIZE_MIN_SGIS,1.f); 1702// extGlPointParameterf(GL_POINT_SIZE_MIN_SGIS,1.f);
1703 extGlPointParameterf(GL_POINT_SIZE_MAX_SGIS, particleSize); 1703 extGlPointParameterf(GL_POINT_SIZE_MAX_SGIS, particleSize);
1704 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_SGIS, 1.0f); 1704 extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_SGIS, 1.0f);
1705#endif 1705#endif
1706#endif 1706#endif
1707 glPointSize(particleSize); 1707 glPointSize(particleSize);
1708 1708
1709#ifdef GL_ARB_point_sprite 1709#ifdef GL_ARB_point_sprite
1710 if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) 1710 if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
1711 glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_TRUE); 1711 glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_TRUE);
1712#endif 1712#endif
1713 glDrawArrays(GL_POINTS, 0, primitiveCount); 1713 glDrawArrays(GL_POINTS, 0, primitiveCount);
1714#ifdef GL_ARB_point_sprite 1714#ifdef GL_ARB_point_sprite
1715 if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) 1715 if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite])
1716 { 1716 {
1717 glDisable(GL_POINT_SPRITE_ARB); 1717 glDisable(GL_POINT_SPRITE_ARB);
1718 glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE); 1718 glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE);
1719 } 1719 }
1720#endif 1720#endif
1721 } 1721 }
1722 break; 1722 break;
1723 case scene::EPT_LINE_STRIP: 1723 case scene::EPT_LINE_STRIP:
1724 glDrawElements(GL_LINE_STRIP, primitiveCount+1, indexSize, indexList); 1724 glDrawElements(GL_LINE_STRIP, primitiveCount+1, indexSize, indexList);
1725 break; 1725 break;
1726 case scene::EPT_LINE_LOOP: 1726 case scene::EPT_LINE_LOOP:
1727 glDrawElements(GL_LINE_LOOP, primitiveCount, indexSize, indexList); 1727 glDrawElements(GL_LINE_LOOP, primitiveCount, indexSize, indexList);
1728 break; 1728 break;
1729 case scene::EPT_LINES: 1729 case scene::EPT_LINES:
1730 glDrawElements(GL_LINES, primitiveCount*2, indexSize, indexList); 1730 glDrawElements(GL_LINES, primitiveCount*2, indexSize, indexList);
1731 break; 1731 break;
1732 case scene::EPT_TRIANGLE_STRIP: 1732 case scene::EPT_TRIANGLE_STRIP:
1733 glDrawElements(GL_TRIANGLE_STRIP, primitiveCount+2, indexSize, indexList); 1733 glDrawElements(GL_TRIANGLE_STRIP, primitiveCount+2, indexSize, indexList);
1734 break; 1734 break;
1735 case scene::EPT_TRIANGLE_FAN: 1735 case scene::EPT_TRIANGLE_FAN:
1736 glDrawElements(GL_TRIANGLE_FAN, primitiveCount+2, indexSize, indexList); 1736 glDrawElements(GL_TRIANGLE_FAN, primitiveCount+2, indexSize, indexList);
1737 break; 1737 break;
1738 case scene::EPT_TRIANGLES: 1738 case scene::EPT_TRIANGLES:
1739 glDrawElements(GL_TRIANGLES, primitiveCount*3, indexSize, indexList); 1739 glDrawElements(GL_TRIANGLES, primitiveCount*3, indexSize, indexList);
1740 break; 1740 break;
1741 case scene::EPT_QUAD_STRIP: 1741 case scene::EPT_QUAD_STRIP:
1742 glDrawElements(GL_QUAD_STRIP, primitiveCount*2+2, indexSize, indexList); 1742 glDrawElements(GL_QUAD_STRIP, primitiveCount*2+2, indexSize, indexList);
1743 break; 1743 break;
1744 case scene::EPT_QUADS: 1744 case scene::EPT_QUADS:
1745 glDrawElements(GL_QUADS, primitiveCount*4, indexSize, indexList); 1745 glDrawElements(GL_QUADS, primitiveCount*4, indexSize, indexList);
1746 break; 1746 break;
1747 case scene::EPT_POLYGON: 1747 case scene::EPT_POLYGON:
1748 glDrawElements(GL_POLYGON, primitiveCount, indexSize, indexList); 1748 glDrawElements(GL_POLYGON, primitiveCount, indexSize, indexList);
1749 break; 1749 break;
1750 } 1750 }
1751} 1751}
1752 1752
1753 1753
1754//! draws a vertex primitive list in 2d 1754//! draws a vertex primitive list in 2d
1755void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, 1755void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
1756 const void* indexList, u32 primitiveCount, 1756 const void* indexList, u32 primitiveCount,
1757 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) 1757 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
1758{ 1758{
1759 if (!primitiveCount || !vertexCount) 1759 if (!primitiveCount || !vertexCount)
1760 return; 1760 return;
1761 1761
1762 if (!checkPrimitiveCount(primitiveCount)) 1762 if (!checkPrimitiveCount(primitiveCount))
1763 return; 1763 return;
1764 1764
1765 CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); 1765 CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);
1766 1766
1767 if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra]) 1767 if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
1768 getColorBuffer(vertices, vertexCount, vType); 1768 getColorBuffer(vertices, vertexCount, vType);
1769 1769
1770 // draw everything 1770 // draw everything
1771 this->setActiveTexture(0, Material.getTexture(0)); 1771 this->setActiveTexture(0, Material.getTexture(0));
1772 if (Material.MaterialType==EMT_ONETEXTURE_BLEND) 1772 if (Material.MaterialType==EMT_ONETEXTURE_BLEND)
1773 { 1773 {
1774 E_BLEND_FACTOR srcFact; 1774 E_BLEND_FACTOR srcFact;
1775 E_BLEND_FACTOR dstFact; 1775 E_BLEND_FACTOR dstFact;
1776 E_MODULATE_FUNC modulo; 1776 E_MODULATE_FUNC modulo;
1777 u32 alphaSource; 1777 u32 alphaSource;
1778 unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); 1778 unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam);
1779 setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); 1779 setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0);
1780 } 1780 }
1781 else 1781 else
1782 setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); 1782 setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL);
1783 1783
1784 if (MultiTextureExtension) 1784 if (MultiTextureExtension)
1785 extGlClientActiveTexture(GL_TEXTURE0_ARB); 1785 extGlClientActiveTexture(GL_TEXTURE0_ARB);
1786 1786
1787 glEnableClientState(GL_COLOR_ARRAY); 1787 glEnableClientState(GL_COLOR_ARRAY);
1788 glEnableClientState(GL_VERTEX_ARRAY); 1788 glEnableClientState(GL_VERTEX_ARRAY);
1789 if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) 1789 if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
1790 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1790 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1791 1791
1792//due to missing defines in OSX headers, we have to be more specific with this check 1792//due to missing defines in OSX headers, we have to be more specific with this check
1793//#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra) 1793//#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra)
1794#ifdef GL_BGRA 1794#ifdef GL_BGRA
1795 const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4; 1795 const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4;
1796#else 1796#else
1797 const GLint colorSize=4; 1797 const GLint colorSize=4;
1798#endif 1798#endif
1799 if (vertices) 1799 if (vertices)
1800 { 1800 {
1801 if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) 1801 if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
1802 { 1802 {
1803 switch (vType) 1803 switch (vType)
1804 { 1804 {
1805 case EVT_STANDARD: 1805 case EVT_STANDARD:
1806 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Color); 1806 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Color);
1807 break; 1807 break;
1808 case EVT_2TCOORDS: 1808 case EVT_2TCOORDS:
1809 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Color); 1809 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Color);
1810 break; 1810 break;
1811 case EVT_TANGENTS: 1811 case EVT_TANGENTS:
1812 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color); 1812 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
1813 break; 1813 break;
1814 } 1814 }
1815 } 1815 }
1816 else 1816 else
1817 { 1817 {
1818 // avoid passing broken pointer to OpenGL 1818 // avoid passing broken pointer to OpenGL
1819 _IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0); 1819 _IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0);
1820 glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); 1820 glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
1821 } 1821 }
1822 } 1822 }
1823 1823
1824 switch (vType) 1824 switch (vType)
1825 { 1825 {
1826 case EVT_STANDARD: 1826 case EVT_STANDARD:
1827 if (vertices) 1827 if (vertices)
1828 { 1828 {
1829 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords); 1829 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords);
1830 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Pos); 1830 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Pos);
1831 } 1831 }
1832 else 1832 else
1833 { 1833 {
1834 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24)); 1834 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24));
1835 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); 1835 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28));
1836 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), 0); 1836 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), 0);
1837 } 1837 }
1838 1838
1839 if (MultiTextureExtension && CurrentTexture[1]) 1839 if (MultiTextureExtension && CurrentTexture[1])
1840 { 1840 {
1841 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1841 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1842 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1842 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1843 if (vertices) 1843 if (vertices)
1844 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords); 1844 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords);
1845 else 1845 else
1846 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); 1846 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28));
1847 } 1847 }
1848 break; 1848 break;
1849 case EVT_2TCOORDS: 1849 case EVT_2TCOORDS:
1850 if (vertices) 1850 if (vertices)
1851 { 1851 {
1852 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords); 1852 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords);
1853 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Pos); 1853 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Pos);
1854 } 1854 }
1855 else 1855 else
1856 { 1856 {
1857 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); 1857 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24));
1858 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); 1858 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28));
1859 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0)); 1859 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0));
1860 } 1860 }
1861 1861
1862 if (MultiTextureExtension) 1862 if (MultiTextureExtension)
1863 { 1863 {
1864 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1864 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1865 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1865 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1866 if (vertices) 1866 if (vertices)
1867 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords2); 1867 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords2);
1868 else 1868 else
1869 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36)); 1869 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36));
1870 } 1870 }
1871 break; 1871 break;
1872 case EVT_TANGENTS: 1872 case EVT_TANGENTS:
1873 if (vertices) 1873 if (vertices)
1874 { 1874 {
1875 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].TCoords); 1875 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].TCoords);
1876 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Pos); 1876 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Pos);
1877 } 1877 }
1878 else 1878 else
1879 { 1879 {
1880 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24)); 1880 glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24));
1881 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28)); 1881 glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28));
1882 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); 1882 glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0));
1883 } 1883 }
1884 1884
1885 break; 1885 break;
1886 } 1886 }
1887 1887
1888 renderArray(indexList, primitiveCount, pType, iType); 1888 renderArray(indexList, primitiveCount, pType, iType);
1889 1889
1890 if (MultiTextureExtension) 1890 if (MultiTextureExtension)
1891 { 1891 {
1892 if ((vType!=EVT_STANDARD) || CurrentTexture[1]) 1892 if ((vType!=EVT_STANDARD) || CurrentTexture[1])
1893 { 1893 {
1894 extGlClientActiveTexture(GL_TEXTURE1_ARB); 1894 extGlClientActiveTexture(GL_TEXTURE1_ARB);
1895 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1895 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1896 } 1896 }
1897 extGlClientActiveTexture(GL_TEXTURE0_ARB); 1897 extGlClientActiveTexture(GL_TEXTURE0_ARB);
1898 } 1898 }
1899 glDisableClientState(GL_COLOR_ARRAY); 1899 glDisableClientState(GL_COLOR_ARRAY);
1900 glDisableClientState(GL_VERTEX_ARRAY); 1900 glDisableClientState(GL_VERTEX_ARRAY);
1901 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1901 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1902} 1902}
1903 1903
1904 1904
1905//! draws a set of 2d images, using a color and the alpha channel of the 1905//! draws a set of 2d images, using a color and the alpha channel of the
1906//! texture if desired. 1906//! texture if desired.
1907void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture, 1907void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture,
1908 const core::array<core::position2d<s32> >& positions, 1908 const core::array<core::position2d<s32> >& positions,
1909 const core::array<core::rect<s32> >& sourceRects, 1909 const core::array<core::rect<s32> >& sourceRects,
1910 const core::rect<s32>* clipRect, 1910 const core::rect<s32>* clipRect,
1911 SColor color, 1911 SColor color,
1912 bool useAlphaChannelOfTexture) 1912 bool useAlphaChannelOfTexture)
1913{ 1913{
1914 if (!texture) 1914 if (!texture)
1915 return; 1915 return;
1916 1916
1917 const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size()); 1917 const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
1918 1918
1919 const core::dimension2d<u32>& ss = texture->getOriginalSize(); 1919 const core::dimension2d<u32>& ss = texture->getOriginalSize();
1920 const f32 invW = 1.f / static_cast<f32>(ss.Width); 1920 const f32 invW = 1.f / static_cast<f32>(ss.Width);
1921 const f32 invH = 1.f / static_cast<f32>(ss.Height); 1921 const f32 invH = 1.f / static_cast<f32>(ss.Height);
1922 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 1922 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
1923 1923
1924 disableTextures(1); 1924 disableTextures(1);
1925 if (!setActiveTexture(0, texture)) 1925 if (!setActiveTexture(0, texture))
1926 return; 1926 return;
1927 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); 1927 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
1928 1928
1929 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 1929 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
1930 glBegin(GL_QUADS); 1930 glBegin(GL_QUADS);
1931 1931
1932 for (u32 i=0; i<drawCount; ++i) 1932 for (u32 i=0; i<drawCount; ++i)
1933 { 1933 {
1934 if (!sourceRects[i].isValid()) 1934 if (!sourceRects[i].isValid())
1935 continue; 1935 continue;
1936 1936
1937 core::position2d<s32> targetPos(positions[i]); 1937 core::position2d<s32> targetPos(positions[i]);
1938 core::position2d<s32> sourcePos(sourceRects[i].UpperLeftCorner); 1938 core::position2d<s32> sourcePos(sourceRects[i].UpperLeftCorner);
1939 // This needs to be signed as it may go negative. 1939 // This needs to be signed as it may go negative.
1940 core::dimension2d<s32> sourceSize(sourceRects[i].getSize()); 1940 core::dimension2d<s32> sourceSize(sourceRects[i].getSize());
1941 if (clipRect) 1941 if (clipRect)
1942 { 1942 {
1943 if (targetPos.X < clipRect->UpperLeftCorner.X) 1943 if (targetPos.X < clipRect->UpperLeftCorner.X)
1944 { 1944 {
1945 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; 1945 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
1946 if (sourceSize.Width <= 0) 1946 if (sourceSize.Width <= 0)
1947 continue; 1947 continue;
1948 1948
1949 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; 1949 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
1950 targetPos.X = clipRect->UpperLeftCorner.X; 1950 targetPos.X = clipRect->UpperLeftCorner.X;
1951 } 1951 }
1952 1952
1953 if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) 1953 if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X)
1954 { 1954 {
1955 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; 1955 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
1956 if (sourceSize.Width <= 0) 1956 if (sourceSize.Width <= 0)
1957 continue; 1957 continue;
1958 } 1958 }
1959 1959
1960 if (targetPos.Y < clipRect->UpperLeftCorner.Y) 1960 if (targetPos.Y < clipRect->UpperLeftCorner.Y)
1961 { 1961 {
1962 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; 1962 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
1963 if (sourceSize.Height <= 0) 1963 if (sourceSize.Height <= 0)
1964 continue; 1964 continue;
1965 1965
1966 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; 1966 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
1967 targetPos.Y = clipRect->UpperLeftCorner.Y; 1967 targetPos.Y = clipRect->UpperLeftCorner.Y;
1968 } 1968 }
1969 1969
1970 if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) 1970 if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y)
1971 { 1971 {
1972 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; 1972 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
1973 if (sourceSize.Height <= 0) 1973 if (sourceSize.Height <= 0)
1974 continue; 1974 continue;
1975 } 1975 }
1976 } 1976 }
1977 1977
1978 // clip these coordinates 1978 // clip these coordinates
1979 1979
1980 if (targetPos.X<0) 1980 if (targetPos.X<0)
1981 { 1981 {
1982 sourceSize.Width += targetPos.X; 1982 sourceSize.Width += targetPos.X;
1983 if (sourceSize.Width <= 0) 1983 if (sourceSize.Width <= 0)
1984 continue; 1984 continue;
1985 1985
1986 sourcePos.X -= targetPos.X; 1986 sourcePos.X -= targetPos.X;
1987 targetPos.X = 0; 1987 targetPos.X = 0;
1988 } 1988 }
1989 1989
1990 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) 1990 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
1991 { 1991 {
1992 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; 1992 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
1993 if (sourceSize.Width <= 0) 1993 if (sourceSize.Width <= 0)
1994 continue; 1994 continue;
1995 } 1995 }
1996 1996
1997 if (targetPos.Y<0) 1997 if (targetPos.Y<0)
1998 { 1998 {
1999 sourceSize.Height += targetPos.Y; 1999 sourceSize.Height += targetPos.Y;
2000 if (sourceSize.Height <= 0) 2000 if (sourceSize.Height <= 0)
2001 continue; 2001 continue;
2002 2002
2003 sourcePos.Y -= targetPos.Y; 2003 sourcePos.Y -= targetPos.Y;
2004 targetPos.Y = 0; 2004 targetPos.Y = 0;
2005 } 2005 }
2006 2006
2007 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) 2007 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
2008 { 2008 {
2009 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; 2009 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
2010 if (sourceSize.Height <= 0) 2010 if (sourceSize.Height <= 0)
2011 continue; 2011 continue;
2012 } 2012 }
2013 2013
2014 // ok, we've clipped everything. 2014 // ok, we've clipped everything.
2015 // now draw it. 2015 // now draw it.
2016 2016
2017 const core::rect<f32> tcoords( 2017 const core::rect<f32> tcoords(
2018 sourcePos.X * invW, 2018 sourcePos.X * invW,
2019 sourcePos.Y * invH, 2019 sourcePos.Y * invH,
2020 (sourcePos.X + sourceSize.Width) * invW, 2020 (sourcePos.X + sourceSize.Width) * invW,
2021 (sourcePos.Y + sourceSize.Height) * invH); 2021 (sourcePos.Y + sourceSize.Height) * invH);
2022 2022
2023 const core::rect<s32> poss(targetPos, sourceSize); 2023 const core::rect<s32> poss(targetPos, sourceSize);
2024 2024
2025 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); 2025 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
2026 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); 2026 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y));
2027 2027
2028 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); 2028 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
2029 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); 2029 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y));
2030 2030
2031 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); 2031 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
2032 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); 2032 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y));
2033 2033
2034 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); 2034 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
2035 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); 2035 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y));
2036 } 2036 }
2037 glEnd(); 2037 glEnd();
2038} 2038}
2039 2039
2040 2040
2041//! draws a 2d image, using a color and the alpha channel of the texture if 2041//! draws a 2d image, using a color and the alpha channel of the texture if
2042//! desired. The image is drawn at pos, clipped against clipRect (if != 0). 2042//! desired. The image is drawn at pos, clipped against clipRect (if != 0).
2043//! Only the subtexture defined by sourceRect is used. 2043//! Only the subtexture defined by sourceRect is used.
2044void COpenGLDriver::draw2DImage(const video::ITexture* texture, 2044void COpenGLDriver::draw2DImage(const video::ITexture* texture,
2045 const core::position2d<s32>& pos, 2045 const core::position2d<s32>& pos,
2046 const core::rect<s32>& sourceRect, 2046 const core::rect<s32>& sourceRect,
2047 const core::rect<s32>* clipRect, SColor color, 2047 const core::rect<s32>* clipRect, SColor color,
2048 bool useAlphaChannelOfTexture) 2048 bool useAlphaChannelOfTexture)
2049{ 2049{
2050 if (!texture) 2050 if (!texture)
2051 return; 2051 return;
2052 2052
2053 if (!sourceRect.isValid()) 2053 if (!sourceRect.isValid())
2054 return; 2054 return;
2055 2055
2056 core::position2d<s32> targetPos(pos); 2056 core::position2d<s32> targetPos(pos);
2057 core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner); 2057 core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner);
2058 // This needs to be signed as it may go negative. 2058 // This needs to be signed as it may go negative.
2059 core::dimension2d<s32> sourceSize(sourceRect.getSize()); 2059 core::dimension2d<s32> sourceSize(sourceRect.getSize());
2060 if (clipRect) 2060 if (clipRect)
2061 { 2061 {
2062 if (targetPos.X < clipRect->UpperLeftCorner.X) 2062 if (targetPos.X < clipRect->UpperLeftCorner.X)
2063 { 2063 {
2064 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; 2064 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
2065 if (sourceSize.Width <= 0) 2065 if (sourceSize.Width <= 0)
2066 return; 2066 return;
2067 2067
2068 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; 2068 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
2069 targetPos.X = clipRect->UpperLeftCorner.X; 2069 targetPos.X = clipRect->UpperLeftCorner.X;
2070 } 2070 }
2071 2071
2072 if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) 2072 if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X)
2073 { 2073 {
2074 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; 2074 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
2075 if (sourceSize.Width <= 0) 2075 if (sourceSize.Width <= 0)
2076 return; 2076 return;
2077 } 2077 }
2078 2078
2079 if (targetPos.Y < clipRect->UpperLeftCorner.Y) 2079 if (targetPos.Y < clipRect->UpperLeftCorner.Y)
2080 { 2080 {
2081 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; 2081 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
2082 if (sourceSize.Height <= 0) 2082 if (sourceSize.Height <= 0)
2083 return; 2083 return;
2084 2084
2085 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; 2085 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
2086 targetPos.Y = clipRect->UpperLeftCorner.Y; 2086 targetPos.Y = clipRect->UpperLeftCorner.Y;
2087 } 2087 }
2088 2088
2089 if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) 2089 if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y)
2090 { 2090 {
2091 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; 2091 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
2092 if (sourceSize.Height <= 0) 2092 if (sourceSize.Height <= 0)
2093 return; 2093 return;
2094 } 2094 }
2095 } 2095 }
2096 2096
2097 // clip these coordinates 2097 // clip these coordinates
2098 2098
2099 if (targetPos.X<0) 2099 if (targetPos.X<0)
2100 { 2100 {
2101 sourceSize.Width += targetPos.X; 2101 sourceSize.Width += targetPos.X;
2102 if (sourceSize.Width <= 0) 2102 if (sourceSize.Width <= 0)
2103 return; 2103 return;
2104 2104
2105 sourcePos.X -= targetPos.X; 2105 sourcePos.X -= targetPos.X;
2106 targetPos.X = 0; 2106 targetPos.X = 0;
2107 } 2107 }
2108 2108
2109 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 2109 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
2110 2110
2111 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) 2111 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
2112 { 2112 {
2113 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; 2113 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
2114 if (sourceSize.Width <= 0) 2114 if (sourceSize.Width <= 0)
2115 return; 2115 return;
2116 } 2116 }
2117 2117
2118 if (targetPos.Y<0) 2118 if (targetPos.Y<0)
2119 { 2119 {
2120 sourceSize.Height += targetPos.Y; 2120 sourceSize.Height += targetPos.Y;
2121 if (sourceSize.Height <= 0) 2121 if (sourceSize.Height <= 0)
2122 return; 2122 return;
2123 2123
2124 sourcePos.Y -= targetPos.Y; 2124 sourcePos.Y -= targetPos.Y;
2125 targetPos.Y = 0; 2125 targetPos.Y = 0;
2126 } 2126 }
2127 2127
2128 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) 2128 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
2129 { 2129 {
2130 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; 2130 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
2131 if (sourceSize.Height <= 0) 2131 if (sourceSize.Height <= 0)
2132 return; 2132 return;
2133 } 2133 }
2134 2134
2135 // ok, we've clipped everything. 2135 // ok, we've clipped everything.
2136 // now draw it. 2136 // now draw it.
2137 2137
2138 const core::dimension2d<u32>& ss = texture->getOriginalSize(); 2138 const core::dimension2d<u32>& ss = texture->getOriginalSize();
2139 const f32 invW = 1.f / static_cast<f32>(ss.Width); 2139 const f32 invW = 1.f / static_cast<f32>(ss.Width);
2140 const f32 invH = 1.f / static_cast<f32>(ss.Height); 2140 const f32 invH = 1.f / static_cast<f32>(ss.Height);
2141 const core::rect<f32> tcoords( 2141 const core::rect<f32> tcoords(
2142 sourcePos.X * invW, 2142 sourcePos.X * invW,
2143 sourcePos.Y * invH, 2143 sourcePos.Y * invH,
2144 (sourcePos.X + sourceSize.Width) * invW, 2144 (sourcePos.X + sourceSize.Width) * invW,
2145 (sourcePos.Y + sourceSize.Height) * invH); 2145 (sourcePos.Y + sourceSize.Height) * invH);
2146 2146
2147 const core::rect<s32> poss(targetPos, sourceSize); 2147 const core::rect<s32> poss(targetPos, sourceSize);
2148 2148
2149 disableTextures(1); 2149 disableTextures(1);
2150 if (!setActiveTexture(0, texture)) 2150 if (!setActiveTexture(0, texture))
2151 return; 2151 return;
2152 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); 2152 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
2153 2153
2154 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 2154 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
2155 glBegin(GL_QUADS); 2155 glBegin(GL_QUADS);
2156 2156
2157 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); 2157 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
2158 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); 2158 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y));
2159 2159
2160 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); 2160 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
2161 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); 2161 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y));
2162 2162
2163 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); 2163 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
2164 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); 2164 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y));
2165 2165
2166 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); 2166 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
2167 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); 2167 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y));
2168 2168
2169 glEnd(); 2169 glEnd();
2170} 2170}
2171 2171
2172 2172
2173//! The same, but with a four element array of colors, one for each vertex 2173//! The same, but with a four element array of colors, one for each vertex
2174void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, 2174void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
2175 const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, 2175 const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
2176 const video::SColor* const colors, bool useAlphaChannelOfTexture) 2176 const video::SColor* const colors, bool useAlphaChannelOfTexture)
2177{ 2177{
2178 if (!texture) 2178 if (!texture)
2179 return; 2179 return;
2180 2180
2181 const core::dimension2d<u32>& ss = texture->getOriginalSize(); 2181 const core::dimension2d<u32>& ss = texture->getOriginalSize();
2182 const f32 invW = 1.f / static_cast<f32>(ss.Width); 2182 const f32 invW = 1.f / static_cast<f32>(ss.Width);
2183 const f32 invH = 1.f / static_cast<f32>(ss.Height); 2183 const f32 invH = 1.f / static_cast<f32>(ss.Height);
2184 const core::rect<f32> tcoords( 2184 const core::rect<f32> tcoords(
2185 sourceRect.UpperLeftCorner.X * invW, 2185 sourceRect.UpperLeftCorner.X * invW,
2186 sourceRect.UpperLeftCorner.Y * invH, 2186 sourceRect.UpperLeftCorner.Y * invH,
2187 sourceRect.LowerRightCorner.X * invW, 2187 sourceRect.LowerRightCorner.X * invW,
2188 sourceRect.LowerRightCorner.Y *invH); 2188 sourceRect.LowerRightCorner.Y *invH);
2189 2189
2190 const video::SColor temp[4] = 2190 const video::SColor temp[4] =
2191 { 2191 {
2192 0xFFFFFFFF, 2192 0xFFFFFFFF,
2193 0xFFFFFFFF, 2193 0xFFFFFFFF,
2194 0xFFFFFFFF, 2194 0xFFFFFFFF,
2195 0xFFFFFFFF 2195 0xFFFFFFFF
2196 }; 2196 };
2197 2197
2198 const video::SColor* const useColor = colors ? colors : temp; 2198 const video::SColor* const useColor = colors ? colors : temp;
2199 2199
2200 disableTextures(1); 2200 disableTextures(1);
2201 setActiveTexture(0, texture); 2201 setActiveTexture(0, texture);
2202 setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || 2202 setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 ||
2203 useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, 2203 useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255,
2204 true, useAlphaChannelOfTexture); 2204 true, useAlphaChannelOfTexture);
2205 2205
2206 if (clipRect) 2206 if (clipRect)
2207 { 2207 {
2208 if (!clipRect->isValid()) 2208 if (!clipRect->isValid())
2209 return; 2209 return;
2210 2210
2211 glEnable(GL_SCISSOR_TEST); 2211 glEnable(GL_SCISSOR_TEST);
2212 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 2212 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
2213 glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, 2213 glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y,
2214 clipRect->getWidth(), clipRect->getHeight()); 2214 clipRect->getWidth(), clipRect->getHeight());
2215 } 2215 }
2216 2216
2217 glBegin(GL_QUADS); 2217 glBegin(GL_QUADS);
2218 2218
2219 glColor4ub(useColor[0].getRed(), useColor[0].getGreen(), useColor[0].getBlue(), useColor[0].getAlpha()); 2219 glColor4ub(useColor[0].getRed(), useColor[0].getGreen(), useColor[0].getBlue(), useColor[0].getAlpha());
2220 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); 2220 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
2221 glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.UpperLeftCorner.Y)); 2221 glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.UpperLeftCorner.Y));
2222 2222
2223 glColor4ub(useColor[3].getRed(), useColor[3].getGreen(), useColor[3].getBlue(), useColor[3].getAlpha()); 2223 glColor4ub(useColor[3].getRed(), useColor[3].getGreen(), useColor[3].getBlue(), useColor[3].getAlpha());
2224 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); 2224 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
2225 glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.UpperLeftCorner.Y)); 2225 glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.UpperLeftCorner.Y));
2226 2226
2227 glColor4ub(useColor[2].getRed(), useColor[2].getGreen(), useColor[2].getBlue(), useColor[2].getAlpha()); 2227 glColor4ub(useColor[2].getRed(), useColor[2].getGreen(), useColor[2].getBlue(), useColor[2].getAlpha());
2228 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); 2228 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
2229 glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.LowerRightCorner.Y)); 2229 glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.LowerRightCorner.Y));
2230 2230
2231 glColor4ub(useColor[1].getRed(), useColor[1].getGreen(), useColor[1].getBlue(), useColor[1].getAlpha()); 2231 glColor4ub(useColor[1].getRed(), useColor[1].getGreen(), useColor[1].getBlue(), useColor[1].getAlpha());
2232 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); 2232 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
2233 glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.LowerRightCorner.Y)); 2233 glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.LowerRightCorner.Y));
2234 2234
2235 glEnd(); 2235 glEnd();
2236 2236
2237 if (clipRect) 2237 if (clipRect)
2238 glDisable(GL_SCISSOR_TEST); 2238 glDisable(GL_SCISSOR_TEST);
2239} 2239}
2240 2240
2241 2241
2242//! draws a set of 2d images, using a color and the alpha channel of the 2242//! draws a set of 2d images, using a color and the alpha channel of the
2243//! texture if desired. The images are drawn beginning at pos and concatenated 2243//! texture if desired. The images are drawn beginning at pos and concatenated
2244//! in one line. All drawings are clipped against clipRect (if != 0). 2244//! in one line. All drawings are clipped against clipRect (if != 0).
2245//! The subtextures are defined by the array of sourceRects and are chosen 2245//! The subtextures are defined by the array of sourceRects and are chosen
2246//! by the indices given. 2246//! by the indices given.
2247void COpenGLDriver::draw2DImage(const video::ITexture* texture, 2247void COpenGLDriver::draw2DImage(const video::ITexture* texture,
2248 const core::position2d<s32>& pos, 2248 const core::position2d<s32>& pos,
2249 const core::array<core::rect<s32> >& sourceRects, 2249 const core::array<core::rect<s32> >& sourceRects,
2250 const core::array<s32>& indices, 2250 const core::array<s32>& indices,
2251 const core::rect<s32>* clipRect, SColor color, 2251 const core::rect<s32>* clipRect, SColor color,
2252 bool useAlphaChannelOfTexture) 2252 bool useAlphaChannelOfTexture)
2253{ 2253{
2254 if (!texture) 2254 if (!texture)
2255 return; 2255 return;
2256 2256
2257 disableTextures(1); 2257 disableTextures(1);
2258 if (!setActiveTexture(0, texture)) 2258 if (!setActiveTexture(0, texture))
2259 return; 2259 return;
2260 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); 2260 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
2261 2261
2262 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 2262 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
2263 if (clipRect) 2263 if (clipRect)
2264 { 2264 {
2265 if (!clipRect->isValid()) 2265 if (!clipRect->isValid())
2266 return; 2266 return;
2267 2267
2268 glEnable(GL_SCISSOR_TEST); 2268 glEnable(GL_SCISSOR_TEST);
2269 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 2269 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
2270 glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, 2270 glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y,
2271 clipRect->getWidth(),clipRect->getHeight()); 2271 clipRect->getWidth(),clipRect->getHeight());
2272 } 2272 }
2273 2273
2274 const core::dimension2d<u32>& ss = texture->getOriginalSize(); 2274 const core::dimension2d<u32>& ss = texture->getOriginalSize();
2275 core::position2d<s32> targetPos(pos); 2275 core::position2d<s32> targetPos(pos);
2276 const f32 invW = 1.f / static_cast<f32>(ss.Width); 2276 const f32 invW = 1.f / static_cast<f32>(ss.Width);
2277 const f32 invH = 1.f / static_cast<f32>(ss.Height); 2277 const f32 invH = 1.f / static_cast<f32>(ss.Height);
2278 2278
2279 for (u32 i=0; i<indices.size(); ++i) 2279 for (u32 i=0; i<indices.size(); ++i)
2280 { 2280 {
2281 const s32 currentIndex = indices[i]; 2281 const s32 currentIndex = indices[i];
2282 if (!sourceRects[currentIndex].isValid()) 2282 if (!sourceRects[currentIndex].isValid())
2283 break; 2283 break;
2284 2284
2285 const core::rect<f32> tcoords( 2285 const core::rect<f32> tcoords(
2286 sourceRects[currentIndex].UpperLeftCorner.X * invW, 2286 sourceRects[currentIndex].UpperLeftCorner.X * invW,
2287 sourceRects[currentIndex].UpperLeftCorner.Y * invH, 2287 sourceRects[currentIndex].UpperLeftCorner.Y * invH,
2288 sourceRects[currentIndex].LowerRightCorner.X * invW, 2288 sourceRects[currentIndex].LowerRightCorner.X * invW,
2289 sourceRects[currentIndex].LowerRightCorner.Y * invH); 2289 sourceRects[currentIndex].LowerRightCorner.Y * invH);
2290 2290
2291 const core::rect<s32> poss(targetPos, sourceRects[currentIndex].getSize()); 2291 const core::rect<s32> poss(targetPos, sourceRects[currentIndex].getSize());
2292 2292
2293 glBegin(GL_QUADS); 2293 glBegin(GL_QUADS);
2294 2294
2295 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); 2295 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
2296 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); 2296 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y));
2297 2297
2298 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); 2298 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
2299 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); 2299 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y));
2300 2300
2301 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); 2301 glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
2302 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); 2302 glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y));
2303 2303
2304 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); 2304 glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
2305 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); 2305 glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y));
2306 2306
2307 glEnd(); 2307 glEnd();
2308 targetPos.X += sourceRects[currentIndex].getWidth(); 2308 targetPos.X += sourceRects[currentIndex].getWidth();
2309 } 2309 }
2310 if (clipRect) 2310 if (clipRect)
2311 glDisable(GL_SCISSOR_TEST); 2311 glDisable(GL_SCISSOR_TEST);
2312} 2312}
2313 2313
2314 2314
2315//! draw a 2d rectangle 2315//! draw a 2d rectangle
2316void COpenGLDriver::draw2DRectangle(SColor color, const core::rect<s32>& position, 2316void COpenGLDriver::draw2DRectangle(SColor color, const core::rect<s32>& position,
2317 const core::rect<s32>* clip) 2317 const core::rect<s32>* clip)
2318{ 2318{
2319 disableTextures(); 2319 disableTextures();
2320 setRenderStates2DMode(color.getAlpha() < 255, false, false); 2320 setRenderStates2DMode(color.getAlpha() < 255, false, false);
2321 2321
2322 core::rect<s32> pos = position; 2322 core::rect<s32> pos = position;
2323 2323
2324 if (clip) 2324 if (clip)
2325 pos.clipAgainst(*clip); 2325 pos.clipAgainst(*clip);
2326 2326
2327 if (!pos.isValid()) 2327 if (!pos.isValid())
2328 return; 2328 return;
2329 2329
2330 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 2330 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
2331 glRectf(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y), 2331 glRectf(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y),
2332 GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y)); 2332 GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y));
2333} 2333}
2334 2334
2335 2335
2336//! draw an 2d rectangle 2336//! draw an 2d rectangle
2337void COpenGLDriver::draw2DRectangle(const core::rect<s32>& position, 2337void COpenGLDriver::draw2DRectangle(const core::rect<s32>& position,
2338 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, 2338 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
2339 const core::rect<s32>* clip) 2339 const core::rect<s32>* clip)
2340{ 2340{
2341 core::rect<s32> pos = position; 2341 core::rect<s32> pos = position;
2342 2342
2343 if (clip) 2343 if (clip)
2344 pos.clipAgainst(*clip); 2344 pos.clipAgainst(*clip);
2345 2345
2346 if (!pos.isValid()) 2346 if (!pos.isValid())
2347 return; 2347 return;
2348 2348
2349 disableTextures(); 2349 disableTextures();
2350 2350
2351 setRenderStates2DMode(colorLeftUp.getAlpha() < 255 || 2351 setRenderStates2DMode(colorLeftUp.getAlpha() < 255 ||
2352 colorRightUp.getAlpha() < 255 || 2352 colorRightUp.getAlpha() < 255 ||
2353 colorLeftDown.getAlpha() < 255 || 2353 colorLeftDown.getAlpha() < 255 ||
2354 colorRightDown.getAlpha() < 255, false, false); 2354 colorRightDown.getAlpha() < 255, false, false);
2355 2355
2356 glBegin(GL_QUADS); 2356 glBegin(GL_QUADS);
2357 glColor4ub(colorLeftUp.getRed(), colorLeftUp.getGreen(), 2357 glColor4ub(colorLeftUp.getRed(), colorLeftUp.getGreen(),
2358 colorLeftUp.getBlue(), colorLeftUp.getAlpha()); 2358 colorLeftUp.getBlue(), colorLeftUp.getAlpha());
2359 glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y)); 2359 glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y));
2360 2360
2361 glColor4ub(colorRightUp.getRed(), colorRightUp.getGreen(), 2361 glColor4ub(colorRightUp.getRed(), colorRightUp.getGreen(),
2362 colorRightUp.getBlue(), colorRightUp.getAlpha()); 2362 colorRightUp.getBlue(), colorRightUp.getAlpha());
2363 glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.UpperLeftCorner.Y)); 2363 glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.UpperLeftCorner.Y));
2364 2364
2365 glColor4ub(colorRightDown.getRed(), colorRightDown.getGreen(), 2365 glColor4ub(colorRightDown.getRed(), colorRightDown.getGreen(),
2366 colorRightDown.getBlue(), colorRightDown.getAlpha()); 2366 colorRightDown.getBlue(), colorRightDown.getAlpha());
2367 glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y)); 2367 glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y));
2368 2368
2369 glColor4ub(colorLeftDown.getRed(), colorLeftDown.getGreen(), 2369 glColor4ub(colorLeftDown.getRed(), colorLeftDown.getGreen(),
2370 colorLeftDown.getBlue(), colorLeftDown.getAlpha()); 2370 colorLeftDown.getBlue(), colorLeftDown.getAlpha());
2371 glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.LowerRightCorner.Y)); 2371 glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.LowerRightCorner.Y));
2372 2372
2373 glEnd(); 2373 glEnd();
2374} 2374}
2375 2375
2376 2376
2377//! Draws a 2d line. 2377//! Draws a 2d line.
2378void COpenGLDriver::draw2DLine(const core::position2d<s32>& start, 2378void COpenGLDriver::draw2DLine(const core::position2d<s32>& start,
2379 const core::position2d<s32>& end, SColor color) 2379 const core::position2d<s32>& end, SColor color)
2380{ 2380{
2381 if (start==end) 2381 if (start==end)
2382 drawPixel(start.X, start.Y, color); 2382 drawPixel(start.X, start.Y, color);
2383 else 2383 else
2384 { 2384 {
2385 disableTextures(); 2385 disableTextures();
2386 setRenderStates2DMode(color.getAlpha() < 255, false, false); 2386 setRenderStates2DMode(color.getAlpha() < 255, false, false);
2387 2387
2388 glBegin(GL_LINES); 2388 glBegin(GL_LINES);
2389 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 2389 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
2390 GLfloat x=(GLfloat)start.X; 2390 GLfloat x=(GLfloat)start.X;
2391 GLfloat y=(GLfloat)start.Y; 2391 GLfloat y=(GLfloat)start.Y;
2392 if (x>end.X) 2392 if (x>end.X)
2393 x += 0.5f; 2393 x += 0.5f;
2394 if (y>end.Y) 2394 if (y>end.Y)
2395 y += 0.5f; 2395 y += 0.5f;
2396 glVertex2f(GLfloat(x), GLfloat(y)); 2396 glVertex2f(GLfloat(x), GLfloat(y));
2397 x=(GLfloat)end.X; 2397 x=(GLfloat)end.X;
2398 y=(GLfloat)end.Y; 2398 y=(GLfloat)end.Y;
2399 if (x>start.X) 2399 if (x>start.X)
2400 x += 0.5f; 2400 x += 0.5f;
2401 if (y>start.Y) 2401 if (y>start.Y)
2402 y += 0.5f; 2402 y += 0.5f;
2403 glVertex2f(GLfloat(x), GLfloat(y)); 2403 glVertex2f(GLfloat(x), GLfloat(y));
2404 glEnd(); 2404 glEnd();
2405 } 2405 }
2406} 2406}
2407 2407
2408//! Draws a pixel 2408//! Draws a pixel
2409void COpenGLDriver::drawPixel(u32 x, u32 y, const SColor &color) 2409void COpenGLDriver::drawPixel(u32 x, u32 y, const SColor &color)
2410{ 2410{
2411 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 2411 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
2412 if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) 2412 if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height)
2413 return; 2413 return;
2414 2414
2415 disableTextures(); 2415 disableTextures();
2416 setRenderStates2DMode(color.getAlpha() < 255, false, false); 2416 setRenderStates2DMode(color.getAlpha() < 255, false, false);
2417 2417
2418 glBegin(GL_POINTS); 2418 glBegin(GL_POINTS);
2419 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 2419 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
2420 glVertex2i(x, y); 2420 glVertex2i(x, y);
2421 glEnd(); 2421 glEnd();
2422} 2422}
2423 2423
2424bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture) 2424bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
2425{ 2425{
2426 if (stage >= MaxSupportedTextures) 2426 if (stage >= MaxSupportedTextures)
2427 return false; 2427 return false;
2428 2428
2429 if (CurrentTexture[stage]==texture) 2429 if (CurrentTexture[stage]==texture)
2430 return true; 2430 return true;
2431 2431
2432 if (MultiTextureExtension) 2432 if (MultiTextureExtension)
2433 extGlActiveTexture(GL_TEXTURE0_ARB + stage); 2433 extGlActiveTexture(GL_TEXTURE0_ARB + stage);
2434 2434
2435 CurrentTexture.set(stage,texture); 2435 CurrentTexture.set(stage,texture);
2436 2436
2437 if (!texture) 2437 if (!texture)
2438 { 2438 {
2439 glDisable(GL_TEXTURE_2D); 2439 glDisable(GL_TEXTURE_2D);
2440 return true; 2440 return true;
2441 } 2441 }
2442 else 2442 else
2443 { 2443 {
2444 if (texture->getDriverType() != EDT_OPENGL) 2444 if (texture->getDriverType() != EDT_OPENGL)
2445 { 2445 {
2446 glDisable(GL_TEXTURE_2D); 2446 glDisable(GL_TEXTURE_2D);
2447 CurrentTexture.set(stage, 0); 2447 CurrentTexture.set(stage, 0);
2448 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); 2448 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
2449 return false; 2449 return false;
2450 } 2450 }
2451 2451
2452 glEnable(GL_TEXTURE_2D); 2452 glEnable(GL_TEXTURE_2D);
2453 glBindTexture(GL_TEXTURE_2D, 2453 glBindTexture(GL_TEXTURE_2D,
2454 static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName()); 2454 static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName());
2455 } 2455 }
2456 return true; 2456 return true;
2457} 2457}
2458 2458
2459 2459
2460//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. 2460//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled.
2461//! Returns whether disabling was successful or not. 2461//! Returns whether disabling was successful or not.
2462bool COpenGLDriver::disableTextures(u32 fromStage) 2462bool COpenGLDriver::disableTextures(u32 fromStage)
2463{ 2463{
2464 bool result=true; 2464 bool result=true;
2465 for (u32 i=fromStage; i<MaxSupportedTextures; ++i) 2465 for (u32 i=fromStage; i<MaxSupportedTextures; ++i)
2466 result &= setActiveTexture(i, 0); 2466 result &= setActiveTexture(i, 0);
2467 return result; 2467 return result;
2468} 2468}
2469 2469
2470 2470
2471//! creates a matrix in supplied GLfloat array to pass to OpenGL 2471//! creates a matrix in supplied GLfloat array to pass to OpenGL
2472inline void COpenGLDriver::getGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m) 2472inline void COpenGLDriver::getGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m)
2473{ 2473{
2474 memcpy(gl_matrix, m.pointer(), 16 * sizeof(f32)); 2474 memcpy(gl_matrix, m.pointer(), 16 * sizeof(f32));
2475} 2475}
2476 2476
2477 2477
2478//! creates a opengltexturematrix from a D3D style texture matrix 2478//! creates a opengltexturematrix from a D3D style texture matrix
2479inline void COpenGLDriver::getGLTextureMatrix(GLfloat *o, const core::matrix4& m) 2479inline void COpenGLDriver::getGLTextureMatrix(GLfloat *o, const core::matrix4& m)
2480{ 2480{
2481 o[0] = m[0]; 2481 o[0] = m[0];
2482 o[1] = m[1]; 2482 o[1] = m[1];
2483 o[2] = 0.f; 2483 o[2] = 0.f;
2484 o[3] = 0.f; 2484 o[3] = 0.f;
2485 2485
2486 o[4] = m[4]; 2486 o[4] = m[4];
2487 o[5] = m[5]; 2487 o[5] = m[5];
2488 o[6] = 0.f; 2488 o[6] = 0.f;
2489 o[7] = 0.f; 2489 o[7] = 0.f;
2490 2490
2491 o[8] = 0.f; 2491 o[8] = 0.f;
2492 o[9] = 0.f; 2492 o[9] = 0.f;
2493 o[10] = 1.f; 2493 o[10] = 1.f;
2494 o[11] = 0.f; 2494 o[11] = 0.f;
2495 2495
2496 o[12] = m[8]; 2496 o[12] = m[8];
2497 o[13] = m[9]; 2497 o[13] = m[9];
2498 o[14] = 0.f; 2498 o[14] = 0.f;
2499 o[15] = 1.f; 2499 o[15] = 1.f;
2500} 2500}
2501 2501
2502 2502
2503//! returns a device dependent texture from a software surface (IImage) 2503//! returns a device dependent texture from a software surface (IImage)
2504video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) 2504video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
2505{ 2505{
2506 return new COpenGLTexture(surface, name, mipmapData, this); 2506 return new COpenGLTexture(surface, name, mipmapData, this);
2507} 2507}
2508 2508
2509 2509
2510//! Sets a material. All 3d drawing functions draw geometry now using this material. 2510//! Sets a material. All 3d drawing functions draw geometry now using this material.
2511void COpenGLDriver::setMaterial(const SMaterial& material) 2511void COpenGLDriver::setMaterial(const SMaterial& material)
2512{ 2512{
2513 Material = material; 2513 Material = material;
2514 OverrideMaterial.apply(Material); 2514 OverrideMaterial.apply(Material);
2515 2515
2516 for (s32 i = MaxTextureUnits-1; i>= 0; --i) 2516 for (s32 i = MaxTextureUnits-1; i>= 0; --i)
2517 { 2517 {
2518 setActiveTexture(i, material.getTexture(i)); 2518 setActiveTexture(i, material.getTexture(i));
2519 setTransform ((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), 2519 setTransform ((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i),
2520 Material.getTextureMatrix(i)); 2520 Material.getTextureMatrix(i));
2521 } 2521 }
2522} 2522}
2523 2523
2524 2524
2525//! prints error if an error happened. 2525//! prints error if an error happened.
2526bool COpenGLDriver::testGLError() 2526bool COpenGLDriver::testGLError()
2527{ 2527{
2528#ifdef _DEBUG 2528#ifdef _DEBUG
2529 GLenum g = glGetError(); 2529 GLenum g = glGetError();
2530 switch (g) 2530 switch (g)
2531 { 2531 {
2532 case GL_NO_ERROR: 2532 case GL_NO_ERROR:
2533 return false; 2533 return false;
2534 case GL_INVALID_ENUM: 2534 case GL_INVALID_ENUM:
2535 os::Printer::log("GL_INVALID_ENUM", ELL_ERROR); break; 2535 os::Printer::log("GL_INVALID_ENUM", ELL_ERROR); break;
2536 case GL_INVALID_VALUE: 2536 case GL_INVALID_VALUE:
2537 os::Printer::log("GL_INVALID_VALUE", ELL_ERROR); break; 2537 os::Printer::log("GL_INVALID_VALUE", ELL_ERROR); break;
2538 case GL_INVALID_OPERATION: 2538 case GL_INVALID_OPERATION:
2539 os::Printer::log("GL_INVALID_OPERATION", ELL_ERROR); break; 2539 os::Printer::log("GL_INVALID_OPERATION", ELL_ERROR); break;
2540 case GL_STACK_OVERFLOW: 2540 case GL_STACK_OVERFLOW:
2541 os::Printer::log("GL_STACK_OVERFLOW", ELL_ERROR); break; 2541 os::Printer::log("GL_STACK_OVERFLOW", ELL_ERROR); break;
2542 case GL_STACK_UNDERFLOW: 2542 case GL_STACK_UNDERFLOW:
2543 os::Printer::log("GL_STACK_UNDERFLOW", ELL_ERROR); break; 2543 os::Printer::log("GL_STACK_UNDERFLOW", ELL_ERROR); break;
2544 case GL_OUT_OF_MEMORY: 2544 case GL_OUT_OF_MEMORY:
2545 os::Printer::log("GL_OUT_OF_MEMORY", ELL_ERROR); break; 2545 os::Printer::log("GL_OUT_OF_MEMORY", ELL_ERROR); break;
2546 case GL_TABLE_TOO_LARGE: 2546 case GL_TABLE_TOO_LARGE:
2547 os::Printer::log("GL_TABLE_TOO_LARGE", ELL_ERROR); break; 2547 os::Printer::log("GL_TABLE_TOO_LARGE", ELL_ERROR); break;
2548#if defined(GL_EXT_framebuffer_object) 2548#if defined(GL_EXT_framebuffer_object)
2549 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: 2549 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
2550 os::Printer::log("GL_INVALID_FRAMEBUFFER_OPERATION", ELL_ERROR); break; 2550 os::Printer::log("GL_INVALID_FRAMEBUFFER_OPERATION", ELL_ERROR); break;
2551#endif 2551#endif
2552 }; 2552 };
2553// _IRR_DEBUG_BREAK_IF(true); 2553// _IRR_DEBUG_BREAK_IF(true);
2554 return true; 2554 return true;
2555#else 2555#else
2556 return false; 2556 return false;
2557#endif 2557#endif
2558} 2558}
2559 2559
2560 2560
2561//! sets the needed renderstates 2561//! sets the needed renderstates
2562void COpenGLDriver::setRenderStates3DMode() 2562void COpenGLDriver::setRenderStates3DMode()
2563{ 2563{
2564 if (CurrentRenderMode != ERM_3D) 2564 if (CurrentRenderMode != ERM_3D)
2565 { 2565 {
2566 // Reset Texture Stages 2566 // Reset Texture Stages
2567 glDisable(GL_BLEND); 2567 glDisable(GL_BLEND);
2568 glDisable(GL_ALPHA_TEST); 2568 glDisable(GL_ALPHA_TEST);
2569 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 2569 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2570 2570
2571 // switch back the matrices 2571 // switch back the matrices
2572 glMatrixMode(GL_MODELVIEW); 2572 glMatrixMode(GL_MODELVIEW);
2573 glLoadMatrixf((Matrices[ETS_VIEW] * Matrices[ETS_WORLD]).pointer()); 2573 glLoadMatrixf((Matrices[ETS_VIEW] * Matrices[ETS_WORLD]).pointer());
2574 2574
2575 glMatrixMode(GL_PROJECTION); 2575 glMatrixMode(GL_PROJECTION);
2576 glLoadMatrixf(Matrices[ETS_PROJECTION].pointer()); 2576 glLoadMatrixf(Matrices[ETS_PROJECTION].pointer());
2577 2577
2578 ResetRenderStates = true; 2578 ResetRenderStates = true;
2579#ifdef GL_EXT_clip_volume_hint 2579#ifdef GL_EXT_clip_volume_hint
2580 if (FeatureAvailable[IRR_EXT_clip_volume_hint]) 2580 if (FeatureAvailable[IRR_EXT_clip_volume_hint])
2581 glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST); 2581 glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST);
2582#endif 2582#endif
2583 } 2583 }
2584 2584
2585 if (ResetRenderStates || LastMaterial != Material) 2585 if (ResetRenderStates || LastMaterial != Material)
2586 { 2586 {
2587 // unset old material 2587 // unset old material
2588 2588
2589 if (LastMaterial.MaterialType != Material.MaterialType && 2589 if (LastMaterial.MaterialType != Material.MaterialType &&
2590 static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) 2590 static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
2591 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); 2591 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
2592 2592
2593 // set new material. 2593 // set new material.
2594 if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) 2594 if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
2595 MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( 2595 MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial(
2596 Material, LastMaterial, ResetRenderStates, this); 2596 Material, LastMaterial, ResetRenderStates, this);
2597 2597
2598 LastMaterial = Material; 2598 LastMaterial = Material;
2599 ResetRenderStates = false; 2599 ResetRenderStates = false;
2600 } 2600 }
2601 2601
2602 if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) 2602 if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
2603 MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, video::EVT_STANDARD); 2603 MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, video::EVT_STANDARD);
2604 2604
2605 CurrentRenderMode = ERM_3D; 2605 CurrentRenderMode = ERM_3D;
2606} 2606}
2607 2607
2608 2608
2609//! Get native wrap mode value 2609//! Get native wrap mode value
2610GLint COpenGLDriver::getTextureWrapMode(const u8 clamp) 2610GLint COpenGLDriver::getTextureWrapMode(const u8 clamp)
2611{ 2611{
2612 GLint mode=GL_REPEAT; 2612 GLint mode=GL_REPEAT;
2613 switch (clamp) 2613 switch (clamp)
2614 { 2614 {
2615 case ETC_REPEAT: 2615 case ETC_REPEAT:
2616 mode=GL_REPEAT; 2616 mode=GL_REPEAT;
2617 break; 2617 break;
2618 case ETC_CLAMP: 2618 case ETC_CLAMP:
2619 mode=GL_CLAMP; 2619 mode=GL_CLAMP;
2620 break; 2620 break;
2621 case ETC_CLAMP_TO_EDGE: 2621 case ETC_CLAMP_TO_EDGE:
2622#ifdef GL_VERSION_1_2 2622#ifdef GL_VERSION_1_2
2623 if (Version>101) 2623 if (Version>101)
2624 mode=GL_CLAMP_TO_EDGE; 2624 mode=GL_CLAMP_TO_EDGE;
2625 else 2625 else
2626#endif 2626#endif
2627#ifdef GL_SGIS_texture_edge_clamp 2627#ifdef GL_SGIS_texture_edge_clamp
2628 if (FeatureAvailable[IRR_SGIS_texture_edge_clamp]) 2628 if (FeatureAvailable[IRR_SGIS_texture_edge_clamp])
2629 mode=GL_CLAMP_TO_EDGE_SGIS; 2629 mode=GL_CLAMP_TO_EDGE_SGIS;
2630 else 2630 else
2631#endif 2631#endif
2632 // fallback 2632 // fallback
2633 mode=GL_CLAMP; 2633 mode=GL_CLAMP;
2634 break; 2634 break;
2635 case ETC_CLAMP_TO_BORDER: 2635 case ETC_CLAMP_TO_BORDER:
2636#ifdef GL_VERSION_1_3 2636#ifdef GL_VERSION_1_3
2637 if (Version>102) 2637 if (Version>102)
2638 mode=GL_CLAMP_TO_BORDER; 2638 mode=GL_CLAMP_TO_BORDER;
2639 else 2639 else
2640#endif 2640#endif
2641#ifdef GL_ARB_texture_border_clamp 2641#ifdef GL_ARB_texture_border_clamp
2642 if (FeatureAvailable[IRR_ARB_texture_border_clamp]) 2642 if (FeatureAvailable[IRR_ARB_texture_border_clamp])
2643 mode=GL_CLAMP_TO_BORDER_ARB; 2643 mode=GL_CLAMP_TO_BORDER_ARB;
2644 else 2644 else
2645#endif 2645#endif
2646#ifdef GL_SGIS_texture_border_clamp 2646#ifdef GL_SGIS_texture_border_clamp
2647 if (FeatureAvailable[IRR_SGIS_texture_border_clamp]) 2647 if (FeatureAvailable[IRR_SGIS_texture_border_clamp])
2648 mode=GL_CLAMP_TO_BORDER_SGIS; 2648 mode=GL_CLAMP_TO_BORDER_SGIS;
2649 else 2649 else
2650#endif 2650#endif
2651 // fallback 2651 // fallback
2652 mode=GL_CLAMP; 2652 mode=GL_CLAMP;
2653 break; 2653 break;
2654 case ETC_MIRROR: 2654 case ETC_MIRROR:
2655#ifdef GL_VERSION_1_4 2655#ifdef GL_VERSION_1_4
2656 if (Version>103) 2656 if (Version>103)
2657 mode=GL_MIRRORED_REPEAT; 2657 mode=GL_MIRRORED_REPEAT;
2658 else 2658 else
2659#endif 2659#endif
2660#ifdef GL_ARB_texture_border_clamp 2660#ifdef GL_ARB_texture_border_clamp
2661 if (FeatureAvailable[IRR_ARB_texture_mirrored_repeat]) 2661 if (FeatureAvailable[IRR_ARB_texture_mirrored_repeat])
2662 mode=GL_MIRRORED_REPEAT_ARB; 2662 mode=GL_MIRRORED_REPEAT_ARB;
2663 else 2663 else
2664#endif 2664#endif
2665#ifdef GL_IBM_texture_mirrored_repeat 2665#ifdef GL_IBM_texture_mirrored_repeat
2666 if (FeatureAvailable[IRR_IBM_texture_mirrored_repeat]) 2666 if (FeatureAvailable[IRR_IBM_texture_mirrored_repeat])
2667 mode=GL_MIRRORED_REPEAT_IBM; 2667 mode=GL_MIRRORED_REPEAT_IBM;
2668 else 2668 else
2669#endif 2669#endif
2670 mode=GL_REPEAT; 2670 mode=GL_REPEAT;
2671 break; 2671 break;
2672 case ETC_MIRROR_CLAMP: 2672 case ETC_MIRROR_CLAMP:
2673#ifdef GL_EXT_texture_mirror_clamp 2673#ifdef GL_EXT_texture_mirror_clamp
2674 if (FeatureAvailable[IRR_EXT_texture_mirror_clamp]) 2674 if (FeatureAvailable[IRR_EXT_texture_mirror_clamp])
2675 mode=GL_MIRROR_CLAMP_EXT; 2675 mode=GL_MIRROR_CLAMP_EXT;
2676 else 2676 else
2677#endif 2677#endif
2678#if defined(GL_ATI_texture_mirror_once) 2678#if defined(GL_ATI_texture_mirror_once)
2679 if (FeatureAvailable[IRR_ATI_texture_mirror_once]) 2679 if (FeatureAvailable[IRR_ATI_texture_mirror_once])
2680 mode=GL_MIRROR_CLAMP_ATI; 2680 mode=GL_MIRROR_CLAMP_ATI;
2681 else 2681 else
2682#endif 2682#endif
2683 mode=GL_CLAMP; 2683 mode=GL_CLAMP;
2684 break; 2684 break;
2685 case ETC_MIRROR_CLAMP_TO_EDGE: 2685 case ETC_MIRROR_CLAMP_TO_EDGE:
2686#ifdef GL_EXT_texture_mirror_clamp 2686#ifdef GL_EXT_texture_mirror_clamp
2687 if (FeatureAvailable[IRR_EXT_texture_mirror_clamp]) 2687 if (FeatureAvailable[IRR_EXT_texture_mirror_clamp])
2688 mode=GL_MIRROR_CLAMP_TO_EDGE_EXT; 2688 mode=GL_MIRROR_CLAMP_TO_EDGE_EXT;
2689 else 2689 else
2690#endif 2690#endif
2691#if defined(GL_ATI_texture_mirror_once) 2691#if defined(GL_ATI_texture_mirror_once)
2692 if (FeatureAvailable[IRR_ATI_texture_mirror_once]) 2692 if (FeatureAvailable[IRR_ATI_texture_mirror_once])
2693 mode=GL_MIRROR_CLAMP_TO_EDGE_ATI; 2693 mode=GL_MIRROR_CLAMP_TO_EDGE_ATI;
2694 else 2694 else
2695#endif 2695#endif
2696 mode=GL_CLAMP; 2696 mode=GL_CLAMP;
2697 break; 2697 break;
2698 case ETC_MIRROR_CLAMP_TO_BORDER: 2698 case ETC_MIRROR_CLAMP_TO_BORDER:
2699#ifdef GL_EXT_texture_mirror_clamp 2699#ifdef GL_EXT_texture_mirror_clamp
2700 if (FeatureAvailable[IRR_EXT_texture_mirror_clamp]) 2700 if (FeatureAvailable[IRR_EXT_texture_mirror_clamp])
2701 mode=GL_MIRROR_CLAMP_TO_BORDER_EXT; 2701 mode=GL_MIRROR_CLAMP_TO_BORDER_EXT;
2702 else 2702 else
2703#endif 2703#endif
2704 mode=GL_CLAMP; 2704 mode=GL_CLAMP;
2705 break; 2705 break;
2706 } 2706 }
2707 return mode; 2707 return mode;
2708} 2708}
2709 2709
2710 2710
2711void COpenGLDriver::setWrapMode(const SMaterial& material) 2711void COpenGLDriver::setWrapMode(const SMaterial& material)
2712{ 2712{
2713 // texture address mode 2713 // texture address mode
2714 // Has to be checked always because it depends on the textures 2714 // Has to be checked always because it depends on the textures
2715 for (u32 u=0; u<MaxTextureUnits; ++u) 2715 for (u32 u=0; u<MaxTextureUnits; ++u)
2716 { 2716 {
2717 if (!CurrentTexture[u]) 2717 if (!CurrentTexture[u])
2718 continue; 2718 continue;
2719 if (MultiTextureExtension) 2719 if (MultiTextureExtension)
2720 extGlActiveTexture(GL_TEXTURE0_ARB + u); 2720 extGlActiveTexture(GL_TEXTURE0_ARB + u);
2721 else if (u>0) 2721 else if (u>0)
2722 break; // stop loop 2722 break; // stop loop
2723 2723
2724 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[u].TextureWrapU)); 2724 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[u].TextureWrapU));
2725 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[u].TextureWrapV)); 2725 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[u].TextureWrapV));
2726 } 2726 }
2727} 2727}
2728 2728
2729 2729
2730//! Can be called by an IMaterialRenderer to make its work easier. 2730//! Can be called by an IMaterialRenderer to make its work easier.
2731void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, 2731void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
2732 bool resetAllRenderStates) 2732 bool resetAllRenderStates)
2733{ 2733{
2734 if (resetAllRenderStates || 2734 if (resetAllRenderStates ||
2735 lastmaterial.ColorMaterial != material.ColorMaterial) 2735 lastmaterial.ColorMaterial != material.ColorMaterial)
2736 { 2736 {
2737 switch (material.ColorMaterial) 2737 switch (material.ColorMaterial)
2738 { 2738 {
2739 case ECM_NONE: 2739 case ECM_NONE:
2740 glDisable(GL_COLOR_MATERIAL); 2740 glDisable(GL_COLOR_MATERIAL);
2741 break; 2741 break;
2742 case ECM_DIFFUSE: 2742 case ECM_DIFFUSE:
2743 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 2743 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
2744 break; 2744 break;
2745 case ECM_AMBIENT: 2745 case ECM_AMBIENT:
2746 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); 2746 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
2747 break; 2747 break;
2748 case ECM_EMISSIVE: 2748 case ECM_EMISSIVE:
2749 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); 2749 glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
2750 break; 2750 break;
2751 case ECM_SPECULAR: 2751 case ECM_SPECULAR:
2752 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); 2752 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
2753 break; 2753 break;
2754 case ECM_DIFFUSE_AND_AMBIENT: 2754 case ECM_DIFFUSE_AND_AMBIENT:
2755 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 2755 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
2756 break; 2756 break;
2757 } 2757 }
2758 if (material.ColorMaterial != ECM_NONE) 2758 if (material.ColorMaterial != ECM_NONE)
2759 glEnable(GL_COLOR_MATERIAL); 2759 glEnable(GL_COLOR_MATERIAL);
2760 } 2760 }
2761 2761
2762 if (resetAllRenderStates || 2762 if (resetAllRenderStates ||
2763 lastmaterial.AmbientColor != material.AmbientColor || 2763 lastmaterial.AmbientColor != material.AmbientColor ||
2764 lastmaterial.DiffuseColor != material.DiffuseColor || 2764 lastmaterial.DiffuseColor != material.DiffuseColor ||
2765 lastmaterial.EmissiveColor != material.EmissiveColor || 2765 lastmaterial.EmissiveColor != material.EmissiveColor ||
2766 lastmaterial.ColorMaterial != material.ColorMaterial) 2766 lastmaterial.ColorMaterial != material.ColorMaterial)
2767 { 2767 {
2768 GLfloat color[4]; 2768 GLfloat color[4];
2769 2769
2770 const f32 inv = 1.0f / 255.0f; 2770 const f32 inv = 1.0f / 255.0f;
2771 2771
2772 if ((material.ColorMaterial != video::ECM_AMBIENT) && 2772 if ((material.ColorMaterial != video::ECM_AMBIENT) &&
2773 (material.ColorMaterial != video::ECM_DIFFUSE_AND_AMBIENT)) 2773 (material.ColorMaterial != video::ECM_DIFFUSE_AND_AMBIENT))
2774 { 2774 {
2775 color[0] = material.AmbientColor.getRed() * inv; 2775 color[0] = material.AmbientColor.getRed() * inv;
2776 color[1] = material.AmbientColor.getGreen() * inv; 2776 color[1] = material.AmbientColor.getGreen() * inv;
2777 color[2] = material.AmbientColor.getBlue() * inv; 2777 color[2] = material.AmbientColor.getBlue() * inv;
2778 color[3] = material.AmbientColor.getAlpha() * inv; 2778 color[3] = material.AmbientColor.getAlpha() * inv;
2779 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); 2779 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
2780 } 2780 }
2781 2781
2782 if ((material.ColorMaterial != video::ECM_DIFFUSE) && 2782 if ((material.ColorMaterial != video::ECM_DIFFUSE) &&
2783 (material.ColorMaterial != video::ECM_DIFFUSE_AND_AMBIENT)) 2783 (material.ColorMaterial != video::ECM_DIFFUSE_AND_AMBIENT))
2784 { 2784 {
2785 color[0] = material.DiffuseColor.getRed() * inv; 2785 color[0] = material.DiffuseColor.getRed() * inv;
2786 color[1] = material.DiffuseColor.getGreen() * inv; 2786 color[1] = material.DiffuseColor.getGreen() * inv;
2787 color[2] = material.DiffuseColor.getBlue() * inv; 2787 color[2] = material.DiffuseColor.getBlue() * inv;
2788 color[3] = material.DiffuseColor.getAlpha() * inv; 2788 color[3] = material.DiffuseColor.getAlpha() * inv;
2789 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); 2789 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
2790 } 2790 }
2791 2791
2792 if (material.ColorMaterial != video::ECM_EMISSIVE) 2792 if (material.ColorMaterial != video::ECM_EMISSIVE)
2793 { 2793 {
2794 color[0] = material.EmissiveColor.getRed() * inv; 2794 color[0] = material.EmissiveColor.getRed() * inv;
2795 color[1] = material.EmissiveColor.getGreen() * inv; 2795 color[1] = material.EmissiveColor.getGreen() * inv;
2796 color[2] = material.EmissiveColor.getBlue() * inv; 2796 color[2] = material.EmissiveColor.getBlue() * inv;
2797 color[3] = material.EmissiveColor.getAlpha() * inv; 2797 color[3] = material.EmissiveColor.getAlpha() * inv;
2798 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color); 2798 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
2799 } 2799 }
2800 } 2800 }
2801 2801
2802 if (resetAllRenderStates || 2802 if (resetAllRenderStates ||
2803 lastmaterial.SpecularColor != material.SpecularColor || 2803 lastmaterial.SpecularColor != material.SpecularColor ||
2804 lastmaterial.Shininess != material.Shininess || 2804 lastmaterial.Shininess != material.Shininess ||
2805 lastmaterial.ColorMaterial != material.ColorMaterial) 2805 lastmaterial.ColorMaterial != material.ColorMaterial)
2806 { 2806 {
2807 GLfloat color[4]={0.f,0.f,0.f,1.f}; 2807 GLfloat color[4]={0.f,0.f,0.f,1.f};
2808 const f32 inv = 1.0f / 255.0f; 2808 const f32 inv = 1.0f / 255.0f;
2809 2809
2810 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.Shininess); 2810 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.Shininess);
2811 // disable Specular colors if no shininess is set 2811 // disable Specular colors if no shininess is set
2812 if ((material.Shininess != 0.0f) && 2812 if ((material.Shininess != 0.0f) &&
2813 (material.ColorMaterial != video::ECM_SPECULAR)) 2813 (material.ColorMaterial != video::ECM_SPECULAR))
2814 { 2814 {
2815#ifdef GL_EXT_separate_specular_color 2815#ifdef GL_EXT_separate_specular_color
2816 if (FeatureAvailable[IRR_EXT_separate_specular_color]) 2816 if (FeatureAvailable[IRR_EXT_separate_specular_color])
2817 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); 2817 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
2818#endif 2818#endif
2819 color[0] = material.SpecularColor.getRed() * inv; 2819 color[0] = material.SpecularColor.getRed() * inv;
2820 color[1] = material.SpecularColor.getGreen() * inv; 2820 color[1] = material.SpecularColor.getGreen() * inv;
2821 color[2] = material.SpecularColor.getBlue() * inv; 2821 color[2] = material.SpecularColor.getBlue() * inv;
2822 color[3] = material.SpecularColor.getAlpha() * inv; 2822 color[3] = material.SpecularColor.getAlpha() * inv;
2823 } 2823 }
2824#ifdef GL_EXT_separate_specular_color 2824#ifdef GL_EXT_separate_specular_color
2825 else if (FeatureAvailable[IRR_EXT_separate_specular_color]) 2825 else if (FeatureAvailable[IRR_EXT_separate_specular_color])
2826 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); 2826 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
2827#endif 2827#endif
2828 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); 2828 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
2829 } 2829 }
2830 2830
2831 // Texture filter 2831 // Texture filter
2832 // Has to be checked always because it depends on the textures 2832 // Has to be checked always because it depends on the textures
2833 // Filtering has to be set for each texture layer 2833 // Filtering has to be set for each texture layer
2834 for (u32 i=0; i<MaxTextureUnits; ++i) 2834 for (u32 i=0; i<MaxTextureUnits; ++i)
2835 { 2835 {
2836 if (!CurrentTexture[i]) 2836 if (!CurrentTexture[i])
2837 continue; 2837 continue;
2838 if (MultiTextureExtension) 2838 if (MultiTextureExtension)
2839 extGlActiveTexture(GL_TEXTURE0_ARB + i); 2839 extGlActiveTexture(GL_TEXTURE0_ARB + i);
2840 else if (i>0) 2840 else if (i>0)
2841 break; 2841 break;
2842 2842
2843#ifdef GL_EXT_texture_lod_bias 2843#ifdef GL_EXT_texture_lod_bias
2844 if (FeatureAvailable[IRR_EXT_texture_lod_bias]) 2844 if (FeatureAvailable[IRR_EXT_texture_lod_bias])
2845 { 2845 {
2846 if (material.TextureLayer[i].LODBias) 2846 if (material.TextureLayer[i].LODBias)
2847 { 2847 {
2848 const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias); 2848 const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
2849 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp); 2849 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp);
2850 } 2850 }
2851 else 2851 else
2852 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f); 2852 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
2853 } 2853 }
2854#endif 2854#endif
2855 2855
2856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 2856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
2857 (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); 2857 (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
2858 2858
2859 if (material.UseMipMaps && CurrentTexture[i]->hasMipMaps()) 2859 if (material.UseMipMaps && CurrentTexture[i]->hasMipMaps())
2860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 2860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
2861 material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : 2861 material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR :
2862 material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : 2862 material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST :
2863 GL_NEAREST_MIPMAP_NEAREST); 2863 GL_NEAREST_MIPMAP_NEAREST);
2864 else 2864 else
2865 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 2865 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
2866 (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); 2866 (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
2867 2867
2868#ifdef GL_EXT_texture_filter_anisotropic 2868#ifdef GL_EXT_texture_filter_anisotropic
2869 if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic]) 2869 if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic])
2870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
2871 material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1); 2871 material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1);
2872#endif 2872#endif
2873 } 2873 }
2874 2874
2875 // fillmode 2875 // fillmode
2876 if (resetAllRenderStates || (lastmaterial.Wireframe != material.Wireframe) || (lastmaterial.PointCloud != material.PointCloud)) 2876 if (resetAllRenderStates || (lastmaterial.Wireframe != material.Wireframe) || (lastmaterial.PointCloud != material.PointCloud))
2877 glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL); 2877 glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL);
2878 2878
2879 // shademode 2879 // shademode
2880 if (resetAllRenderStates || (lastmaterial.GouraudShading != material.GouraudShading)) 2880 if (resetAllRenderStates || (lastmaterial.GouraudShading != material.GouraudShading))
2881 { 2881 {
2882 if (material.GouraudShading) 2882 if (material.GouraudShading)
2883 glShadeModel(GL_SMOOTH); 2883 glShadeModel(GL_SMOOTH);
2884 else 2884 else
2885 glShadeModel(GL_FLAT); 2885 glShadeModel(GL_FLAT);
2886 } 2886 }
2887 2887
2888 // lighting 2888 // lighting
2889 if (resetAllRenderStates || (lastmaterial.Lighting != material.Lighting)) 2889 if (resetAllRenderStates || (lastmaterial.Lighting != material.Lighting))
2890 { 2890 {
2891 if (material.Lighting) 2891 if (material.Lighting)
2892 glEnable(GL_LIGHTING); 2892 glEnable(GL_LIGHTING);
2893 else 2893 else
2894 glDisable(GL_LIGHTING); 2894 glDisable(GL_LIGHTING);
2895 } 2895 }
2896 2896
2897 // zbuffer 2897 // zbuffer
2898 if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer) 2898 if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer)
2899 { 2899 {
2900 switch (material.ZBuffer) 2900 switch (material.ZBuffer)
2901 { 2901 {
2902 case ECFN_NEVER: 2902 case ECFN_NEVER:
2903 glDisable(GL_DEPTH_TEST); 2903 glDisable(GL_DEPTH_TEST);
2904 break; 2904 break;
2905 case ECFN_LESSEQUAL: 2905 case ECFN_LESSEQUAL:
2906 glEnable(GL_DEPTH_TEST); 2906 glEnable(GL_DEPTH_TEST);
2907 glDepthFunc(GL_LEQUAL); 2907 glDepthFunc(GL_LEQUAL);
2908 break; 2908 break;
2909 case ECFN_EQUAL: 2909 case ECFN_EQUAL:
2910 glEnable(GL_DEPTH_TEST); 2910 glEnable(GL_DEPTH_TEST);
2911 glDepthFunc(GL_EQUAL); 2911 glDepthFunc(GL_EQUAL);
2912 break; 2912 break;
2913 case ECFN_LESS: 2913 case ECFN_LESS:
2914 glEnable(GL_DEPTH_TEST); 2914 glEnable(GL_DEPTH_TEST);
2915 glDepthFunc(GL_LESS); 2915 glDepthFunc(GL_LESS);
2916 break; 2916 break;
2917 case ECFN_NOTEQUAL: 2917 case ECFN_NOTEQUAL:
2918 glEnable(GL_DEPTH_TEST); 2918 glEnable(GL_DEPTH_TEST);
2919 glDepthFunc(GL_NOTEQUAL); 2919 glDepthFunc(GL_NOTEQUAL);
2920 break; 2920 break;
2921 case ECFN_GREATEREQUAL: 2921 case ECFN_GREATEREQUAL:
2922 glEnable(GL_DEPTH_TEST); 2922 glEnable(GL_DEPTH_TEST);
2923 glDepthFunc(GL_GEQUAL); 2923 glDepthFunc(GL_GEQUAL);
2924 break; 2924 break;
2925 case ECFN_GREATER: 2925 case ECFN_GREATER:
2926 glEnable(GL_DEPTH_TEST); 2926 glEnable(GL_DEPTH_TEST);
2927 glDepthFunc(GL_GREATER); 2927 glDepthFunc(GL_GREATER);
2928 break; 2928 break;
2929 case ECFN_ALWAYS: 2929 case ECFN_ALWAYS:
2930 glEnable(GL_DEPTH_TEST); 2930 glEnable(GL_DEPTH_TEST);
2931 glDepthFunc(GL_ALWAYS); 2931 glDepthFunc(GL_ALWAYS);
2932 break; 2932 break;
2933 } 2933 }
2934 } 2934 }
2935 2935
2936 // zwrite 2936 // zwrite
2937// if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable) 2937// if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable)
2938 { 2938 {
2939 if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) 2939 if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent()))
2940 { 2940 {
2941 glDepthMask(GL_TRUE); 2941 glDepthMask(GL_TRUE);
2942 } 2942 }
2943 else 2943 else
2944 glDepthMask(GL_FALSE); 2944 glDepthMask(GL_FALSE);
2945 } 2945 }
2946 2946
2947 // back face culling 2947 // back face culling
2948 if (resetAllRenderStates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) 2948 if (resetAllRenderStates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling))
2949 { 2949 {
2950 if ((material.FrontfaceCulling) && (material.BackfaceCulling)) 2950 if ((material.FrontfaceCulling) && (material.BackfaceCulling))
2951 { 2951 {
2952 glCullFace(GL_FRONT_AND_BACK); 2952 glCullFace(GL_FRONT_AND_BACK);
2953 glEnable(GL_CULL_FACE); 2953 glEnable(GL_CULL_FACE);
2954 } 2954 }
2955 else 2955 else
2956 if (material.BackfaceCulling) 2956 if (material.BackfaceCulling)
2957 { 2957 {
2958 glCullFace(GL_BACK); 2958 glCullFace(GL_BACK);
2959 glEnable(GL_CULL_FACE); 2959 glEnable(GL_CULL_FACE);
2960 } 2960 }
2961 else 2961 else
2962 if (material.FrontfaceCulling) 2962 if (material.FrontfaceCulling)
2963 { 2963 {
2964 glCullFace(GL_FRONT); 2964 glCullFace(GL_FRONT);
2965 glEnable(GL_CULL_FACE); 2965 glEnable(GL_CULL_FACE);
2966 } 2966 }
2967 else 2967 else
2968 glDisable(GL_CULL_FACE); 2968 glDisable(GL_CULL_FACE);
2969 } 2969 }
2970 2970
2971 // fog 2971 // fog
2972 if (resetAllRenderStates || lastmaterial.FogEnable != material.FogEnable) 2972 if (resetAllRenderStates || lastmaterial.FogEnable != material.FogEnable)
2973 { 2973 {
2974 if (material.FogEnable) 2974 if (material.FogEnable)
2975 glEnable(GL_FOG); 2975 glEnable(GL_FOG);
2976 else 2976 else
2977 glDisable(GL_FOG); 2977 glDisable(GL_FOG);
2978 } 2978 }
2979 2979
2980 // normalization 2980 // normalization
2981 if (resetAllRenderStates || lastmaterial.NormalizeNormals != material.NormalizeNormals) 2981 if (resetAllRenderStates || lastmaterial.NormalizeNormals != material.NormalizeNormals)
2982 { 2982 {
2983 if (material.NormalizeNormals) 2983 if (material.NormalizeNormals)
2984 glEnable(GL_NORMALIZE); 2984 glEnable(GL_NORMALIZE);
2985 else 2985 else
2986 glDisable(GL_NORMALIZE); 2986 glDisable(GL_NORMALIZE);
2987 } 2987 }
2988 2988
2989 // Color Mask 2989 // Color Mask
2990 if (resetAllRenderStates || lastmaterial.ColorMask != material.ColorMask) 2990 if (resetAllRenderStates || lastmaterial.ColorMask != material.ColorMask)
2991 { 2991 {
2992 glColorMask( 2992 glColorMask(
2993 (material.ColorMask & ECP_RED)?GL_TRUE:GL_FALSE, 2993 (material.ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
2994 (material.ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE, 2994 (material.ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
2995 (material.ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE, 2995 (material.ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
2996 (material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE); 2996 (material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
2997 } 2997 }
2998 2998
2999 if (queryFeature(EVDF_BLEND_OPERATIONS) && 2999 if (queryFeature(EVDF_BLEND_OPERATIONS) &&
3000 (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation)) 3000 (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation))
3001 { 3001 {
3002 if (material.BlendOperation==EBO_NONE) 3002 if (material.BlendOperation==EBO_NONE)
3003 glDisable(GL_BLEND); 3003 glDisable(GL_BLEND);
3004 else 3004 else
3005 { 3005 {
3006 glEnable(GL_BLEND); 3006 glEnable(GL_BLEND);
3007#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) || defined(GL_VERSION_1_2) 3007#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) || defined(GL_VERSION_1_2)
3008 switch (material.BlendOperation) 3008 switch (material.BlendOperation)
3009 { 3009 {
3010 case EBO_SUBTRACT: 3010 case EBO_SUBTRACT:
3011#if defined(GL_EXT_blend_subtract) 3011#if defined(GL_EXT_blend_subtract)
3012 if (FeatureAvailable[IRR_EXT_blend_subtract] || (Version>=120)) 3012 if (FeatureAvailable[IRR_EXT_blend_subtract] || (Version>=120))
3013 extGlBlendEquation(GL_FUNC_SUBTRACT_EXT); 3013 extGlBlendEquation(GL_FUNC_SUBTRACT_EXT);
3014#elif defined(GL_VERSION_1_2) 3014#elif defined(GL_VERSION_1_2)
3015 if (Version>=120) 3015 if (Version>=120)
3016 extGlBlendEquation(GL_FUNC_SUBTRACT); 3016 extGlBlendEquation(GL_FUNC_SUBTRACT);
3017#endif 3017#endif
3018 break; 3018 break;
3019 case EBO_REVSUBTRACT: 3019 case EBO_REVSUBTRACT:
3020#if defined(GL_EXT_blend_subtract) 3020#if defined(GL_EXT_blend_subtract)
3021 if (FeatureAvailable[IRR_EXT_blend_subtract] || (Version>=120)) 3021 if (FeatureAvailable[IRR_EXT_blend_subtract] || (Version>=120))
3022 extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT); 3022 extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT);
3023#elif defined(GL_VERSION_1_2) 3023#elif defined(GL_VERSION_1_2)
3024 if (Version>=120) 3024 if (Version>=120)
3025 extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT); 3025 extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
3026#endif 3026#endif
3027 break; 3027 break;
3028 case EBO_MIN: 3028 case EBO_MIN:
3029#if defined(GL_EXT_blend_minmax) 3029#if defined(GL_EXT_blend_minmax)
3030 if (FeatureAvailable[IRR_EXT_blend_minmax] || (Version>=120)) 3030 if (FeatureAvailable[IRR_EXT_blend_minmax] || (Version>=120))
3031 extGlBlendEquation(GL_MIN_EXT); 3031 extGlBlendEquation(GL_MIN_EXT);
3032#elif defined(GL_VERSION_1_2) 3032#elif defined(GL_VERSION_1_2)
3033 if (Version>=120) 3033 if (Version>=120)
3034 extGlBlendEquation(GL_MIN); 3034 extGlBlendEquation(GL_MIN);
3035#endif 3035#endif
3036 break; 3036 break;
3037 case EBO_MAX: 3037 case EBO_MAX:
3038#if defined(GL_EXT_blend_minmax) 3038#if defined(GL_EXT_blend_minmax)
3039 if (FeatureAvailable[IRR_EXT_blend_minmax] || (Version>=120)) 3039 if (FeatureAvailable[IRR_EXT_blend_minmax] || (Version>=120))
3040 extGlBlendEquation(GL_MAX_EXT); 3040 extGlBlendEquation(GL_MAX_EXT);
3041#elif defined(GL_VERSION_1_2) 3041#elif defined(GL_VERSION_1_2)
3042 if (Version>=120) 3042 if (Version>=120)
3043 extGlBlendEquation(GL_MAX); 3043 extGlBlendEquation(GL_MAX);
3044#endif 3044#endif
3045 break; 3045 break;
3046 case EBO_MIN_FACTOR: 3046 case EBO_MIN_FACTOR:
3047#if defined(GL_AMD_blend_minmax_factor) 3047#if defined(GL_AMD_blend_minmax_factor)
3048 if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) 3048 if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
3049 extGlBlendEquation(GL_FACTOR_MIN_AMD); 3049 extGlBlendEquation(GL_FACTOR_MIN_AMD);
3050#endif 3050#endif
3051 // fallback in case of missing extension 3051 // fallback in case of missing extension
3052#if defined(GL_VERSION_1_2) 3052#if defined(GL_VERSION_1_2)
3053#if defined(GL_AMD_blend_minmax_factor) 3053#if defined(GL_AMD_blend_minmax_factor)
3054 else 3054 else
3055#endif 3055#endif
3056 if (Version>=120) 3056 if (Version>=120)
3057 extGlBlendEquation(GL_MIN); 3057 extGlBlendEquation(GL_MIN);
3058#endif 3058#endif
3059 break; 3059 break;
3060 case EBO_MAX_FACTOR: 3060 case EBO_MAX_FACTOR:
3061#if defined(GL_AMD_blend_minmax_factor) 3061#if defined(GL_AMD_blend_minmax_factor)
3062 if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) 3062 if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
3063 extGlBlendEquation(GL_FACTOR_MAX_AMD); 3063 extGlBlendEquation(GL_FACTOR_MAX_AMD);
3064#endif 3064#endif
3065 // fallback in case of missing extension 3065 // fallback in case of missing extension
3066#if defined(GL_VERSION_1_2) 3066#if defined(GL_VERSION_1_2)
3067#if defined(GL_AMD_blend_minmax_factor) 3067#if defined(GL_AMD_blend_minmax_factor)
3068 else 3068 else
3069#endif 3069#endif
3070 if (Version>=120) 3070 if (Version>=120)
3071 extGlBlendEquation(GL_MAX); 3071 extGlBlendEquation(GL_MAX);
3072#endif 3072#endif
3073 break; 3073 break;
3074 case EBO_MIN_ALPHA: 3074 case EBO_MIN_ALPHA:
3075#if defined(GL_SGIX_blend_alpha_minmax) 3075#if defined(GL_SGIX_blend_alpha_minmax)
3076 if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax]) 3076 if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax])
3077 extGlBlendEquation(GL_ALPHA_MIN_SGIX); 3077 extGlBlendEquation(GL_ALPHA_MIN_SGIX);
3078 // fallback in case of missing extension 3078 // fallback in case of missing extension
3079 else 3079 else
3080 if (FeatureAvailable[IRR_EXT_blend_minmax]) 3080 if (FeatureAvailable[IRR_EXT_blend_minmax])
3081 extGlBlendEquation(GL_MIN_EXT); 3081 extGlBlendEquation(GL_MIN_EXT);
3082#endif 3082#endif
3083 break; 3083 break;
3084 case EBO_MAX_ALPHA: 3084 case EBO_MAX_ALPHA:
3085#if defined(GL_SGIX_blend_alpha_minmax) 3085#if defined(GL_SGIX_blend_alpha_minmax)
3086 if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax]) 3086 if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax])
3087 extGlBlendEquation(GL_ALPHA_MAX_SGIX); 3087 extGlBlendEquation(GL_ALPHA_MAX_SGIX);
3088 // fallback in case of missing extension 3088 // fallback in case of missing extension
3089 else 3089 else
3090 if (FeatureAvailable[IRR_EXT_blend_minmax]) 3090 if (FeatureAvailable[IRR_EXT_blend_minmax])
3091 extGlBlendEquation(GL_MAX_EXT); 3091 extGlBlendEquation(GL_MAX_EXT);
3092#endif 3092#endif
3093 break; 3093 break;
3094 default: 3094 default:
3095#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) 3095#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op)
3096 extGlBlendEquation(GL_FUNC_ADD_EXT); 3096 extGlBlendEquation(GL_FUNC_ADD_EXT);
3097#elif defined(GL_VERSION_1_2) 3097#elif defined(GL_VERSION_1_2)
3098 extGlBlendEquation(GL_FUNC_ADD); 3098 extGlBlendEquation(GL_FUNC_ADD);
3099#endif 3099#endif
3100 break; 3100 break;
3101 } 3101 }
3102#endif 3102#endif
3103 } 3103 }
3104 } 3104 }
3105 3105
3106 // Polygon Offset 3106 // Polygon Offset
3107 if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderStates || 3107 if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderStates ||
3108 lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || 3108 lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
3109 lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) 3109 lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor))
3110 { 3110 {
3111 glDisable(lastmaterial.Wireframe?GL_POLYGON_OFFSET_LINE:lastmaterial.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL); 3111 glDisable(lastmaterial.Wireframe?GL_POLYGON_OFFSET_LINE:lastmaterial.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL);
3112 if (material.PolygonOffsetFactor) 3112 if (material.PolygonOffsetFactor)
3113 { 3113 {
3114 glDisable(material.Wireframe?GL_POLYGON_OFFSET_LINE:material.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL); 3114 glDisable(material.Wireframe?GL_POLYGON_OFFSET_LINE:material.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL);
3115 glEnable(material.Wireframe?GL_POLYGON_OFFSET_LINE:material.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL); 3115 glEnable(material.Wireframe?GL_POLYGON_OFFSET_LINE:material.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL);
3116 } 3116 }
3117 if (material.PolygonOffsetDirection==EPO_BACK) 3117 if (material.PolygonOffsetDirection==EPO_BACK)
3118 glPolygonOffset(1.0f, (GLfloat)material.PolygonOffsetFactor); 3118 glPolygonOffset(1.0f, (GLfloat)material.PolygonOffsetFactor);
3119 else 3119 else
3120 glPolygonOffset(-1.0f, (GLfloat)-material.PolygonOffsetFactor); 3120 glPolygonOffset(-1.0f, (GLfloat)-material.PolygonOffsetFactor);
3121 } 3121 }
3122 3122
3123 // thickness 3123 // thickness
3124 if (resetAllRenderStates || lastmaterial.Thickness != material.Thickness) 3124 if (resetAllRenderStates || lastmaterial.Thickness != material.Thickness)
3125 { 3125 {
3126 if (AntiAlias) 3126 if (AntiAlias)
3127 { 3127 {
3128// glPointSize(core::clamp(static_cast<GLfloat>(material.Thickness), DimSmoothedPoint[0], DimSmoothedPoint[1])); 3128// glPointSize(core::clamp(static_cast<GLfloat>(material.Thickness), DimSmoothedPoint[0], DimSmoothedPoint[1]));
3129 // we don't use point smoothing 3129 // we don't use point smoothing
3130 glPointSize(core::clamp(static_cast<GLfloat>(material.Thickness), DimAliasedPoint[0], DimAliasedPoint[1])); 3130 glPointSize(core::clamp(static_cast<GLfloat>(material.Thickness), DimAliasedPoint[0], DimAliasedPoint[1]));
3131 glLineWidth(core::clamp(static_cast<GLfloat>(material.Thickness), DimSmoothedLine[0], DimSmoothedLine[1])); 3131 glLineWidth(core::clamp(static_cast<GLfloat>(material.Thickness), DimSmoothedLine[0], DimSmoothedLine[1]));
3132 } 3132 }
3133 else 3133 else
3134 { 3134 {
3135 glPointSize(core::clamp(static_cast<GLfloat>(material.Thickness), DimAliasedPoint[0], DimAliasedPoint[1])); 3135 glPointSize(core::clamp(static_cast<GLfloat>(material.Thickness), DimAliasedPoint[0], DimAliasedPoint[1]));
3136 glLineWidth(core::clamp(static_cast<GLfloat>(material.Thickness), DimAliasedLine[0], DimAliasedLine[1])); 3136 glLineWidth(core::clamp(static_cast<GLfloat>(material.Thickness), DimAliasedLine[0], DimAliasedLine[1]));
3137 } 3137 }
3138 } 3138 }
3139 3139
3140 // Anti aliasing 3140 // Anti aliasing
3141 if (resetAllRenderStates || lastmaterial.AntiAliasing != material.AntiAliasing) 3141 if (resetAllRenderStates || lastmaterial.AntiAliasing != material.AntiAliasing)
3142 { 3142 {
3143 if (FeatureAvailable[IRR_ARB_multisample]) 3143 if (FeatureAvailable[IRR_ARB_multisample])
3144 { 3144 {
3145 if (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE) 3145 if (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)
3146 glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); 3146 glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
3147 else if (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE) 3147 else if (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)
3148 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); 3148 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
3149 3149
3150 if ((AntiAlias >= 2) && (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))) 3150 if ((AntiAlias >= 2) && (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)))
3151 { 3151 {
3152 glEnable(GL_MULTISAMPLE_ARB); 3152 glEnable(GL_MULTISAMPLE_ARB);
3153#ifdef GL_NV_multisample_filter_hint 3153#ifdef GL_NV_multisample_filter_hint
3154 if (FeatureAvailable[IRR_NV_multisample_filter_hint]) 3154 if (FeatureAvailable[IRR_NV_multisample_filter_hint])
3155 { 3155 {
3156 if ((material.AntiAliasing & EAAM_QUALITY) == EAAM_QUALITY) 3156 if ((material.AntiAliasing & EAAM_QUALITY) == EAAM_QUALITY)
3157 glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); 3157 glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
3158 else 3158 else
3159 glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); 3159 glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
3160 } 3160 }
3161#endif 3161#endif
3162 } 3162 }
3163 else 3163 else
3164 glDisable(GL_MULTISAMPLE_ARB); 3164 glDisable(GL_MULTISAMPLE_ARB);
3165 } 3165 }
3166 if ((material.AntiAliasing & EAAM_LINE_SMOOTH) != (lastmaterial.AntiAliasing & EAAM_LINE_SMOOTH)) 3166 if ((material.AntiAliasing & EAAM_LINE_SMOOTH) != (lastmaterial.AntiAliasing & EAAM_LINE_SMOOTH))
3167 { 3167 {
3168 if (material.AntiAliasing & EAAM_LINE_SMOOTH) 3168 if (material.AntiAliasing & EAAM_LINE_SMOOTH)
3169 glEnable(GL_LINE_SMOOTH); 3169 glEnable(GL_LINE_SMOOTH);
3170 else if (lastmaterial.AntiAliasing & EAAM_LINE_SMOOTH) 3170 else if (lastmaterial.AntiAliasing & EAAM_LINE_SMOOTH)
3171 glDisable(GL_LINE_SMOOTH); 3171 glDisable(GL_LINE_SMOOTH);
3172 } 3172 }
3173 if ((material.AntiAliasing & EAAM_POINT_SMOOTH) != (lastmaterial.AntiAliasing & EAAM_POINT_SMOOTH)) 3173 if ((material.AntiAliasing & EAAM_POINT_SMOOTH) != (lastmaterial.AntiAliasing & EAAM_POINT_SMOOTH))
3174 { 3174 {
3175 if (material.AntiAliasing & EAAM_POINT_SMOOTH) 3175 if (material.AntiAliasing & EAAM_POINT_SMOOTH)
3176 // often in software, and thus very slow 3176 // often in software, and thus very slow
3177 glEnable(GL_POINT_SMOOTH); 3177 glEnable(GL_POINT_SMOOTH);
3178 else if (lastmaterial.AntiAliasing & EAAM_POINT_SMOOTH) 3178 else if (lastmaterial.AntiAliasing & EAAM_POINT_SMOOTH)
3179 glDisable(GL_POINT_SMOOTH); 3179 glDisable(GL_POINT_SMOOTH);
3180 } 3180 }
3181 } 3181 }
3182 3182
3183 setWrapMode(material); 3183 setWrapMode(material);
3184 3184
3185 // be sure to leave in texture stage 0 3185 // be sure to leave in texture stage 0
3186 if (MultiTextureExtension) 3186 if (MultiTextureExtension)
3187 extGlActiveTexture(GL_TEXTURE0_ARB); 3187 extGlActiveTexture(GL_TEXTURE0_ARB);
3188} 3188}
3189 3189
3190 3190
3191//! Enable the 2d override material 3191//! Enable the 2d override material
3192void COpenGLDriver::enableMaterial2D(bool enable) 3192void COpenGLDriver::enableMaterial2D(bool enable)
3193{ 3193{
3194 if (!enable) 3194 if (!enable)
3195 CurrentRenderMode = ERM_NONE; 3195 CurrentRenderMode = ERM_NONE;
3196 CNullDriver::enableMaterial2D(enable); 3196 CNullDriver::enableMaterial2D(enable);
3197} 3197}
3198 3198
3199 3199
3200//! sets the needed renderstates 3200//! sets the needed renderstates
3201void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) 3201void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel)
3202{ 3202{
3203 if (CurrentRenderMode != ERM_2D || Transformation3DChanged) 3203 if (CurrentRenderMode != ERM_2D || Transformation3DChanged)
3204 { 3204 {
3205 // unset last 3d material 3205 // unset last 3d material
3206 if (CurrentRenderMode == ERM_3D) 3206 if (CurrentRenderMode == ERM_3D)
3207 { 3207 {
3208 if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) 3208 if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
3209 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); 3209 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
3210 } 3210 }
3211 if (Transformation3DChanged) 3211 if (Transformation3DChanged)
3212 { 3212 {
3213 glMatrixMode(GL_PROJECTION); 3213 glMatrixMode(GL_PROJECTION);
3214 3214
3215 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 3215 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
3216 core::matrix4 m(core::matrix4::EM4CONST_NOTHING); 3216 core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
3217 m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f); 3217 m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);
3218 m.setTranslation(core::vector3df(-1,1,0)); 3218 m.setTranslation(core::vector3df(-1,1,0));
3219 glLoadMatrixf(m.pointer()); 3219 glLoadMatrixf(m.pointer());
3220 3220
3221 glMatrixMode(GL_MODELVIEW); 3221 glMatrixMode(GL_MODELVIEW);
3222 glLoadIdentity(); 3222 glLoadIdentity();
3223 glTranslatef(0.375f, 0.375f, 0.0f); 3223 glTranslatef(0.375f, 0.375f, 0.0f);
3224 3224
3225 // Make sure we set first texture matrix 3225 // Make sure we set first texture matrix
3226 if (MultiTextureExtension) 3226 if (MultiTextureExtension)
3227 extGlActiveTexture(GL_TEXTURE0_ARB); 3227 extGlActiveTexture(GL_TEXTURE0_ARB);
3228 3228
3229 Transformation3DChanged = false; 3229 Transformation3DChanged = false;
3230 } 3230 }
3231 if (!OverrideMaterial2DEnabled) 3231 if (!OverrideMaterial2DEnabled)
3232 { 3232 {
3233 setBasicRenderStates(InitMaterial2D, LastMaterial, true); 3233 setBasicRenderStates(InitMaterial2D, LastMaterial, true);
3234 LastMaterial = InitMaterial2D; 3234 LastMaterial = InitMaterial2D;
3235 } 3235 }
3236 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 3236 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3237#ifdef GL_EXT_clip_volume_hint 3237#ifdef GL_EXT_clip_volume_hint
3238 if (FeatureAvailable[IRR_EXT_clip_volume_hint]) 3238 if (FeatureAvailable[IRR_EXT_clip_volume_hint])
3239 glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); 3239 glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
3240#endif 3240#endif
3241 3241
3242 } 3242 }
3243 if (OverrideMaterial2DEnabled) 3243 if (OverrideMaterial2DEnabled)
3244 { 3244 {
3245 OverrideMaterial2D.Lighting=false; 3245 OverrideMaterial2D.Lighting=false;
3246 setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); 3246 setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
3247 LastMaterial = OverrideMaterial2D; 3247 LastMaterial = OverrideMaterial2D;
3248 } 3248 }
3249 3249
3250 // no alphaChannel without texture 3250 // no alphaChannel without texture
3251 alphaChannel &= texture; 3251 alphaChannel &= texture;
3252 3252
3253 if (alphaChannel || alpha) 3253 if (alphaChannel || alpha)
3254 { 3254 {
3255 glEnable(GL_BLEND); 3255 glEnable(GL_BLEND);
3256 glEnable(GL_ALPHA_TEST); 3256 glEnable(GL_ALPHA_TEST);
3257 glAlphaFunc(GL_GREATER, 0.f); 3257 glAlphaFunc(GL_GREATER, 0.f);
3258 } 3258 }
3259 else 3259 else
3260 { 3260 {
3261 glDisable(GL_BLEND); 3261 glDisable(GL_BLEND);
3262 glDisable(GL_ALPHA_TEST); 3262 glDisable(GL_ALPHA_TEST);
3263 } 3263 }
3264 3264
3265 if (texture) 3265 if (texture)
3266 { 3266 {
3267 if (!OverrideMaterial2DEnabled) 3267 if (!OverrideMaterial2DEnabled)
3268 { 3268 {
3269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3271 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 3271 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
3272 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 3272 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
3273 } 3273 }
3274 Material.setTexture(0, const_cast<video::ITexture*>(CurrentTexture[0])); 3274 Material.setTexture(0, const_cast<video::ITexture*>(CurrentTexture[0]));
3275 setTransform(ETS_TEXTURE_0, core::IdentityMatrix); 3275 setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
3276 // Due to the transformation change, the previous line would call a reset each frame 3276 // Due to the transformation change, the previous line would call a reset each frame
3277 // but we can safely reset the variable as it was false before 3277 // but we can safely reset the variable as it was false before
3278 Transformation3DChanged=false; 3278 Transformation3DChanged=false;
3279 3279
3280 if (alphaChannel) 3280 if (alphaChannel)
3281 { 3281 {
3282 // if alpha and alpha texture just modulate, otherwise use only the alpha channel 3282 // if alpha and alpha texture just modulate, otherwise use only the alpha channel
3283 if (alpha) 3283 if (alpha)
3284 { 3284 {
3285 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 3285 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3286 } 3286 }
3287 else 3287 else
3288 { 3288 {
3289#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) 3289#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine)
3290 if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) 3290 if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine])
3291 { 3291 {
3292#ifdef GL_ARB_texture_env_combine 3292#ifdef GL_ARB_texture_env_combine
3293 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); 3293 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3294 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 3294 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
3295 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); 3295 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
3296 // rgb always modulates 3296 // rgb always modulates
3297 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 3297 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
3298 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 3298 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
3299 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 3299 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
3300#else 3300#else
3301 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); 3301 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3302 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); 3302 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
3303 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); 3303 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
3304 // rgb always modulates 3304 // rgb always modulates
3305 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); 3305 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
3306 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); 3306 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
3307 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); 3307 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
3308#endif 3308#endif
3309 } 3309 }
3310 else 3310 else
3311#endif 3311#endif
3312 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 3312 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3313 } 3313 }
3314 } 3314 }
3315 else 3315 else
3316 { 3316 {
3317 if (alpha) 3317 if (alpha)
3318 { 3318 {
3319#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) 3319#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine)
3320 if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) 3320 if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine])
3321 { 3321 {
3322#ifdef GL_ARB_texture_env_combine 3322#ifdef GL_ARB_texture_env_combine
3323 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); 3323 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
3324 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 3324 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
3325 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 3325 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
3326 // rgb always modulates 3326 // rgb always modulates
3327 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 3327 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
3328 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 3328 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
3329 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 3329 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
3330#else 3330#else
3331 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); 3331 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
3332 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); 3332 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
3333 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); 3333 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
3334 // rgb always modulates 3334 // rgb always modulates
3335 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); 3335 glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
3336 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); 3336 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
3337 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); 3337 glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
3338#endif 3338#endif
3339 } 3339 }
3340 else 3340 else
3341#endif 3341#endif
3342 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 3342 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3343 } 3343 }
3344 else 3344 else
3345 { 3345 {
3346 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 3346 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3347 } 3347 }
3348 } 3348 }
3349 } 3349 }
3350 3350
3351 CurrentRenderMode = ERM_2D; 3351 CurrentRenderMode = ERM_2D;
3352} 3352}
3353 3353
3354 3354
3355//! \return Returns the name of the video driver. 3355//! \return Returns the name of the video driver.
3356const wchar_t* COpenGLDriver::getName() const 3356const wchar_t* COpenGLDriver::getName() const
3357{ 3357{
3358 return Name.c_str(); 3358 return Name.c_str();
3359} 3359}
3360 3360
3361 3361
3362//! deletes all dynamic lights there are 3362//! deletes all dynamic lights there are
3363void COpenGLDriver::deleteAllDynamicLights() 3363void COpenGLDriver::deleteAllDynamicLights()
3364{ 3364{
3365 for (s32 i=0; i<MaxLights; ++i) 3365 for (s32 i=0; i<MaxLights; ++i)
3366 glDisable(GL_LIGHT0 + i); 3366 glDisable(GL_LIGHT0 + i);
3367 3367
3368 RequestedLights.clear(); 3368 RequestedLights.clear();
3369 3369
3370 CNullDriver::deleteAllDynamicLights(); 3370 CNullDriver::deleteAllDynamicLights();
3371} 3371}
3372 3372
3373 3373
3374//! adds a dynamic light 3374//! adds a dynamic light
3375s32 COpenGLDriver::addDynamicLight(const SLight& light) 3375s32 COpenGLDriver::addDynamicLight(const SLight& light)
3376{ 3376{
3377 CNullDriver::addDynamicLight(light); 3377 CNullDriver::addDynamicLight(light);
3378 3378
3379 RequestedLights.push_back(RequestedLight(light)); 3379 RequestedLights.push_back(RequestedLight(light));
3380 3380
3381 u32 newLightIndex = RequestedLights.size() - 1; 3381 u32 newLightIndex = RequestedLights.size() - 1;
3382 3382
3383 // Try and assign a hardware light just now, but don't worry if I can't 3383 // Try and assign a hardware light just now, but don't worry if I can't
3384 assignHardwareLight(newLightIndex); 3384 assignHardwareLight(newLightIndex);
3385 3385
3386 return (s32)newLightIndex; 3386 return (s32)newLightIndex;
3387} 3387}
3388 3388
3389 3389
3390void COpenGLDriver::assignHardwareLight(u32 lightIndex) 3390void COpenGLDriver::assignHardwareLight(u32 lightIndex)
3391{ 3391{
3392 setTransform(ETS_WORLD, core::matrix4()); 3392 setTransform(ETS_WORLD, core::matrix4());
3393 3393
3394 s32 lidx; 3394 s32 lidx;
3395 for (lidx=GL_LIGHT0; lidx < GL_LIGHT0 + MaxLights; ++lidx) 3395 for (lidx=GL_LIGHT0; lidx < GL_LIGHT0 + MaxLights; ++lidx)
3396 { 3396 {
3397 if(!glIsEnabled(lidx)) 3397 if(!glIsEnabled(lidx))
3398 { 3398 {
3399 RequestedLights[lightIndex].HardwareLightIndex = lidx; 3399 RequestedLights[lightIndex].HardwareLightIndex = lidx;
3400 break; 3400 break;
3401 } 3401 }
3402 } 3402 }
3403 3403
3404 if(lidx == GL_LIGHT0 + MaxLights) // There's no room for it just now 3404 if(lidx == GL_LIGHT0 + MaxLights) // There's no room for it just now
3405 return; 3405 return;
3406 3406
3407 GLfloat data[4]; 3407 GLfloat data[4];
3408 const SLight & light = RequestedLights[lightIndex].LightData; 3408 const SLight & light = RequestedLights[lightIndex].LightData;
3409 3409
3410 switch (light.Type) 3410 switch (light.Type)
3411 { 3411 {
3412 case video::ELT_SPOT: 3412 case video::ELT_SPOT:
3413 data[0] = light.Direction.X; 3413 data[0] = light.Direction.X;
3414 data[1] = light.Direction.Y; 3414 data[1] = light.Direction.Y;
3415 data[2] = light.Direction.Z; 3415 data[2] = light.Direction.Z;
3416 data[3] = 0.0f; 3416 data[3] = 0.0f;
3417 glLightfv(lidx, GL_SPOT_DIRECTION, data); 3417 glLightfv(lidx, GL_SPOT_DIRECTION, data);
3418 3418
3419 // set position 3419 // set position
3420 data[0] = light.Position.X; 3420 data[0] = light.Position.X;
3421 data[1] = light.Position.Y; 3421 data[1] = light.Position.Y;
3422 data[2] = light.Position.Z; 3422 data[2] = light.Position.Z;
3423 data[3] = 1.0f; // 1.0f for positional light 3423 data[3] = 1.0f; // 1.0f for positional light
3424 glLightfv(lidx, GL_POSITION, data); 3424 glLightfv(lidx, GL_POSITION, data);
3425 3425
3426 glLightf(lidx, GL_SPOT_EXPONENT, light.Falloff); 3426 glLightf(lidx, GL_SPOT_EXPONENT, light.Falloff);
3427 glLightf(lidx, GL_SPOT_CUTOFF, light.OuterCone); 3427 glLightf(lidx, GL_SPOT_CUTOFF, light.OuterCone);
3428 break; 3428 break;
3429 case video::ELT_POINT: 3429 case video::ELT_POINT:
3430 // set position 3430 // set position
3431 data[0] = light.Position.X; 3431 data[0] = light.Position.X;
3432 data[1] = light.Position.Y; 3432 data[1] = light.Position.Y;
3433 data[2] = light.Position.Z; 3433 data[2] = light.Position.Z;
3434 data[3] = 1.0f; // 1.0f for positional light 3434 data[3] = 1.0f; // 1.0f for positional light
3435 glLightfv(lidx, GL_POSITION, data); 3435 glLightfv(lidx, GL_POSITION, data);
3436 3436
3437 glLightf(lidx, GL_SPOT_EXPONENT, 0.0f); 3437 glLightf(lidx, GL_SPOT_EXPONENT, 0.0f);
3438 glLightf(lidx, GL_SPOT_CUTOFF, 180.0f); 3438 glLightf(lidx, GL_SPOT_CUTOFF, 180.0f);
3439 break; 3439 break;
3440 case video::ELT_DIRECTIONAL: 3440 case video::ELT_DIRECTIONAL:
3441 // set direction 3441 // set direction
3442 data[0] = -light.Direction.X; 3442 data[0] = -light.Direction.X;
3443 data[1] = -light.Direction.Y; 3443 data[1] = -light.Direction.Y;
3444 data[2] = -light.Direction.Z; 3444 data[2] = -light.Direction.Z;
3445 data[3] = 0.0f; // 0.0f for directional light 3445 data[3] = 0.0f; // 0.0f for directional light
3446 glLightfv(lidx, GL_POSITION, data); 3446 glLightfv(lidx, GL_POSITION, data);
3447 3447
3448 glLightf(lidx, GL_SPOT_EXPONENT, 0.0f); 3448 glLightf(lidx, GL_SPOT_EXPONENT, 0.0f);
3449 glLightf(lidx, GL_SPOT_CUTOFF, 180.0f); 3449 glLightf(lidx, GL_SPOT_CUTOFF, 180.0f);
3450 break; 3450 break;
3451 default: 3451 default:
3452 break; 3452 break;
3453 } 3453 }
3454 3454
3455 // set diffuse color 3455 // set diffuse color
3456 data[0] = light.DiffuseColor.r; 3456 data[0] = light.DiffuseColor.r;
3457 data[1] = light.DiffuseColor.g; 3457 data[1] = light.DiffuseColor.g;
3458 data[2] = light.DiffuseColor.b; 3458 data[2] = light.DiffuseColor.b;
3459 data[3] = light.DiffuseColor.a; 3459 data[3] = light.DiffuseColor.a;
3460 glLightfv(lidx, GL_DIFFUSE, data); 3460 glLightfv(lidx, GL_DIFFUSE, data);
3461 3461
3462 // set specular color 3462 // set specular color
3463 data[0] = light.SpecularColor.r; 3463 data[0] = light.SpecularColor.r;
3464 data[1] = light.SpecularColor.g; 3464 data[1] = light.SpecularColor.g;
3465 data[2] = light.SpecularColor.b; 3465 data[2] = light.SpecularColor.b;
3466 data[3] = light.SpecularColor.a; 3466 data[3] = light.SpecularColor.a;
3467 glLightfv(lidx, GL_SPECULAR, data); 3467 glLightfv(lidx, GL_SPECULAR, data);
3468 3468
3469 // set ambient color 3469 // set ambient color
3470 data[0] = light.AmbientColor.r; 3470 data[0] = light.AmbientColor.r;
3471 data[1] = light.AmbientColor.g; 3471 data[1] = light.AmbientColor.g;
3472 data[2] = light.AmbientColor.b; 3472 data[2] = light.AmbientColor.b;
3473 data[3] = light.AmbientColor.a; 3473 data[3] = light.AmbientColor.a;
3474 glLightfv(lidx, GL_AMBIENT, data); 3474 glLightfv(lidx, GL_AMBIENT, data);
3475 3475
3476 // 1.0f / (constant + linear * d + quadratic*(d*d); 3476 // 1.0f / (constant + linear * d + quadratic*(d*d);
3477 3477
3478 // set attenuation 3478 // set attenuation
3479 glLightf(lidx, GL_CONSTANT_ATTENUATION, light.Attenuation.X); 3479 glLightf(lidx, GL_CONSTANT_ATTENUATION, light.Attenuation.X);
3480 glLightf(lidx, GL_LINEAR_ATTENUATION, light.Attenuation.Y); 3480 glLightf(lidx, GL_LINEAR_ATTENUATION, light.Attenuation.Y);
3481 glLightf(lidx, GL_QUADRATIC_ATTENUATION, light.Attenuation.Z); 3481 glLightf(lidx, GL_QUADRATIC_ATTENUATION, light.Attenuation.Z);
3482 3482
3483 glEnable(lidx); 3483 glEnable(lidx);
3484} 3484}
3485 3485
3486 3486
3487//! Turns a dynamic light on or off 3487//! Turns a dynamic light on or off
3488//! \param lightIndex: the index returned by addDynamicLight 3488//! \param lightIndex: the index returned by addDynamicLight
3489//! \param turnOn: true to turn the light on, false to turn it off 3489//! \param turnOn: true to turn the light on, false to turn it off
3490void COpenGLDriver::turnLightOn(s32 lightIndex, bool turnOn) 3490void COpenGLDriver::turnLightOn(s32 lightIndex, bool turnOn)
3491{ 3491{
3492 if(lightIndex < 0 || lightIndex >= (s32)RequestedLights.size()) 3492 if(lightIndex < 0 || lightIndex >= (s32)RequestedLights.size())
3493 return; 3493 return;
3494 3494
3495 RequestedLight & requestedLight = RequestedLights[lightIndex]; 3495 RequestedLight & requestedLight = RequestedLights[lightIndex];
3496 3496
3497 requestedLight.DesireToBeOn = turnOn; 3497 requestedLight.DesireToBeOn = turnOn;
3498 3498
3499 if(turnOn) 3499 if(turnOn)
3500 { 3500 {
3501 if(-1 == requestedLight.HardwareLightIndex) 3501 if(-1 == requestedLight.HardwareLightIndex)
3502 assignHardwareLight(lightIndex); 3502 assignHardwareLight(lightIndex);
3503 } 3503 }
3504 else 3504 else
3505 { 3505 {
3506 if(-1 != requestedLight.HardwareLightIndex) 3506 if(-1 != requestedLight.HardwareLightIndex)
3507 { 3507 {
3508 // It's currently assigned, so free up the hardware light 3508 // It's currently assigned, so free up the hardware light
3509 glDisable(requestedLight.HardwareLightIndex); 3509 glDisable(requestedLight.HardwareLightIndex);
3510 requestedLight.HardwareLightIndex = -1; 3510 requestedLight.HardwareLightIndex = -1;
3511 3511
3512 // Now let the first light that's waiting on a free hardware light grab it 3512 // Now let the first light that's waiting on a free hardware light grab it
3513 for(u32 requested = 0; requested < RequestedLights.size(); ++requested) 3513 for(u32 requested = 0; requested < RequestedLights.size(); ++requested)
3514 if(RequestedLights[requested].DesireToBeOn 3514 if(RequestedLights[requested].DesireToBeOn
3515 && 3515 &&
3516 -1 == RequestedLights[requested].HardwareLightIndex) 3516 -1 == RequestedLights[requested].HardwareLightIndex)
3517 { 3517 {
3518 assignHardwareLight(requested); 3518 assignHardwareLight(requested);
3519 break; 3519 break;
3520 } 3520 }
3521 } 3521 }
3522 } 3522 }
3523} 3523}
3524 3524
3525 3525
3526//! returns the maximal amount of dynamic lights the device can handle 3526//! returns the maximal amount of dynamic lights the device can handle
3527u32 COpenGLDriver::getMaximalDynamicLightAmount() const 3527u32 COpenGLDriver::getMaximalDynamicLightAmount() const
3528{ 3528{
3529 return MaxLights; 3529 return MaxLights;
3530} 3530}
3531 3531
3532 3532
3533//! Sets the dynamic ambient light color. The default color is 3533//! Sets the dynamic ambient light color. The default color is
3534//! (0,0,0,0) which means it is dark. 3534//! (0,0,0,0) which means it is dark.
3535//! \param color: New color of the ambient light. 3535//! \param color: New color of the ambient light.
3536void COpenGLDriver::setAmbientLight(const SColorf& color) 3536void COpenGLDriver::setAmbientLight(const SColorf& color)
3537{ 3537{
3538 GLfloat data[4] = {color.r, color.g, color.b, color.a}; 3538 GLfloat data[4] = {color.r, color.g, color.b, color.a};
3539 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data); 3539 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data);
3540} 3540}
3541 3541
3542 3542
3543// this code was sent in by Oliver Klems, thank you! (I modified the glViewport 3543// this code was sent in by Oliver Klems, thank you! (I modified the glViewport
3544// method just a bit. 3544// method just a bit.
3545void COpenGLDriver::setViewPort(const core::rect<s32>& area) 3545void COpenGLDriver::setViewPort(const core::rect<s32>& area)
3546{ 3546{
3547 if (area == ViewPort) 3547 if (area == ViewPort)
3548 return; 3548 return;
3549 core::rect<s32> vp = area; 3549 core::rect<s32> vp = area;
3550 core::rect<s32> rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); 3550 core::rect<s32> rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height);
3551 vp.clipAgainst(rendert); 3551 vp.clipAgainst(rendert);
3552 3552
3553 if (vp.getHeight()>0 && vp.getWidth()>0) 3553 if (vp.getHeight()>0 && vp.getWidth()>0)
3554 { 3554 {
3555 glViewport(vp.UpperLeftCorner.X, 3555 glViewport(vp.UpperLeftCorner.X,
3556 getCurrentRenderTargetSize().Height - vp.UpperLeftCorner.Y - vp.getHeight(), 3556 getCurrentRenderTargetSize().Height - vp.UpperLeftCorner.Y - vp.getHeight(),
3557 vp.getWidth(), vp.getHeight()); 3557 vp.getWidth(), vp.getHeight());
3558 3558
3559 ViewPort = vp; 3559 ViewPort = vp;
3560 } 3560 }
3561} 3561}
3562 3562
3563 3563
3564//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do 3564//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
3565//! this: First, draw all geometry. Then use this method, to draw the shadow 3565//! this: First, draw all geometry. Then use this method, to draw the shadow
3566//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow. 3566//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow.
3567void COpenGLDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) 3567void COpenGLDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)
3568{ 3568{
3569 const u32 count=triangles.size(); 3569 const u32 count=triangles.size();
3570 if (!StencilBuffer || !count) 3570 if (!StencilBuffer || !count)
3571 return; 3571 return;
3572 3572
3573 // unset last 3d material 3573 // unset last 3d material
3574 if (CurrentRenderMode == ERM_3D && 3574 if (CurrentRenderMode == ERM_3D &&
3575 static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) 3575 static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
3576 { 3576 {
3577 MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); 3577 MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial();
3578 ResetRenderStates = true; 3578 ResetRenderStates = true;
3579 } 3579 }
3580 3580
3581 // store current OpenGL state 3581 // store current OpenGL state
3582 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | 3582 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT |
3583 GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT); 3583 GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT);
3584 3584
3585 glDisable(GL_LIGHTING); 3585 glDisable(GL_LIGHTING);
3586 glDisable(GL_FOG); 3586 glDisable(GL_FOG);
3587 glDepthFunc(GL_LESS); 3587 glDepthFunc(GL_LESS);
3588 glDepthMask(GL_FALSE); // no depth buffer writing 3588 glDepthMask(GL_FALSE); // no depth buffer writing
3589 if (debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) 3589 if (debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)
3590 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 3590 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
3591 if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) 3591 if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY)))
3592 { 3592 {
3593 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no color buffer drawing 3593 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no color buffer drawing
3594 glEnable(GL_STENCIL_TEST); 3594 glEnable(GL_STENCIL_TEST);
3595 } 3595 }
3596 3596
3597 glEnableClientState(GL_VERTEX_ARRAY); 3597 glEnableClientState(GL_VERTEX_ARRAY);
3598 glVertexPointer(3,GL_FLOAT,sizeof(core::vector3df),triangles.const_pointer()); 3598 glVertexPointer(3,GL_FLOAT,sizeof(core::vector3df),triangles.const_pointer());
3599 glStencilMask(~0); 3599 glStencilMask(~0);
3600 glStencilFunc(GL_ALWAYS, 0, ~0); 3600 glStencilFunc(GL_ALWAYS, 0, ~0);
3601 3601
3602 GLenum incr = GL_INCR; 3602 GLenum incr = GL_INCR;
3603 GLenum decr = GL_DECR; 3603 GLenum decr = GL_DECR;
3604#ifdef GL_EXT_stencil_wrap 3604#ifdef GL_EXT_stencil_wrap
3605 if (FeatureAvailable[IRR_EXT_stencil_wrap]) 3605 if (FeatureAvailable[IRR_EXT_stencil_wrap])
3606 { 3606 {
3607 incr = GL_INCR_WRAP_EXT; 3607 incr = GL_INCR_WRAP_EXT;
3608 decr = GL_DECR_WRAP_EXT; 3608 decr = GL_DECR_WRAP_EXT;
3609 } 3609 }
3610#endif 3610#endif
3611#ifdef GL_NV_depth_clamp 3611#ifdef GL_NV_depth_clamp
3612 if (FeatureAvailable[IRR_NV_depth_clamp]) 3612 if (FeatureAvailable[IRR_NV_depth_clamp])
3613 glEnable(GL_DEPTH_CLAMP_NV); 3613 glEnable(GL_DEPTH_CLAMP_NV);
3614#endif 3614#endif
3615 3615
3616 // The first parts are not correctly working, yet. 3616 // The first parts are not correctly working, yet.
3617#if 0 3617#if 0
3618#ifdef GL_EXT_stencil_two_side 3618#ifdef GL_EXT_stencil_two_side
3619 if (FeatureAvailable[IRR_EXT_stencil_two_side]) 3619 if (FeatureAvailable[IRR_EXT_stencil_two_side])
3620 { 3620 {
3621 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); 3621 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
3622 glDisable(GL_CULL_FACE); 3622 glDisable(GL_CULL_FACE);
3623 if (zfail) 3623 if (zfail)
3624 { 3624 {
3625 extGlActiveStencilFace(GL_BACK); 3625 extGlActiveStencilFace(GL_BACK);
3626 glStencilOp(GL_KEEP, incr, GL_KEEP); 3626 glStencilOp(GL_KEEP, incr, GL_KEEP);
3627 glStencilMask(~0); 3627 glStencilMask(~0);
3628 glStencilFunc(GL_ALWAYS, 0, ~0); 3628 glStencilFunc(GL_ALWAYS, 0, ~0);
3629 3629
3630 extGlActiveStencilFace(GL_FRONT); 3630 extGlActiveStencilFace(GL_FRONT);
3631 glStencilOp(GL_KEEP, decr, GL_KEEP); 3631 glStencilOp(GL_KEEP, decr, GL_KEEP);
3632 } 3632 }
3633 else // zpass 3633 else // zpass
3634 { 3634 {
3635 extGlActiveStencilFace(GL_BACK); 3635 extGlActiveStencilFace(GL_BACK);
3636 glStencilOp(GL_KEEP, GL_KEEP, decr); 3636 glStencilOp(GL_KEEP, GL_KEEP, decr);
3637 glStencilMask(~0); 3637 glStencilMask(~0);
3638 glStencilFunc(GL_ALWAYS, 0, ~0); 3638 glStencilFunc(GL_ALWAYS, 0, ~0);
3639 3639
3640 extGlActiveStencilFace(GL_FRONT); 3640 extGlActiveStencilFace(GL_FRONT);
3641 glStencilOp(GL_KEEP, GL_KEEP, incr); 3641 glStencilOp(GL_KEEP, GL_KEEP, incr);
3642 } 3642 }
3643 glStencilMask(~0); 3643 glStencilMask(~0);
3644 glStencilFunc(GL_ALWAYS, 0, ~0); 3644 glStencilFunc(GL_ALWAYS, 0, ~0);
3645 glDrawArrays(GL_TRIANGLES,0,count); 3645 glDrawArrays(GL_TRIANGLES,0,count);
3646 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); 3646 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
3647 } 3647 }
3648 else 3648 else
3649#endif 3649#endif
3650 if (FeatureAvailable[IRR_ATI_separate_stencil]) 3650 if (FeatureAvailable[IRR_ATI_separate_stencil])
3651 { 3651 {
3652 glDisable(GL_CULL_FACE); 3652 glDisable(GL_CULL_FACE);
3653 if (zfail) 3653 if (zfail)
3654 { 3654 {
3655 extGlStencilOpSeparate(GL_BACK, GL_KEEP, incr, GL_KEEP); 3655 extGlStencilOpSeparate(GL_BACK, GL_KEEP, incr, GL_KEEP);
3656 extGlStencilOpSeparate(GL_FRONT, GL_KEEP, decr, GL_KEEP); 3656 extGlStencilOpSeparate(GL_FRONT, GL_KEEP, decr, GL_KEEP);
3657 } 3657 }
3658 else // zpass 3658 else // zpass
3659 { 3659 {
3660 extGlStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, decr); 3660 extGlStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, decr);
3661 extGlStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, incr); 3661 extGlStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, incr);
3662 } 3662 }
3663 extGlStencilFuncSeparate(GL_ALWAYS, GL_ALWAYS, 0, ~0); 3663 extGlStencilFuncSeparate(GL_ALWAYS, GL_ALWAYS, 0, ~0);
3664 glStencilMask(~0); 3664 glStencilMask(~0);
3665 glDrawArrays(GL_TRIANGLES,0,count); 3665 glDrawArrays(GL_TRIANGLES,0,count);
3666 } 3666 }
3667 else 3667 else
3668#endif 3668#endif
3669 { 3669 {
3670 glEnable(GL_CULL_FACE); 3670 glEnable(GL_CULL_FACE);
3671 if (zfail) 3671 if (zfail)
3672 { 3672 {
3673 glCullFace(GL_FRONT); 3673 glCullFace(GL_FRONT);
3674 glStencilOp(GL_KEEP, incr, GL_KEEP); 3674 glStencilOp(GL_KEEP, incr, GL_KEEP);
3675 glDrawArrays(GL_TRIANGLES,0,count); 3675 glDrawArrays(GL_TRIANGLES,0,count);
3676 3676
3677 glCullFace(GL_BACK); 3677 glCullFace(GL_BACK);
3678 glStencilOp(GL_KEEP, decr, GL_KEEP); 3678 glStencilOp(GL_KEEP, decr, GL_KEEP);
3679 glDrawArrays(GL_TRIANGLES,0,count); 3679 glDrawArrays(GL_TRIANGLES,0,count);
3680 } 3680 }
3681 else // zpass 3681 else // zpass
3682 { 3682 {
3683 glCullFace(GL_BACK); 3683 glCullFace(GL_BACK);
3684 glStencilOp(GL_KEEP, GL_KEEP, incr); 3684 glStencilOp(GL_KEEP, GL_KEEP, incr);
3685 glDrawArrays(GL_TRIANGLES,0,count); 3685 glDrawArrays(GL_TRIANGLES,0,count);
3686 3686
3687 glCullFace(GL_FRONT); 3687 glCullFace(GL_FRONT);
3688 glStencilOp(GL_KEEP, GL_KEEP, decr); 3688 glStencilOp(GL_KEEP, GL_KEEP, decr);
3689 glDrawArrays(GL_TRIANGLES,0,count); 3689 glDrawArrays(GL_TRIANGLES,0,count);
3690 } 3690 }
3691 } 3691 }
3692#ifdef GL_NV_depth_clamp 3692#ifdef GL_NV_depth_clamp
3693 if (FeatureAvailable[IRR_NV_depth_clamp]) 3693 if (FeatureAvailable[IRR_NV_depth_clamp])
3694 glDisable(GL_DEPTH_CLAMP_NV); 3694 glDisable(GL_DEPTH_CLAMP_NV);
3695#endif 3695#endif
3696 3696
3697 glDisable(GL_POLYGON_OFFSET_FILL); 3697 glDisable(GL_POLYGON_OFFSET_FILL);
3698 glDisableClientState(GL_VERTEX_ARRAY); //not stored on stack 3698 glDisableClientState(GL_VERTEX_ARRAY); //not stored on stack
3699 glPopAttrib(); 3699 glPopAttrib();
3700} 3700}
3701 3701
3702//! Fills the stencil shadow with color. After the shadow volume has been drawn 3702//! Fills the stencil shadow with color. After the shadow volume has been drawn
3703//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this 3703//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
3704//! to draw the color of the shadow. 3704//! to draw the color of the shadow.
3705void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, 3705void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
3706 video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) 3706 video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
3707{ 3707{
3708 if (!StencilBuffer) 3708 if (!StencilBuffer)
3709 return; 3709 return;
3710 3710
3711 disableTextures(); 3711 disableTextures();
3712 3712
3713 // store attributes 3713 // store attributes
3714 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT | GL_LIGHTING_BIT); 3714 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT | GL_LIGHTING_BIT);
3715 3715
3716 glDisable(GL_LIGHTING); 3716 glDisable(GL_LIGHTING);
3717 glDisable(GL_FOG); 3717 glDisable(GL_FOG);
3718 glDepthMask(GL_FALSE); 3718 glDepthMask(GL_FALSE);
3719 3719
3720 glShadeModel(GL_FLAT); 3720 glShadeModel(GL_FLAT);
3721 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3721 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3722 3722
3723 glEnable(GL_BLEND); 3723 glEnable(GL_BLEND);
3724 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 3724 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3725 3725
3726 glEnable(GL_STENCIL_TEST); 3726 glEnable(GL_STENCIL_TEST);
3727 glStencilFunc(GL_NOTEQUAL, 0, ~0); 3727 glStencilFunc(GL_NOTEQUAL, 0, ~0);
3728 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 3728 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3729 3729
3730 // draw a shadow rectangle covering the entire screen using stencil buffer 3730 // draw a shadow rectangle covering the entire screen using stencil buffer
3731 glMatrixMode(GL_MODELVIEW); 3731 glMatrixMode(GL_MODELVIEW);
3732 glPushMatrix(); 3732 glPushMatrix();
3733 glLoadIdentity(); 3733 glLoadIdentity();
3734 glMatrixMode(GL_PROJECTION); 3734 glMatrixMode(GL_PROJECTION);
3735 glPushMatrix(); 3735 glPushMatrix();
3736 glLoadIdentity(); 3736 glLoadIdentity();
3737 3737
3738 glBegin(GL_QUADS); 3738 glBegin(GL_QUADS);
3739 3739
3740 glColor4ub(leftDownEdge.getRed(), leftDownEdge.getGreen(), leftDownEdge.getBlue(), leftDownEdge.getAlpha()); 3740 glColor4ub(leftDownEdge.getRed(), leftDownEdge.getGreen(), leftDownEdge.getBlue(), leftDownEdge.getAlpha());
3741 glVertex3f(-1.f,-1.f,-0.9f); 3741 glVertex3f(-1.f,-1.f,-0.9f);
3742 3742
3743 glColor4ub(leftUpEdge.getRed(), leftUpEdge.getGreen(), leftUpEdge.getBlue(), leftUpEdge.getAlpha()); 3743 glColor4ub(leftUpEdge.getRed(), leftUpEdge.getGreen(), leftUpEdge.getBlue(), leftUpEdge.getAlpha());
3744 glVertex3f(-1.f, 1.f,-0.9f); 3744 glVertex3f(-1.f, 1.f,-0.9f);
3745 3745
3746 glColor4ub(rightUpEdge.getRed(), rightUpEdge.getGreen(), rightUpEdge.getBlue(), rightUpEdge.getAlpha()); 3746 glColor4ub(rightUpEdge.getRed(), rightUpEdge.getGreen(), rightUpEdge.getBlue(), rightUpEdge.getAlpha());
3747 glVertex3f(1.f, 1.f,-0.9f); 3747 glVertex3f(1.f, 1.f,-0.9f);
3748 3748
3749 glColor4ub(rightDownEdge.getRed(), rightDownEdge.getGreen(), rightDownEdge.getBlue(), rightDownEdge.getAlpha()); 3749 glColor4ub(rightDownEdge.getRed(), rightDownEdge.getGreen(), rightDownEdge.getBlue(), rightDownEdge.getAlpha());
3750 glVertex3f(1.f,-1.f,-0.9f); 3750 glVertex3f(1.f,-1.f,-0.9f);
3751 3751
3752 glEnd(); 3752 glEnd();
3753 3753
3754 clearBuffers(false, false, clearStencilBuffer, 0x0); 3754 clearBuffers(false, false, clearStencilBuffer, 0x0);
3755 3755
3756 // restore settings 3756 // restore settings
3757 glPopMatrix(); 3757 glPopMatrix();
3758 glMatrixMode(GL_MODELVIEW); 3758 glMatrixMode(GL_MODELVIEW);
3759 glPopMatrix(); 3759 glPopMatrix();
3760 glPopAttrib(); 3760 glPopAttrib();
3761} 3761}
3762 3762
3763 3763
3764//! Sets the fog mode. 3764//! Sets the fog mode.
3765void COpenGLDriver::setFog(SColor c, E_FOG_TYPE fogType, f32 start, 3765void COpenGLDriver::setFog(SColor c, E_FOG_TYPE fogType, f32 start,
3766 f32 end, f32 density, bool pixelFog, bool rangeFog) 3766 f32 end, f32 density, bool pixelFog, bool rangeFog)
3767{ 3767{
3768 CNullDriver::setFog(c, fogType, start, end, density, pixelFog, rangeFog); 3768 CNullDriver::setFog(c, fogType, start, end, density, pixelFog, rangeFog);
3769 3769
3770 glFogf(GL_FOG_MODE, GLfloat((fogType==EFT_FOG_LINEAR)? GL_LINEAR : (fogType==EFT_FOG_EXP)?GL_EXP:GL_EXP2)); 3770 glFogf(GL_FOG_MODE, GLfloat((fogType==EFT_FOG_LINEAR)? GL_LINEAR : (fogType==EFT_FOG_EXP)?GL_EXP:GL_EXP2));
3771 3771
3772#ifdef GL_EXT_fog_coord 3772#ifdef GL_EXT_fog_coord
3773 if (FeatureAvailable[IRR_EXT_fog_coord]) 3773 if (FeatureAvailable[IRR_EXT_fog_coord])
3774 glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH); 3774 glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
3775#endif 3775#endif
3776#ifdef GL_NV_fog_distance 3776#ifdef GL_NV_fog_distance
3777 if (FeatureAvailable[IRR_NV_fog_distance]) 3777 if (FeatureAvailable[IRR_NV_fog_distance])
3778 { 3778 {
3779 if (rangeFog) 3779 if (rangeFog)
3780 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV); 3780 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
3781 else 3781 else
3782 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV); 3782 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
3783 } 3783 }
3784#endif 3784#endif
3785 3785
3786 if (fogType==EFT_FOG_LINEAR) 3786 if (fogType==EFT_FOG_LINEAR)
3787 { 3787 {
3788 glFogf(GL_FOG_START, start); 3788 glFogf(GL_FOG_START, start);
3789 glFogf(GL_FOG_END, end); 3789 glFogf(GL_FOG_END, end);
3790 } 3790 }
3791 else 3791 else
3792 glFogf(GL_FOG_DENSITY, density); 3792 glFogf(GL_FOG_DENSITY, density);
3793 3793
3794 if (pixelFog) 3794 if (pixelFog)
3795 glHint(GL_FOG_HINT, GL_NICEST); 3795 glHint(GL_FOG_HINT, GL_NICEST);
3796 else 3796 else
3797 glHint(GL_FOG_HINT, GL_FASTEST); 3797 glHint(GL_FOG_HINT, GL_FASTEST);
3798 3798
3799 SColorf color(c); 3799 SColorf color(c);
3800 GLfloat data[4] = {color.r, color.g, color.b, color.a}; 3800 GLfloat data[4] = {color.r, color.g, color.b, color.a};
3801 glFogfv(GL_FOG_COLOR, data); 3801 glFogfv(GL_FOG_COLOR, data);
3802} 3802}
3803 3803
3804 3804
3805//! Draws a 3d line. 3805//! Draws a 3d line.
3806void COpenGLDriver::draw3DLine(const core::vector3df& start, 3806void COpenGLDriver::draw3DLine(const core::vector3df& start,
3807 const core::vector3df& end, SColor color) 3807 const core::vector3df& end, SColor color)
3808{ 3808{
3809 setRenderStates3DMode(); 3809 setRenderStates3DMode();
3810 3810
3811 glBegin(GL_LINES); 3811 glBegin(GL_LINES);
3812 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); 3812 glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
3813 glVertex3f(start.X, start.Y, start.Z); 3813 glVertex3f(start.X, start.Y, start.Z);
3814 3814
3815 glVertex3f(end.X, end.Y, end.Z); 3815 glVertex3f(end.X, end.Y, end.Z);
3816 glEnd(); 3816 glEnd();
3817} 3817}
3818 3818
3819 3819
3820//! Removes a texture from the texture cache and deletes it, freeing lot of memory. 3820//! Removes a texture from the texture cache and deletes it, freeing lot of memory.
3821void COpenGLDriver::removeTexture(ITexture* texture) 3821void COpenGLDriver::removeTexture(ITexture* texture)
3822{ 3822{
3823 if (!texture) 3823 if (!texture)
3824 return; 3824 return;
3825 3825
3826 CNullDriver::removeTexture(texture); 3826 CNullDriver::removeTexture(texture);
3827 // Remove this texture from CurrentTexture as well 3827 // Remove this texture from CurrentTexture as well
3828 CurrentTexture.remove(texture); 3828 CurrentTexture.remove(texture);
3829} 3829}
3830 3830
3831 3831
3832//! Only used by the internal engine. Used to notify the driver that 3832//! Only used by the internal engine. Used to notify the driver that
3833//! the window was resized. 3833//! the window was resized.
3834void COpenGLDriver::OnResize(const core::dimension2d<u32>& size) 3834void COpenGLDriver::OnResize(const core::dimension2d<u32>& size)
3835{ 3835{
3836 CNullDriver::OnResize(size); 3836 CNullDriver::OnResize(size);
3837 glViewport(0, 0, size.Width, size.Height); 3837 glViewport(0, 0, size.Width, size.Height);
3838 Transformation3DChanged = true; 3838 Transformation3DChanged = true;
3839} 3839}
3840 3840
3841 3841
3842//! Returns type of video driver 3842//! Returns type of video driver
3843E_DRIVER_TYPE COpenGLDriver::getDriverType() const 3843E_DRIVER_TYPE COpenGLDriver::getDriverType() const
3844{ 3844{
3845 return EDT_OPENGL; 3845 return EDT_OPENGL;
3846} 3846}
3847 3847
3848 3848
3849//! returns color format 3849//! returns color format
3850ECOLOR_FORMAT COpenGLDriver::getColorFormat() const 3850ECOLOR_FORMAT COpenGLDriver::getColorFormat() const
3851{ 3851{
3852 return ColorFormat; 3852 return ColorFormat;
3853} 3853}
3854 3854
3855 3855
3856//! Sets a vertex shader constant. 3856//! Sets a vertex shader constant.
3857void COpenGLDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) 3857void COpenGLDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
3858{ 3858{
3859#ifdef GL_ARB_vertex_program 3859#ifdef GL_ARB_vertex_program
3860 for (s32 i=0; i<constantAmount; ++i) 3860 for (s32 i=0; i<constantAmount; ++i)
3861 extGlProgramLocalParameter4fv(GL_VERTEX_PROGRAM_ARB, startRegister+i, &data[i*4]); 3861 extGlProgramLocalParameter4fv(GL_VERTEX_PROGRAM_ARB, startRegister+i, &data[i*4]);
3862#endif 3862#endif
3863} 3863}
3864 3864
3865//! Sets a pixel shader constant. 3865//! Sets a pixel shader constant.
3866void COpenGLDriver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) 3866void COpenGLDriver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
3867{ 3867{
3868#ifdef GL_ARB_fragment_program 3868#ifdef GL_ARB_fragment_program
3869 for (s32 i=0; i<constantAmount; ++i) 3869 for (s32 i=0; i<constantAmount; ++i)
3870 extGlProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM_ARB, startRegister+i, &data[i*4]); 3870 extGlProgramLocalParameter4fv(GL_FRAGMENT_PROGRAM_ARB, startRegister+i, &data[i*4]);
3871#endif 3871#endif
3872} 3872}
3873 3873
3874//! Sets a constant for the vertex shader based on a name. 3874//! Sets a constant for the vertex shader based on a name.
3875bool COpenGLDriver::setVertexShaderConstant(const c8* name, const f32* floats, int count) 3875bool COpenGLDriver::setVertexShaderConstant(const c8* name, const f32* floats, int count)
3876{ 3876{
3877 //pass this along, as in GLSL the same routine is used for both vertex and fragment shaders 3877 //pass this along, as in GLSL the same routine is used for both vertex and fragment shaders
3878 return setPixelShaderConstant(name, floats, count); 3878 return setPixelShaderConstant(name, floats, count);
3879} 3879}
3880 3880
3881//! Bool interface for the above. 3881//! Bool interface for the above.
3882bool COpenGLDriver::setVertexShaderConstant(const c8* name, const bool* bools, int count) 3882bool COpenGLDriver::setVertexShaderConstant(const c8* name, const bool* bools, int count)
3883{ 3883{
3884 return setPixelShaderConstant(name, bools, count); 3884 return setPixelShaderConstant(name, bools, count);
3885} 3885}
3886 3886
3887//! Int interface for the above. 3887//! Int interface for the above.
3888bool COpenGLDriver::setVertexShaderConstant(const c8* name, const s32* ints, int count) 3888bool COpenGLDriver::setVertexShaderConstant(const c8* name, const s32* ints, int count)
3889{ 3889{
3890 return setPixelShaderConstant(name, ints, count); 3890 return setPixelShaderConstant(name, ints, count);
3891} 3891}
3892 3892
3893//! Sets a constant for the pixel shader based on a name. 3893//! Sets a constant for the pixel shader based on a name.
3894bool COpenGLDriver::setPixelShaderConstant(const c8* name, const f32* floats, int count) 3894bool COpenGLDriver::setPixelShaderConstant(const c8* name, const f32* floats, int count)
3895{ 3895{
3896 os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); 3896 os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant().");
3897 return false; 3897 return false;
3898} 3898}
3899 3899
3900//! Bool interface for the above. 3900//! Bool interface for the above.
3901bool COpenGLDriver::setPixelShaderConstant(const c8* name, const bool* bools, int count) 3901bool COpenGLDriver::setPixelShaderConstant(const c8* name, const bool* bools, int count)
3902{ 3902{
3903 os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); 3903 os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant().");
3904 return false; 3904 return false;
3905} 3905}
3906 3906
3907//! Int interface for the above. 3907//! Int interface for the above.
3908bool COpenGLDriver::setPixelShaderConstant(const c8* name, const s32* ints, int count) 3908bool COpenGLDriver::setPixelShaderConstant(const c8* name, const s32* ints, int count)
3909{ 3909{
3910 os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); 3910 os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant().");
3911 return false; 3911 return false;
3912} 3912}
3913 3913
3914 3914
3915//! Adds a new material renderer to the VideoDriver, using pixel and/or 3915//! Adds a new material renderer to the VideoDriver, using pixel and/or
3916//! vertex shaders to render geometry. 3916//! vertex shaders to render geometry.
3917s32 COpenGLDriver::addShaderMaterial(const c8* vertexShaderProgram, 3917s32 COpenGLDriver::addShaderMaterial(const c8* vertexShaderProgram,
3918 const c8* pixelShaderProgram, 3918 const c8* pixelShaderProgram,
3919 IShaderConstantSetCallBack* callback, 3919 IShaderConstantSetCallBack* callback,
3920 E_MATERIAL_TYPE baseMaterial, s32 userData) 3920 E_MATERIAL_TYPE baseMaterial, s32 userData)
3921{ 3921{
3922 s32 nr = -1; 3922 s32 nr = -1;
3923 COpenGLShaderMaterialRenderer* r = new COpenGLShaderMaterialRenderer( 3923 COpenGLShaderMaterialRenderer* r = new COpenGLShaderMaterialRenderer(
3924 this, nr, vertexShaderProgram, pixelShaderProgram, 3924 this, nr, vertexShaderProgram, pixelShaderProgram,
3925 callback, getMaterialRenderer(baseMaterial), userData); 3925 callback, getMaterialRenderer(baseMaterial), userData);
3926 3926
3927 r->drop(); 3927 r->drop();
3928 return nr; 3928 return nr;
3929} 3929}
3930 3930
3931 3931
3932//! Adds a new material renderer to the VideoDriver, using GLSL to render geometry. 3932//! Adds a new material renderer to the VideoDriver, using GLSL to render geometry.
3933s32 COpenGLDriver::addHighLevelShaderMaterial( 3933s32 COpenGLDriver::addHighLevelShaderMaterial(
3934 const c8* vertexShaderProgram, 3934 const c8* vertexShaderProgram,
3935 const c8* vertexShaderEntryPointName, 3935 const c8* vertexShaderEntryPointName,
3936 E_VERTEX_SHADER_TYPE vsCompileTarget, 3936 E_VERTEX_SHADER_TYPE vsCompileTarget,
3937 const c8* pixelShaderProgram, 3937 const c8* pixelShaderProgram,
3938 const c8* pixelShaderEntryPointName, 3938 const c8* pixelShaderEntryPointName,
3939 E_PIXEL_SHADER_TYPE psCompileTarget, 3939 E_PIXEL_SHADER_TYPE psCompileTarget,
3940 const c8* geometryShaderProgram, 3940 const c8* geometryShaderProgram,
3941 const c8* geometryShaderEntryPointName, 3941 const c8* geometryShaderEntryPointName,
3942 E_GEOMETRY_SHADER_TYPE gsCompileTarget, 3942 E_GEOMETRY_SHADER_TYPE gsCompileTarget,
3943 scene::E_PRIMITIVE_TYPE inType, 3943 scene::E_PRIMITIVE_TYPE inType,
3944 scene::E_PRIMITIVE_TYPE outType, 3944 scene::E_PRIMITIVE_TYPE outType,
3945 u32 verticesOut, 3945 u32 verticesOut,
3946 IShaderConstantSetCallBack* callback, 3946 IShaderConstantSetCallBack* callback,
3947 E_MATERIAL_TYPE baseMaterial, 3947 E_MATERIAL_TYPE baseMaterial,
3948 s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) 3948 s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
3949{ 3949{
3950 s32 nr = -1; 3950 s32 nr = -1;
3951 3951
3952 #ifdef _IRR_COMPILE_WITH_CG_ 3952 #ifdef _IRR_COMPILE_WITH_CG_
3953 if (shadingLang == EGSL_CG) 3953 if (shadingLang == EGSL_CG)
3954 { 3954 {
3955 COpenGLCgMaterialRenderer* r = new COpenGLCgMaterialRenderer( 3955 COpenGLCgMaterialRenderer* r = new COpenGLCgMaterialRenderer(
3956 this, nr, 3956 this, nr,
3957 vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, 3957 vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
3958 pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, 3958 pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
3959 geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, 3959 geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
3960 inType, outType, verticesOut, 3960 inType, outType, verticesOut,
3961 callback,getMaterialRenderer(baseMaterial), userData); 3961 callback,getMaterialRenderer(baseMaterial), userData);
3962 3962
3963 r->drop(); 3963 r->drop();
3964 } 3964 }
3965 else 3965 else
3966 #endif 3966 #endif
3967 { 3967 {
3968 COpenGLSLMaterialRenderer* r = new COpenGLSLMaterialRenderer( 3968 COpenGLSLMaterialRenderer* r = new COpenGLSLMaterialRenderer(
3969 this, nr, 3969 this, nr,
3970 vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, 3970 vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
3971 pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, 3971 pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
3972 geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, 3972 geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
3973 inType, outType, verticesOut, 3973 inType, outType, verticesOut,
3974 callback,getMaterialRenderer(baseMaterial), userData); 3974 callback,getMaterialRenderer(baseMaterial), userData);
3975 3975
3976 r->drop(); 3976 r->drop();
3977 } 3977 }
3978 3978
3979 return nr; 3979 return nr;
3980} 3980}
3981 3981
3982 3982
3983//! Returns a pointer to the IVideoDriver interface. (Implementation for 3983//! Returns a pointer to the IVideoDriver interface. (Implementation for
3984//! IMaterialRendererServices) 3984//! IMaterialRendererServices)
3985IVideoDriver* COpenGLDriver::getVideoDriver() 3985IVideoDriver* COpenGLDriver::getVideoDriver()
3986{ 3986{
3987 return this; 3987 return this;
3988} 3988}
3989 3989
3990 3990
3991ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d<u32>& size, 3991ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
3992 const io::path& name, 3992 const io::path& name,
3993 const ECOLOR_FORMAT format) 3993 const ECOLOR_FORMAT format)
3994{ 3994{
3995 //disable mip-mapping 3995 //disable mip-mapping
3996 bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); 3996 bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
3997 setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false); 3997 setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
3998 3998
3999 video::ITexture* rtt = 0; 3999 video::ITexture* rtt = 0;
4000#if defined(GL_EXT_framebuffer_object) 4000#if defined(GL_EXT_framebuffer_object)
4001 // if driver supports FrameBufferObjects, use them 4001 // if driver supports FrameBufferObjects, use them
4002 if (queryFeature(EVDF_FRAMEBUFFER_OBJECT)) 4002 if (queryFeature(EVDF_FRAMEBUFFER_OBJECT))
4003 { 4003 {
4004 rtt = new COpenGLFBOTexture(size, name, this, format); 4004 rtt = new COpenGLFBOTexture(size, name, this, format);
4005 if (rtt) 4005 if (rtt)
4006 { 4006 {
4007 bool success = false; 4007 bool success = false;
4008 addTexture(rtt); 4008 addTexture(rtt);
4009 ITexture* tex = createDepthTexture(rtt); 4009 ITexture* tex = createDepthTexture(rtt);
4010 if (tex) 4010 if (tex)
4011 { 4011 {
4012 success = static_cast<video::COpenGLFBODepthTexture*>(tex)->attach(rtt); 4012 success = static_cast<video::COpenGLFBODepthTexture*>(tex)->attach(rtt);
4013 if ( !success ) 4013 if ( !success )
4014 { 4014 {
4015 removeDepthTexture(tex); 4015 removeDepthTexture(tex);
4016 } 4016 }
4017 tex->drop(); 4017 tex->drop();
4018 } 4018 }
4019 rtt->drop(); 4019 rtt->drop();
4020 if (!success) 4020 if (!success)
4021 { 4021 {
4022 removeTexture(rtt); 4022 removeTexture(rtt);
4023 rtt=0; 4023 rtt=0;
4024 } 4024 }
4025 } 4025 }
4026 } 4026 }
4027 else 4027 else
4028#endif 4028#endif
4029 { 4029 {
4030 // the simple texture is only possible for size <= screensize 4030 // the simple texture is only possible for size <= screensize
4031 // we try to find an optimal size with the original constraints 4031 // we try to find an optimal size with the original constraints
4032 core::dimension2du destSize(core::min_(size.Width,ScreenSize.Width), core::min_(size.Height,ScreenSize.Height)); 4032 core::dimension2du destSize(core::min_(size.Width,ScreenSize.Width), core::min_(size.Height,ScreenSize.Height));
4033 destSize = destSize.getOptimalSize((size==size.getOptimalSize()), false, false); 4033 destSize = destSize.getOptimalSize((size==size.getOptimalSize()), false, false);
4034 rtt = addTexture(destSize, name, ECF_A8R8G8B8); 4034 rtt = addTexture(destSize, name, ECF_A8R8G8B8);
4035 if (rtt) 4035 if (rtt)
4036 { 4036 {
4037 static_cast<video::COpenGLTexture*>(rtt)->setIsRenderTarget(true); 4037 static_cast<video::COpenGLTexture*>(rtt)->setIsRenderTarget(true);
4038 } 4038 }
4039 } 4039 }
4040 4040
4041 //restore mip-mapping 4041 //restore mip-mapping
4042 setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels); 4042 setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
4043 4043
4044 return rtt; 4044 return rtt;
4045} 4045}
4046 4046
4047 4047
4048//! Returns the maximum amount of primitives (mostly vertices) which 4048//! Returns the maximum amount of primitives (mostly vertices) which
4049//! the device is able to render with one drawIndexedTriangleList 4049//! the device is able to render with one drawIndexedTriangleList
4050//! call. 4050//! call.
4051u32 COpenGLDriver::getMaximalPrimitiveCount() const 4051u32 COpenGLDriver::getMaximalPrimitiveCount() const
4052{ 4052{
4053 return 0x7fffffff; 4053 return 0x7fffffff;
4054} 4054}
4055 4055
4056 4056
4057//! set or reset render target 4057//! set or reset render target
4058bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, 4058bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
4059 bool clearZBuffer, SColor color) 4059 bool clearZBuffer, SColor color)
4060{ 4060{
4061 if (target != CurrentTarget) 4061 if (target != CurrentTarget)
4062 setRenderTarget(0, false, false, 0x0); 4062 setRenderTarget(0, false, false, 0x0);
4063 4063
4064 if (ERT_RENDER_TEXTURE == target) 4064 if (ERT_RENDER_TEXTURE == target)
4065 { 4065 {
4066 os::Printer::log("For render textures call setRenderTarget with the actual texture as first parameter.", ELL_ERROR); 4066 os::Printer::log("For render textures call setRenderTarget with the actual texture as first parameter.", ELL_ERROR);
4067 return false; 4067 return false;
4068 } 4068 }
4069 if (ERT_MULTI_RENDER_TEXTURES == target) 4069 if (ERT_MULTI_RENDER_TEXTURES == target)
4070 { 4070 {
4071 os::Printer::log("For multiple render textures call setRenderTarget with the texture array as first parameter.", ELL_ERROR); 4071 os::Printer::log("For multiple render textures call setRenderTarget with the texture array as first parameter.", ELL_ERROR);
4072 return false; 4072 return false;
4073 } 4073 }
4074 4074
4075 if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target)) 4075 if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target))
4076 { 4076 {
4077 if (Params.Doublebuffer) 4077 if (Params.Doublebuffer)
4078 glDrawBuffer(GL_BACK_RIGHT); 4078 glDrawBuffer(GL_BACK_RIGHT);
4079 else 4079 else
4080 glDrawBuffer(GL_FRONT_RIGHT); 4080 glDrawBuffer(GL_FRONT_RIGHT);
4081 } 4081 }
4082 else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target) 4082 else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target)
4083 { 4083 {
4084 if (Params.Doublebuffer) 4084 if (Params.Doublebuffer)
4085 glDrawBuffer(GL_BACK); 4085 glDrawBuffer(GL_BACK);
4086 else 4086 else
4087 glDrawBuffer(GL_FRONT); 4087 glDrawBuffer(GL_FRONT);
4088 } 4088 }
4089 else if ((target >= ERT_AUX_BUFFER0) && (target-ERT_AUX_BUFFER0 < MaxAuxBuffers)) 4089 else if ((target >= ERT_AUX_BUFFER0) && (target-ERT_AUX_BUFFER0 < MaxAuxBuffers))
4090 { 4090 {
4091 glDrawBuffer(GL_AUX0+target-ERT_AUX_BUFFER0); 4091 glDrawBuffer(GL_AUX0+target-ERT_AUX_BUFFER0);
4092 } 4092 }
4093 else 4093 else
4094 { 4094 {
4095 if (Params.Doublebuffer) 4095 if (Params.Doublebuffer)
4096 glDrawBuffer(GL_BACK_LEFT); 4096 glDrawBuffer(GL_BACK_LEFT);
4097 else 4097 else
4098 glDrawBuffer(GL_FRONT_LEFT); 4098 glDrawBuffer(GL_FRONT_LEFT);
4099 // exit with false, but also with working color buffer 4099 // exit with false, but also with working color buffer
4100 if (target != ERT_FRAME_BUFFER) 4100 if (target != ERT_FRAME_BUFFER)
4101 return false; 4101 return false;
4102 } 4102 }
4103 CurrentTarget=target; 4103 CurrentTarget=target;
4104 clearBuffers(clearTarget, clearZBuffer, false, color); 4104 clearBuffers(clearTarget, clearZBuffer, false, color);
4105 return true; 4105 return true;
4106} 4106}
4107 4107
4108 4108
4109//! set or reset render target 4109//! set or reset render target
4110bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, 4110bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
4111 bool clearZBuffer, SColor color) 4111 bool clearZBuffer, SColor color)
4112{ 4112{
4113 // check for right driver type 4113 // check for right driver type
4114 4114
4115 if (texture && texture->getDriverType() != EDT_OPENGL) 4115 if (texture && texture->getDriverType() != EDT_OPENGL)
4116 { 4116 {
4117 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); 4117 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
4118 return false; 4118 return false;
4119 } 4119 }
4120 4120
4121#if defined(GL_EXT_framebuffer_object) 4121#if defined(GL_EXT_framebuffer_object)
4122 if (CurrentTarget==ERT_MULTI_RENDER_TEXTURES) 4122 if (CurrentTarget==ERT_MULTI_RENDER_TEXTURES)
4123 { 4123 {
4124 for (u32 i=0; i<MRTargets.size(); ++i) 4124 for (u32 i=0; i<MRTargets.size(); ++i)
4125 { 4125 {
4126 if (MRTargets[i].TargetType==ERT_RENDER_TEXTURE) 4126 if (MRTargets[i].TargetType==ERT_RENDER_TEXTURE)
4127 { 4127 {
4128 for (++i; i<MRTargets.size(); ++i) 4128 for (++i; i<MRTargets.size(); ++i)
4129 if (MRTargets[i].TargetType==ERT_RENDER_TEXTURE) 4129 if (MRTargets[i].TargetType==ERT_RENDER_TEXTURE)
4130 extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, 0, 0); 4130 extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, 0, 0);
4131 } 4131 }
4132 } 4132 }
4133 MRTargets.clear(); 4133 MRTargets.clear();
4134 } 4134 }
4135#endif 4135#endif
4136 4136
4137 // check if we should set the previous RT back 4137 // check if we should set the previous RT back
4138 if ((RenderTargetTexture != texture) || 4138 if ((RenderTargetTexture != texture) ||
4139 (CurrentTarget==ERT_MULTI_RENDER_TEXTURES)) 4139 (CurrentTarget==ERT_MULTI_RENDER_TEXTURES))
4140 { 4140 {
4141 setActiveTexture(0, 0); 4141 setActiveTexture(0, 0);
4142 ResetRenderStates=true; 4142 ResetRenderStates=true;
4143 if (RenderTargetTexture!=0) 4143 if (RenderTargetTexture!=0)
4144 { 4144 {
4145 RenderTargetTexture->unbindRTT(); 4145 RenderTargetTexture->unbindRTT();
4146 } 4146 }
4147 4147
4148 if (texture) 4148 if (texture)
4149 { 4149 {
4150 // we want to set a new target. so do this. 4150 // we want to set a new target. so do this.
4151 glViewport(0, 0, texture->getSize().Width, texture->getSize().Height); 4151 glViewport(0, 0, texture->getSize().Width, texture->getSize().Height);
4152 RenderTargetTexture = static_cast<COpenGLTexture*>(texture); 4152 RenderTargetTexture = static_cast<COpenGLTexture*>(texture);
4153 // calls glDrawBuffer as well 4153 // calls glDrawBuffer as well
4154 RenderTargetTexture->bindRTT(); 4154 RenderTargetTexture->bindRTT();
4155 CurrentRendertargetSize = texture->getSize(); 4155 CurrentRendertargetSize = texture->getSize();
4156 CurrentTarget=ERT_RENDER_TEXTURE; 4156 CurrentTarget=ERT_RENDER_TEXTURE;
4157 } 4157 }
4158 else 4158 else
4159 { 4159 {
4160 glViewport(0,0,ScreenSize.Width,ScreenSize.Height); 4160 glViewport(0,0,ScreenSize.Width,ScreenSize.Height);
4161 RenderTargetTexture = 0; 4161 RenderTargetTexture = 0;
4162 CurrentRendertargetSize = core::dimension2d<u32>(0,0); 4162 CurrentRendertargetSize = core::dimension2d<u32>(0,0);
4163 CurrentTarget=ERT_FRAME_BUFFER; 4163 CurrentTarget=ERT_FRAME_BUFFER;
4164 glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT); 4164 glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT);
4165 } 4165 }
4166 // we need to update the matrices due to the rendersize change. 4166 // we need to update the matrices due to the rendersize change.
4167 Transformation3DChanged=true; 4167 Transformation3DChanged=true;
4168 } 4168 }
4169 4169
4170 clearBuffers(clearBackBuffer, clearZBuffer, false, color); 4170 clearBuffers(clearBackBuffer, clearZBuffer, false, color);
4171 4171
4172 return true; 4172 return true;
4173} 4173}
4174 4174
4175 4175
4176//! Sets multiple render targets 4176//! Sets multiple render targets
4177bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& targets, 4177bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
4178 bool clearBackBuffer, bool clearZBuffer, SColor color) 4178 bool clearBackBuffer, bool clearZBuffer, SColor color)
4179{ 4179{
4180 // if simply disabling the MRT via array call 4180 // if simply disabling the MRT via array call
4181 if (targets.size()==0) 4181 if (targets.size()==0)
4182 return setRenderTarget(0, clearBackBuffer, clearZBuffer, color); 4182 return setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
4183 // if disabling old MRT, but enabling new one as well 4183 // if disabling old MRT, but enabling new one as well
4184 if ((MRTargets.size()!=0) && (targets != MRTargets)) 4184 if ((MRTargets.size()!=0) && (targets != MRTargets))
4185 setRenderTarget(0, clearBackBuffer, clearZBuffer, color); 4185 setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
4186 // if no change, simply clear buffers 4186 // if no change, simply clear buffers
4187 else if (targets == MRTargets) 4187 else if (targets == MRTargets)
4188 { 4188 {
4189 clearBuffers(clearBackBuffer, clearZBuffer, false, color); 4189 clearBuffers(clearBackBuffer, clearZBuffer, false, color);
4190 return true; 4190 return true;
4191 } 4191 }
4192 4192
4193 // copy to storage for correct disabling 4193 // copy to storage for correct disabling
4194 MRTargets=targets; 4194 MRTargets=targets;
4195 4195
4196 u32 maxMultipleRTTs = core::min_(static_cast<u32>(MaxMultipleRenderTargets), targets.size()); 4196 u32 maxMultipleRTTs = core::min_(static_cast<u32>(MaxMultipleRenderTargets), targets.size());
4197 4197
4198 // determine common size 4198 // determine common size
4199 core::dimension2du rttSize = CurrentRendertargetSize; 4199 core::dimension2du rttSize = CurrentRendertargetSize;
4200 if (targets[0].TargetType==ERT_RENDER_TEXTURE) 4200 if (targets[0].TargetType==ERT_RENDER_TEXTURE)
4201 { 4201 {
4202 if (!targets[0].RenderTexture) 4202 if (!targets[0].RenderTexture)
4203 { 4203 {
4204 os::Printer::log("Missing render texture for MRT.", ELL_ERROR); 4204 os::Printer::log("Missing render texture for MRT.", ELL_ERROR);
4205 return false; 4205 return false;
4206 } 4206 }
4207 rttSize=targets[0].RenderTexture->getSize(); 4207 rttSize=targets[0].RenderTexture->getSize();
4208 } 4208 }
4209 4209
4210 for (u32 i = 0; i < maxMultipleRTTs; ++i) 4210 for (u32 i = 0; i < maxMultipleRTTs; ++i)
4211 { 4211 {
4212 // check for right driver type 4212 // check for right driver type
4213 if (targets[i].TargetType==ERT_RENDER_TEXTURE) 4213 if (targets[i].TargetType==ERT_RENDER_TEXTURE)
4214 { 4214 {
4215 if (!targets[i].RenderTexture) 4215 if (!targets[i].RenderTexture)
4216 { 4216 {
4217 maxMultipleRTTs=i; 4217 maxMultipleRTTs=i;
4218 os::Printer::log("Missing render texture for MRT.", ELL_WARNING); 4218 os::Printer::log("Missing render texture for MRT.", ELL_WARNING);
4219 break; 4219 break;
4220 } 4220 }
4221 if (targets[i].RenderTexture->getDriverType() != EDT_OPENGL) 4221 if (targets[i].RenderTexture->getDriverType() != EDT_OPENGL)
4222 { 4222 {
4223 maxMultipleRTTs=i; 4223 maxMultipleRTTs=i;
4224 os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING); 4224 os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING);
4225 break; 4225 break;
4226 } 4226 }
4227 4227
4228 // check for valid render target 4228 // check for valid render target
4229 if (!targets[i].RenderTexture->isRenderTarget() || !static_cast<COpenGLTexture*>(targets[i].RenderTexture)->isFrameBufferObject()) 4229 if (!targets[i].RenderTexture->isRenderTarget() || !static_cast<COpenGLTexture*>(targets[i].RenderTexture)->isFrameBufferObject())
4230 { 4230 {
4231 maxMultipleRTTs=i; 4231 maxMultipleRTTs=i;
4232 os::Printer::log("Tried to set a non FBO-RTT as render target.", ELL_WARNING); 4232 os::Printer::log("Tried to set a non FBO-RTT as render target.", ELL_WARNING);
4233 break; 4233 break;
4234 } 4234 }
4235 4235
4236 // check for valid size 4236 // check for valid size
4237 if (rttSize != targets[i].RenderTexture->getSize()) 4237 if (rttSize != targets[i].RenderTexture->getSize())
4238 { 4238 {
4239 maxMultipleRTTs=i; 4239 maxMultipleRTTs=i;
4240 os::Printer::log("Render target texture has wrong size.", ELL_WARNING); 4240 os::Printer::log("Render target texture has wrong size.", ELL_WARNING);
4241 break; 4241 break;
4242 } 4242 }
4243 } 4243 }
4244 } 4244 }
4245 if (maxMultipleRTTs==0) 4245 if (maxMultipleRTTs==0)
4246 { 4246 {
4247 os::Printer::log("No valid MRTs.", ELL_ERROR); 4247 os::Printer::log("No valid MRTs.", ELL_ERROR);
4248 return false; 4248 return false;
4249 } 4249 }
4250 4250
4251 // init FBO, if any 4251 // init FBO, if any
4252 for (u32 i=0; i<maxMultipleRTTs; ++i) 4252 for (u32 i=0; i<maxMultipleRTTs; ++i)
4253 { 4253 {
4254 if (targets[i].TargetType==ERT_RENDER_TEXTURE) 4254 if (targets[i].TargetType==ERT_RENDER_TEXTURE)
4255 { 4255 {
4256 setRenderTarget(targets[i].RenderTexture, false, false, 0x0); 4256 setRenderTarget(targets[i].RenderTexture, false, false, 0x0);
4257 break; // bind only first RTT 4257 break; // bind only first RTT
4258 } 4258 }
4259 } 4259 }
4260 // init other main buffer, if necessary 4260 // init other main buffer, if necessary
4261 if (targets[0].TargetType!=ERT_RENDER_TEXTURE) 4261 if (targets[0].TargetType!=ERT_RENDER_TEXTURE)
4262 setRenderTarget(targets[0].TargetType, false, false, 0x0); 4262 setRenderTarget(targets[0].TargetType, false, false, 0x0);
4263 4263
4264 // attach other textures and store buffers into array 4264 // attach other textures and store buffers into array
4265 if (maxMultipleRTTs > 1) 4265 if (maxMultipleRTTs > 1)
4266 { 4266 {
4267 CurrentTarget=ERT_MULTI_RENDER_TEXTURES; 4267 CurrentTarget=ERT_MULTI_RENDER_TEXTURES;
4268 core::array<GLenum> MRTs; 4268 core::array<GLenum> MRTs;
4269 MRTs.set_used(maxMultipleRTTs); 4269 MRTs.set_used(maxMultipleRTTs);
4270 for(u32 i = 0; i < maxMultipleRTTs; i++) 4270 for(u32 i = 0; i < maxMultipleRTTs; i++)
4271 { 4271 {
4272 if (FeatureAvailable[IRR_EXT_draw_buffers2]) 4272 if (FeatureAvailable[IRR_EXT_draw_buffers2])
4273 { 4273 {
4274 extGlColorMaskIndexed(i, 4274 extGlColorMaskIndexed(i,
4275 (targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE, 4275 (targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
4276 (targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE, 4276 (targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
4277 (targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE, 4277 (targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
4278 (targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE); 4278 (targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
4279 if (targets[i].BlendOp==EBO_NONE) 4279 if (targets[i].BlendOp==EBO_NONE)
4280 extGlDisableIndexed(GL_BLEND, i); 4280 extGlDisableIndexed(GL_BLEND, i);
4281 else 4281 else
4282 extGlEnableIndexed(GL_BLEND, i); 4282 extGlEnableIndexed(GL_BLEND, i);
4283 } 4283 }
4284#if defined(GL_AMD_draw_buffers_blend) || defined(GL_ARB_draw_buffers_blend) 4284#if defined(GL_AMD_draw_buffers_blend) || defined(GL_ARB_draw_buffers_blend)
4285 if (FeatureAvailable[IRR_AMD_draw_buffers_blend] || FeatureAvailable[IRR_ARB_draw_buffers_blend]) 4285 if (FeatureAvailable[IRR_AMD_draw_buffers_blend] || FeatureAvailable[IRR_ARB_draw_buffers_blend])
4286 { 4286 {
4287 extGlBlendFuncIndexed(i, getGLBlend(targets[i].BlendFuncSrc), getGLBlend(targets[i].BlendFuncDst)); 4287 extGlBlendFuncIndexed(i, getGLBlend(targets[i].BlendFuncSrc), getGLBlend(targets[i].BlendFuncDst));
4288 switch(targets[i].BlendOp) 4288 switch(targets[i].BlendOp)
4289 { 4289 {
4290 case EBO_SUBTRACT: 4290 case EBO_SUBTRACT:
4291 extGlBlendEquationIndexed(i, GL_FUNC_SUBTRACT); 4291 extGlBlendEquationIndexed(i, GL_FUNC_SUBTRACT);
4292 break; 4292 break;
4293 case EBO_REVSUBTRACT: 4293 case EBO_REVSUBTRACT:
4294 extGlBlendEquationIndexed(i, GL_FUNC_REVERSE_SUBTRACT); 4294 extGlBlendEquationIndexed(i, GL_FUNC_REVERSE_SUBTRACT);
4295 break; 4295 break;
4296 case EBO_MIN: 4296 case EBO_MIN:
4297 extGlBlendEquationIndexed(i, GL_MIN); 4297 extGlBlendEquationIndexed(i, GL_MIN);
4298 break; 4298 break;
4299 case EBO_MAX: 4299 case EBO_MAX:
4300 extGlBlendEquationIndexed(i, GL_MAX); 4300 extGlBlendEquationIndexed(i, GL_MAX);
4301 break; 4301 break;
4302 case EBO_MIN_FACTOR: 4302 case EBO_MIN_FACTOR:
4303 case EBO_MIN_ALPHA: 4303 case EBO_MIN_ALPHA:
4304#if defined(GL_AMD_blend_minmax_factor) 4304#if defined(GL_AMD_blend_minmax_factor)
4305 if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) 4305 if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
4306 extGlBlendEquationIndexed(i, GL_FACTOR_MIN_AMD); 4306 extGlBlendEquationIndexed(i, GL_FACTOR_MIN_AMD);
4307 // fallback in case of missing extension 4307 // fallback in case of missing extension
4308 else 4308 else
4309#endif 4309#endif
4310 extGlBlendEquation(GL_MIN); 4310 extGlBlendEquation(GL_MIN);
4311 break; 4311 break;
4312 case EBO_MAX_FACTOR: 4312 case EBO_MAX_FACTOR:
4313 case EBO_MAX_ALPHA: 4313 case EBO_MAX_ALPHA:
4314#if defined(GL_AMD_blend_minmax_factor) 4314#if defined(GL_AMD_blend_minmax_factor)
4315 if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) 4315 if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
4316 extGlBlendEquationIndexed(i, GL_FACTOR_MAX_AMD); 4316 extGlBlendEquationIndexed(i, GL_FACTOR_MAX_AMD);
4317 // fallback in case of missing extension 4317 // fallback in case of missing extension
4318 else 4318 else
4319#endif 4319#endif
4320 extGlBlendEquation(GL_MAX); 4320 extGlBlendEquation(GL_MAX);
4321 break; 4321 break;
4322 default: 4322 default:
4323 extGlBlendEquationIndexed(i, GL_FUNC_ADD); 4323 extGlBlendEquationIndexed(i, GL_FUNC_ADD);
4324 break; 4324 break;
4325 } 4325 }
4326 } 4326 }
4327#endif 4327#endif
4328 if (targets[i].TargetType==ERT_RENDER_TEXTURE) 4328 if (targets[i].TargetType==ERT_RENDER_TEXTURE)
4329 { 4329 {
4330 GLenum attachment = GL_NONE; 4330 GLenum attachment = GL_NONE;
4331#ifdef GL_EXT_framebuffer_object 4331#ifdef GL_EXT_framebuffer_object
4332 // attach texture to FrameBuffer Object on Color [i] 4332 // attach texture to FrameBuffer Object on Color [i]
4333 attachment = GL_COLOR_ATTACHMENT0_EXT+i; 4333 attachment = GL_COLOR_ATTACHMENT0_EXT+i;
4334 if ((i != 0) && (targets[i].RenderTexture != RenderTargetTexture)) 4334 if ((i != 0) && (targets[i].RenderTexture != RenderTargetTexture))
4335 extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, static_cast<COpenGLTexture*>(targets[i].RenderTexture)->getOpenGLTextureName(), 0); 4335 extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, static_cast<COpenGLTexture*>(targets[i].RenderTexture)->getOpenGLTextureName(), 0);
4336#endif 4336#endif
4337 MRTs[i]=attachment; 4337 MRTs[i]=attachment;
4338 } 4338 }
4339 else 4339 else
4340 { 4340 {
4341 switch(targets[i].TargetType) 4341 switch(targets[i].TargetType)
4342 { 4342 {
4343 case ERT_FRAME_BUFFER: 4343 case ERT_FRAME_BUFFER:
4344 MRTs[i]=GL_BACK_LEFT; 4344 MRTs[i]=GL_BACK_LEFT;
4345 break; 4345 break;
4346 case ERT_STEREO_BOTH_BUFFERS: 4346 case ERT_STEREO_BOTH_BUFFERS:
4347 MRTs[i]=GL_BACK; 4347 MRTs[i]=GL_BACK;
4348 break; 4348 break;
4349 case ERT_STEREO_RIGHT_BUFFER: 4349 case ERT_STEREO_RIGHT_BUFFER:
4350 MRTs[i]=GL_BACK_RIGHT; 4350 MRTs[i]=GL_BACK_RIGHT;
4351 break; 4351 break;
4352 case ERT_STEREO_LEFT_BUFFER: 4352 case ERT_STEREO_LEFT_BUFFER:
4353 MRTs[i]=GL_BACK_LEFT; 4353 MRTs[i]=GL_BACK_LEFT;
4354 break; 4354 break;
4355 default: 4355 default:
4356 MRTs[i]=GL_AUX0+(targets[i].TargetType-ERT_AUX_BUFFER0); 4356 MRTs[i]=GL_AUX0+(targets[i].TargetType-ERT_AUX_BUFFER0);
4357 break; 4357 break;
4358 } 4358 }
4359 } 4359 }
4360 } 4360 }
4361 4361
4362 extGlDrawBuffers(maxMultipleRTTs, MRTs.const_pointer()); 4362 extGlDrawBuffers(maxMultipleRTTs, MRTs.const_pointer());
4363 } 4363 }
4364 4364
4365 clearBuffers(clearBackBuffer, clearZBuffer, false, color); 4365 clearBuffers(clearBackBuffer, clearZBuffer, false, color);
4366 return true; 4366 return true;
4367} 4367}
4368 4368
4369 4369
4370// returns the current size of the screen or rendertarget 4370// returns the current size of the screen or rendertarget
4371const core::dimension2d<u32>& COpenGLDriver::getCurrentRenderTargetSize() const 4371const core::dimension2d<u32>& COpenGLDriver::getCurrentRenderTargetSize() const
4372{ 4372{
4373 if (CurrentRendertargetSize.Width == 0) 4373 if (CurrentRendertargetSize.Width == 0)
4374 return ScreenSize; 4374 return ScreenSize;
4375 else 4375 else
4376 return CurrentRendertargetSize; 4376 return CurrentRendertargetSize;
4377} 4377}
4378 4378
4379 4379
4380//! Clears the ZBuffer. 4380//! Clears the ZBuffer.
4381void COpenGLDriver::clearZBuffer() 4381void COpenGLDriver::clearZBuffer()
4382{ 4382{
4383 clearBuffers(false, true, false, 0x0); 4383 clearBuffers(false, true, false, 0x0);
4384} 4384}
4385 4385
4386 4386
4387//! Returns an image created from the last rendered frame. 4387//! Returns an image created from the last rendered frame.
4388IImage* COpenGLDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) 4388IImage* COpenGLDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
4389{ 4389{
4390 if (target==video::ERT_MULTI_RENDER_TEXTURES || target==video::ERT_RENDER_TEXTURE || target==video::ERT_STEREO_BOTH_BUFFERS) 4390 if (target==video::ERT_MULTI_RENDER_TEXTURES || target==video::ERT_RENDER_TEXTURE || target==video::ERT_STEREO_BOTH_BUFFERS)
4391 return 0; 4391 return 0;
4392 4392
4393 // allows to read pixels in top-to-bottom order 4393 // allows to read pixels in top-to-bottom order
4394#ifdef GL_MESA_pack_invert 4394#ifdef GL_MESA_pack_invert
4395 if (FeatureAvailable[IRR_MESA_pack_invert]) 4395 if (FeatureAvailable[IRR_MESA_pack_invert])
4396 glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); 4396 glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
4397#endif 4397#endif
4398 4398
4399 if (format==video::ECF_UNKNOWN) 4399 if (format==video::ECF_UNKNOWN)
4400 format=getColorFormat(); 4400 format=getColorFormat();
4401 GLenum fmt; 4401 GLenum fmt;
4402 GLenum type; 4402 GLenum type;
4403 switch (format) 4403 switch (format)
4404 { 4404 {
4405 case ECF_A1R5G5B5: 4405 case ECF_A1R5G5B5:
4406 fmt = GL_BGRA; 4406 fmt = GL_BGRA;
4407 type = GL_UNSIGNED_SHORT_1_5_5_5_REV; 4407 type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
4408 break; 4408 break;
4409 case ECF_R5G6B5: 4409 case ECF_R5G6B5:
4410 fmt = GL_RGB; 4410 fmt = GL_RGB;
4411 type = GL_UNSIGNED_SHORT_5_6_5; 4411 type = GL_UNSIGNED_SHORT_5_6_5;
4412 break; 4412 break;
4413 case ECF_R8G8B8: 4413 case ECF_R8G8B8:
4414 fmt = GL_RGB; 4414 fmt = GL_RGB;
4415 type = GL_UNSIGNED_BYTE; 4415 type = GL_UNSIGNED_BYTE;
4416 break; 4416 break;
4417 case ECF_A8R8G8B8: 4417 case ECF_A8R8G8B8:
4418 fmt = GL_BGRA; 4418 fmt = GL_BGRA;
4419 if (Version > 101) 4419 if (Version > 101)
4420 type = GL_UNSIGNED_INT_8_8_8_8_REV; 4420 type = GL_UNSIGNED_INT_8_8_8_8_REV;
4421 else 4421 else
4422 type = GL_UNSIGNED_BYTE; 4422 type = GL_UNSIGNED_BYTE;
4423 break; 4423 break;
4424 case ECF_R16F: 4424 case ECF_R16F:
4425 if (FeatureAvailable[IRR_ARB_texture_rg]) 4425 if (FeatureAvailable[IRR_ARB_texture_rg])
4426 fmt = GL_RED; 4426 fmt = GL_RED;
4427 else 4427 else
4428 fmt = GL_LUMINANCE; 4428 fmt = GL_LUMINANCE;
4429#ifdef GL_ARB_half_float_pixel 4429#ifdef GL_ARB_half_float_pixel
4430 if (FeatureAvailable[IRR_ARB_half_float_pixel]) 4430 if (FeatureAvailable[IRR_ARB_half_float_pixel])
4431 type = GL_HALF_FLOAT_ARB; 4431 type = GL_HALF_FLOAT_ARB;
4432 else 4432 else
4433#endif 4433#endif
4434 { 4434 {
4435 type = GL_FLOAT; 4435 type = GL_FLOAT;
4436 format = ECF_R32F; 4436 format = ECF_R32F;
4437 } 4437 }
4438 break; 4438 break;
4439 case ECF_G16R16F: 4439 case ECF_G16R16F:
4440#ifdef GL_ARB_texture_rg 4440#ifdef GL_ARB_texture_rg
4441 if (FeatureAvailable[IRR_ARB_texture_rg]) 4441 if (FeatureAvailable[IRR_ARB_texture_rg])
4442 fmt = GL_RG; 4442 fmt = GL_RG;
4443 else 4443 else
4444#endif 4444#endif
4445 fmt = GL_LUMINANCE_ALPHA; 4445 fmt = GL_LUMINANCE_ALPHA;
4446#ifdef GL_ARB_half_float_pixel 4446#ifdef GL_ARB_half_float_pixel
4447 if (FeatureAvailable[IRR_ARB_half_float_pixel]) 4447 if (FeatureAvailable[IRR_ARB_half_float_pixel])
4448 type = GL_HALF_FLOAT_ARB; 4448 type = GL_HALF_FLOAT_ARB;
4449 else 4449 else
4450#endif 4450#endif
4451 { 4451 {
4452 type = GL_FLOAT; 4452 type = GL_FLOAT;
4453 format = ECF_G32R32F; 4453 format = ECF_G32R32F;
4454 } 4454 }
4455 break; 4455 break;
4456 case ECF_A16B16G16R16F: 4456 case ECF_A16B16G16R16F:
4457 fmt = GL_BGRA; 4457 fmt = GL_BGRA;
4458#ifdef GL_ARB_half_float_pixel 4458#ifdef GL_ARB_half_float_pixel
4459 if (FeatureAvailable[IRR_ARB_half_float_pixel]) 4459 if (FeatureAvailable[IRR_ARB_half_float_pixel])
4460 type = GL_HALF_FLOAT_ARB; 4460 type = GL_HALF_FLOAT_ARB;
4461 else 4461 else
4462#endif 4462#endif
4463 { 4463 {
4464 type = GL_FLOAT; 4464 type = GL_FLOAT;
4465 format = ECF_A32B32G32R32F; 4465 format = ECF_A32B32G32R32F;
4466 } 4466 }
4467 break; 4467 break;
4468 case ECF_R32F: 4468 case ECF_R32F:
4469 if (FeatureAvailable[IRR_ARB_texture_rg]) 4469 if (FeatureAvailable[IRR_ARB_texture_rg])
4470 fmt = GL_RED; 4470 fmt = GL_RED;
4471 else 4471 else
4472 fmt = GL_LUMINANCE; 4472 fmt = GL_LUMINANCE;
4473 type = GL_FLOAT; 4473 type = GL_FLOAT;
4474 break; 4474 break;
4475 case ECF_G32R32F: 4475 case ECF_G32R32F:
4476#ifdef GL_ARB_texture_rg 4476#ifdef GL_ARB_texture_rg
4477 if (FeatureAvailable[IRR_ARB_texture_rg]) 4477 if (FeatureAvailable[IRR_ARB_texture_rg])
4478 fmt = GL_RG; 4478 fmt = GL_RG;
4479 else 4479 else
4480#endif 4480#endif
4481 fmt = GL_LUMINANCE_ALPHA; 4481 fmt = GL_LUMINANCE_ALPHA;
4482 type = GL_FLOAT; 4482 type = GL_FLOAT;
4483 break; 4483 break;
4484 case ECF_A32B32G32R32F: 4484 case ECF_A32B32G32R32F:
4485 fmt = GL_BGRA; 4485 fmt = GL_BGRA;
4486 type = GL_FLOAT; 4486 type = GL_FLOAT;
4487 break; 4487 break;
4488 default: 4488 default:
4489 fmt = GL_BGRA; 4489 fmt = GL_BGRA;
4490 type = GL_UNSIGNED_BYTE; 4490 type = GL_UNSIGNED_BYTE;
4491 break; 4491 break;
4492 } 4492 }
4493 IImage* newImage = createImage(format, ScreenSize); 4493 IImage* newImage = createImage(format, ScreenSize);
4494 4494
4495 u8* pixels = 0; 4495 u8* pixels = 0;
4496 if (newImage) 4496 if (newImage)
4497 pixels = static_cast<u8*>(newImage->lock()); 4497 pixels = static_cast<u8*>(newImage->lock());
4498 if (pixels) 4498 if (pixels)
4499 { 4499 {
4500 GLenum tgt=GL_FRONT; 4500 GLenum tgt=GL_FRONT;
4501 switch (target) 4501 switch (target)
4502 { 4502 {
4503 case video::ERT_FRAME_BUFFER: 4503 case video::ERT_FRAME_BUFFER:
4504 break; 4504 break;
4505 case video::ERT_STEREO_LEFT_BUFFER: 4505 case video::ERT_STEREO_LEFT_BUFFER:
4506 tgt=GL_FRONT_LEFT; 4506 tgt=GL_FRONT_LEFT;
4507 break; 4507 break;
4508 case video::ERT_STEREO_RIGHT_BUFFER: 4508 case video::ERT_STEREO_RIGHT_BUFFER:
4509 tgt=GL_FRONT_RIGHT; 4509 tgt=GL_FRONT_RIGHT;
4510 break; 4510 break;
4511 default: 4511 default:
4512 tgt=GL_AUX0+(target-video::ERT_AUX_BUFFER0); 4512 tgt=GL_AUX0+(target-video::ERT_AUX_BUFFER0);
4513 break; 4513 break;
4514 } 4514 }
4515 glReadBuffer(tgt); 4515 glReadBuffer(tgt);
4516 glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, fmt, type, pixels); 4516 glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, fmt, type, pixels);
4517 testGLError(); 4517 testGLError();
4518 glReadBuffer(GL_BACK); 4518 glReadBuffer(GL_BACK);
4519 } 4519 }
4520 4520
4521#ifdef GL_MESA_pack_invert 4521#ifdef GL_MESA_pack_invert
4522 if (FeatureAvailable[IRR_MESA_pack_invert]) 4522 if (FeatureAvailable[IRR_MESA_pack_invert])
4523 glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE); 4523 glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
4524 else 4524 else
4525#endif 4525#endif
4526 if (pixels) 4526 if (pixels)
4527 { 4527 {
4528 // opengl images are horizontally flipped, so we have to fix that here. 4528 // opengl images are horizontally flipped, so we have to fix that here.
4529 const s32 pitch=newImage->getPitch(); 4529 const s32 pitch=newImage->getPitch();
4530 u8* p2 = pixels + (ScreenSize.Height - 1) * pitch; 4530 u8* p2 = pixels + (ScreenSize.Height - 1) * pitch;
4531 u8* tmpBuffer = new u8[pitch]; 4531 u8* tmpBuffer = new u8[pitch];
4532 for (u32 i=0; i < ScreenSize.Height; i += 2) 4532 for (u32 i=0; i < ScreenSize.Height; i += 2)
4533 { 4533 {
4534 memcpy(tmpBuffer, pixels, pitch); 4534 memcpy(tmpBuffer, pixels, pitch);
4535// for (u32 j=0; j<pitch; ++j) 4535// for (u32 j=0; j<pitch; ++j)
4536// { 4536// {
4537// pixels[j]=(u8)(p2[j]*255.f); 4537// pixels[j]=(u8)(p2[j]*255.f);
4538// } 4538// }
4539 memcpy(pixels, p2, pitch); 4539 memcpy(pixels, p2, pitch);
4540// for (u32 j=0; j<pitch; ++j) 4540// for (u32 j=0; j<pitch; ++j)
4541// { 4541// {
4542// p2[j]=(u8)(tmpBuffer[j]*255.f); 4542// p2[j]=(u8)(tmpBuffer[j]*255.f);
4543// } 4543// }
4544 memcpy(p2, tmpBuffer, pitch); 4544 memcpy(p2, tmpBuffer, pitch);
4545 pixels += pitch; 4545 pixels += pitch;
4546 p2 -= pitch; 4546 p2 -= pitch;
4547 } 4547 }
4548 delete [] tmpBuffer; 4548 delete [] tmpBuffer;
4549 } 4549 }
4550 4550
4551 if (newImage) 4551 if (newImage)
4552 { 4552 {
4553 newImage->unlock(); 4553 newImage->unlock();
4554 if (testGLError() || !pixels) 4554 if (testGLError() || !pixels)
4555 { 4555 {
4556 newImage->drop(); 4556 newImage->drop();
4557 return 0; 4557 return 0;
4558 } 4558 }
4559 } 4559 }
4560 return newImage; 4560 return newImage;
4561} 4561}
4562 4562
4563 4563
4564//! get depth texture for the given render target texture 4564//! get depth texture for the given render target texture
4565ITexture* COpenGLDriver::createDepthTexture(ITexture* texture, bool shared) 4565ITexture* COpenGLDriver::createDepthTexture(ITexture* texture, bool shared)
4566{ 4566{
4567 if ((texture->getDriverType() != EDT_OPENGL) || (!texture->isRenderTarget())) 4567 if ((texture->getDriverType() != EDT_OPENGL) || (!texture->isRenderTarget()))
4568 return 0; 4568 return 0;
4569 COpenGLTexture* tex = static_cast<COpenGLTexture*>(texture); 4569 COpenGLTexture* tex = static_cast<COpenGLTexture*>(texture);
4570 4570
4571 if (!tex->isFrameBufferObject()) 4571 if (!tex->isFrameBufferObject())
4572 return 0; 4572 return 0;
4573 4573
4574 if (shared) 4574 if (shared)
4575 { 4575 {
4576 for (u32 i=0; i<DepthTextures.size(); ++i) 4576 for (u32 i=0; i<DepthTextures.size(); ++i)
4577 { 4577 {
4578 if (DepthTextures[i]->getSize()==texture->getSize()) 4578 if (DepthTextures[i]->getSize()==texture->getSize())
4579 { 4579 {
4580 DepthTextures[i]->grab(); 4580 DepthTextures[i]->grab();
4581 return DepthTextures[i]; 4581 return DepthTextures[i];
4582 } 4582 }
4583 } 4583 }
4584 DepthTextures.push_back(new COpenGLFBODepthTexture(texture->getSize(), "depth1", this)); 4584 DepthTextures.push_back(new COpenGLFBODepthTexture(texture->getSize(), "depth1", this));
4585 return DepthTextures.getLast(); 4585 return DepthTextures.getLast();
4586 } 4586 }
4587 return (new COpenGLFBODepthTexture(texture->getSize(), "depth1", this)); 4587 return (new COpenGLFBODepthTexture(texture->getSize(), "depth1", this));
4588} 4588}
4589 4589
4590 4590
4591void COpenGLDriver::removeDepthTexture(ITexture* texture) 4591void COpenGLDriver::removeDepthTexture(ITexture* texture)
4592{ 4592{
4593 for (u32 i=0; i<DepthTextures.size(); ++i) 4593 for (u32 i=0; i<DepthTextures.size(); ++i)
4594 { 4594 {
4595 if (texture==DepthTextures[i]) 4595 if (texture==DepthTextures[i])
4596 { 4596 {
4597 DepthTextures.erase(i); 4597 DepthTextures.erase(i);
4598 return; 4598 return;
4599 } 4599 }
4600 } 4600 }
4601} 4601}
4602 4602
4603 4603
4604//! Set/unset a clipping plane. 4604//! Set/unset a clipping plane.
4605bool COpenGLDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) 4605bool COpenGLDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable)
4606{ 4606{
4607 if (index >= MaxUserClipPlanes) 4607 if (index >= MaxUserClipPlanes)
4608 return false; 4608 return false;
4609 4609
4610 UserClipPlanes[index].Plane=plane; 4610 UserClipPlanes[index].Plane=plane;
4611 enableClipPlane(index, enable); 4611 enableClipPlane(index, enable);
4612 return true; 4612 return true;
4613} 4613}
4614 4614
4615 4615
4616void COpenGLDriver::uploadClipPlane(u32 index) 4616void COpenGLDriver::uploadClipPlane(u32 index)
4617{ 4617{
4618 // opengl needs an array of doubles for the plane equation 4618 // opengl needs an array of doubles for the plane equation
4619 GLdouble clip_plane[4]; 4619 GLdouble clip_plane[4];
4620 clip_plane[0] = UserClipPlanes[index].Plane.Normal.X; 4620 clip_plane[0] = UserClipPlanes[index].Plane.Normal.X;
4621 clip_plane[1] = UserClipPlanes[index].Plane.Normal.Y; 4621 clip_plane[1] = UserClipPlanes[index].Plane.Normal.Y;
4622 clip_plane[2] = UserClipPlanes[index].Plane.Normal.Z; 4622 clip_plane[2] = UserClipPlanes[index].Plane.Normal.Z;
4623 clip_plane[3] = UserClipPlanes[index].Plane.D; 4623 clip_plane[3] = UserClipPlanes[index].Plane.D;
4624 glClipPlane(GL_CLIP_PLANE0 + index, clip_plane); 4624 glClipPlane(GL_CLIP_PLANE0 + index, clip_plane);
4625} 4625}
4626 4626
4627 4627
4628//! Enable/disable a clipping plane. 4628//! Enable/disable a clipping plane.
4629void COpenGLDriver::enableClipPlane(u32 index, bool enable) 4629void COpenGLDriver::enableClipPlane(u32 index, bool enable)
4630{ 4630{
4631 if (index >= MaxUserClipPlanes) 4631 if (index >= MaxUserClipPlanes)
4632 return; 4632 return;
4633 if (enable) 4633 if (enable)
4634 { 4634 {
4635 if (!UserClipPlanes[index].Enabled) 4635 if (!UserClipPlanes[index].Enabled)
4636 { 4636 {
4637 uploadClipPlane(index); 4637 uploadClipPlane(index);
4638 glEnable(GL_CLIP_PLANE0 + index); 4638 glEnable(GL_CLIP_PLANE0 + index);
4639 } 4639 }
4640 } 4640 }
4641 else 4641 else
4642 glDisable(GL_CLIP_PLANE0 + index); 4642 glDisable(GL_CLIP_PLANE0 + index);
4643 4643
4644 UserClipPlanes[index].Enabled=enable; 4644 UserClipPlanes[index].Enabled=enable;
4645} 4645}
4646 4646
4647 4647
4648core::dimension2du COpenGLDriver::getMaxTextureSize() const 4648core::dimension2du COpenGLDriver::getMaxTextureSize() const
4649{ 4649{
4650 return core::dimension2du(MaxTextureSize, MaxTextureSize); 4650 return core::dimension2du(MaxTextureSize, MaxTextureSize);
4651} 4651}
4652 4652
4653 4653
4654//! Convert E_PRIMITIVE_TYPE to OpenGL equivalent 4654//! Convert E_PRIMITIVE_TYPE to OpenGL equivalent
4655GLenum COpenGLDriver::primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const 4655GLenum COpenGLDriver::primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const
4656{ 4656{
4657 switch (type) 4657 switch (type)
4658 { 4658 {
4659 case scene::EPT_POINTS: 4659 case scene::EPT_POINTS:
4660 return GL_POINTS; 4660 return GL_POINTS;
4661 case scene::EPT_LINE_STRIP: 4661 case scene::EPT_LINE_STRIP:
4662 return GL_LINE_STRIP; 4662 return GL_LINE_STRIP;
4663 case scene::EPT_LINE_LOOP: 4663 case scene::EPT_LINE_LOOP:
4664 return GL_LINE_LOOP; 4664 return GL_LINE_LOOP;
4665 case scene::EPT_LINES: 4665 case scene::EPT_LINES:
4666 return GL_LINES; 4666 return GL_LINES;
4667 case scene::EPT_TRIANGLE_STRIP: 4667 case scene::EPT_TRIANGLE_STRIP:
4668 return GL_TRIANGLE_STRIP; 4668 return GL_TRIANGLE_STRIP;
4669 case scene::EPT_TRIANGLE_FAN: 4669 case scene::EPT_TRIANGLE_FAN:
4670 return GL_TRIANGLE_FAN; 4670 return GL_TRIANGLE_FAN;
4671 case scene::EPT_TRIANGLES: 4671 case scene::EPT_TRIANGLES:
4672 return GL_TRIANGLES; 4672 return GL_TRIANGLES;
4673 case scene::EPT_QUAD_STRIP: 4673 case scene::EPT_QUAD_STRIP:
4674 return GL_QUAD_STRIP; 4674 return GL_QUAD_STRIP;
4675 case scene::EPT_QUADS: 4675 case scene::EPT_QUADS:
4676 return GL_QUADS; 4676 return GL_QUADS;
4677 case scene::EPT_POLYGON: 4677 case scene::EPT_POLYGON:
4678 return GL_POLYGON; 4678 return GL_POLYGON;
4679 case scene::EPT_POINT_SPRITES: 4679 case scene::EPT_POINT_SPRITES:
4680#ifdef GL_ARB_point_sprite 4680#ifdef GL_ARB_point_sprite
4681 return GL_POINT_SPRITE_ARB; 4681 return GL_POINT_SPRITE_ARB;
4682#else 4682#else
4683 return GL_POINTS; 4683 return GL_POINTS;
4684#endif 4684#endif
4685 } 4685 }
4686 return GL_TRIANGLES; 4686 return GL_TRIANGLES;
4687} 4687}
4688 4688
4689 4689
4690GLenum COpenGLDriver::getGLBlend(E_BLEND_FACTOR factor) const 4690GLenum COpenGLDriver::getGLBlend(E_BLEND_FACTOR factor) const
4691{ 4691{
4692 GLenum r = 0; 4692 GLenum r = 0;
4693 switch (factor) 4693 switch (factor)
4694 { 4694 {
4695 case EBF_ZERO: r = GL_ZERO; break; 4695 case EBF_ZERO: r = GL_ZERO; break;
4696 case EBF_ONE: r = GL_ONE; break; 4696 case EBF_ONE: r = GL_ONE; break;
4697 case EBF_DST_COLOR: r = GL_DST_COLOR; break; 4697 case EBF_DST_COLOR: r = GL_DST_COLOR; break;
4698 case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break; 4698 case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break;
4699 case EBF_SRC_COLOR: r = GL_SRC_COLOR; break; 4699 case EBF_SRC_COLOR: r = GL_SRC_COLOR; break;
4700 case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break; 4700 case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break;
4701 case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break; 4701 case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break;
4702 case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break; 4702 case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break;
4703 case EBF_DST_ALPHA: r = GL_DST_ALPHA; break; 4703 case EBF_DST_ALPHA: r = GL_DST_ALPHA; break;
4704 case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break; 4704 case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break;
4705 case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break; 4705 case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break;
4706 } 4706 }
4707 return r; 4707 return r;
4708} 4708}
4709 4709
4710GLenum COpenGLDriver::getZBufferBits() const 4710GLenum COpenGLDriver::getZBufferBits() const
4711{ 4711{
4712 GLenum bits = 0; 4712 GLenum bits = 0;
4713 switch (Params.ZBufferBits) 4713 switch (Params.ZBufferBits)
4714 { 4714 {
4715 case 16: 4715 case 16:
4716 bits = GL_DEPTH_COMPONENT16; 4716 bits = GL_DEPTH_COMPONENT16;
4717 break; 4717 break;
4718 case 24: 4718 case 24:
4719 bits = GL_DEPTH_COMPONENT24; 4719 bits = GL_DEPTH_COMPONENT24;
4720 break; 4720 break;
4721 case 32: 4721 case 32:
4722 bits = GL_DEPTH_COMPONENT32; 4722 bits = GL_DEPTH_COMPONENT32;
4723 break; 4723 break;
4724 default: 4724 default:
4725 bits = GL_DEPTH_COMPONENT; 4725 bits = GL_DEPTH_COMPONENT;
4726 break; 4726 break;
4727 } 4727 }
4728 return bits; 4728 return bits;
4729} 4729}
4730 4730
4731#ifdef _IRR_COMPILE_WITH_CG_ 4731#ifdef _IRR_COMPILE_WITH_CG_
4732const CGcontext& COpenGLDriver::getCgContext() 4732const CGcontext& COpenGLDriver::getCgContext()
4733{ 4733{
4734 return CgContext; 4734 return CgContext;
4735} 4735}
4736#endif 4736#endif
4737 4737
4738 4738
4739} // end namespace 4739} // end namespace
4740} // end namespace 4740} // end namespace
4741 4741
4742#endif // _IRR_COMPILE_WITH_OPENGL_ 4742#endif // _IRR_COMPILE_WITH_OPENGL_
4743 4743
4744namespace irr 4744namespace irr
4745{ 4745{
4746namespace video 4746namespace video
4747{ 4747{
4748 4748
4749 4749
4750// ----------------------------------- 4750// -----------------------------------
4751// WINDOWS VERSION 4751// WINDOWS VERSION
4752// ----------------------------------- 4752// -----------------------------------
4753#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 4753#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
4754IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, 4754IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
4755 io::IFileSystem* io, CIrrDeviceWin32* device) 4755 io::IFileSystem* io, CIrrDeviceWin32* device)
4756{ 4756{
4757#ifdef _IRR_COMPILE_WITH_OPENGL_ 4757#ifdef _IRR_COMPILE_WITH_OPENGL_
4758 COpenGLDriver* ogl = new COpenGLDriver(params, io, device); 4758 COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
4759 if (!ogl->initDriver(device)) 4759 if (!ogl->initDriver(device))
4760 { 4760 {
4761 ogl->drop(); 4761 ogl->drop();
4762 ogl = 0; 4762 ogl = 0;
4763 } 4763 }
4764 return ogl; 4764 return ogl;
4765#else 4765#else
4766 return 0; 4766 return 0;
4767#endif // _IRR_COMPILE_WITH_OPENGL_ 4767#endif // _IRR_COMPILE_WITH_OPENGL_
4768} 4768}
4769#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ 4769#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_
4770 4770
4771// ----------------------------------- 4771// -----------------------------------
4772// MACOSX VERSION 4772// MACOSX VERSION
4773// ----------------------------------- 4773// -----------------------------------
4774#if defined(_IRR_COMPILE_WITH_OSX_DEVICE_) 4774#if defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
4775IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, 4775IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
4776 io::IFileSystem* io, CIrrDeviceMacOSX *device) 4776 io::IFileSystem* io, CIrrDeviceMacOSX *device)
4777{ 4777{
4778#ifdef _IRR_COMPILE_WITH_OPENGL_ 4778#ifdef _IRR_COMPILE_WITH_OPENGL_
4779 return new COpenGLDriver(params, io, device); 4779 return new COpenGLDriver(params, io, device);
4780#else 4780#else
4781 return 0; 4781 return 0;
4782#endif // _IRR_COMPILE_WITH_OPENGL_ 4782#endif // _IRR_COMPILE_WITH_OPENGL_
4783} 4783}
4784#endif // _IRR_COMPILE_WITH_OSX_DEVICE_ 4784#endif // _IRR_COMPILE_WITH_OSX_DEVICE_
4785 4785
4786// ----------------------------------- 4786// -----------------------------------
4787// X11 VERSION 4787// X11 VERSION
4788// ----------------------------------- 4788// -----------------------------------
4789#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ 4789#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
4790IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, 4790IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
4791 io::IFileSystem* io, CIrrDeviceLinux* device) 4791 io::IFileSystem* io, CIrrDeviceLinux* device)
4792{ 4792{
4793#ifdef _IRR_COMPILE_WITH_OPENGL_ 4793#ifdef _IRR_COMPILE_WITH_OPENGL_
4794 COpenGLDriver* ogl = new COpenGLDriver(params, io, device); 4794 COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
4795 if (!ogl->initDriver(device)) 4795 if (!ogl->initDriver(device))
4796 { 4796 {
4797 ogl->drop(); 4797 ogl->drop();
4798 ogl = 0; 4798 ogl = 0;
4799 } 4799 }
4800 return ogl; 4800 return ogl;
4801#else 4801#else
4802 return 0; 4802 return 0;
4803#endif // _IRR_COMPILE_WITH_OPENGL_ 4803#endif // _IRR_COMPILE_WITH_OPENGL_
4804} 4804}
4805#endif // _IRR_COMPILE_WITH_X11_DEVICE_ 4805#endif // _IRR_COMPILE_WITH_X11_DEVICE_
4806 4806
4807 4807
4808// ----------------------------------- 4808// -----------------------------------
4809// SDL VERSION 4809// SDL VERSION
4810// ----------------------------------- 4810// -----------------------------------
4811#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ 4811#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
4812IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, 4812IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
4813 io::IFileSystem* io, CIrrDeviceSDL* device) 4813 io::IFileSystem* io, CIrrDeviceSDL* device)
4814{ 4814{
4815#ifdef _IRR_COMPILE_WITH_OPENGL_ 4815#ifdef _IRR_COMPILE_WITH_OPENGL_
4816 return new COpenGLDriver(params, io, device); 4816 return new COpenGLDriver(params, io, device);
4817#else 4817#else
4818 return 0; 4818 return 0;
4819#endif // _IRR_COMPILE_WITH_OPENGL_ 4819#endif // _IRR_COMPILE_WITH_OPENGL_
4820} 4820}
4821#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ 4821#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
4822 4822
4823} // end namespace 4823} // end namespace
4824} // end namespace 4824} // end namespace
4825 4825
4826 4826