0025147: Visualization, TKOpenGl - support EGL as alternative to GLX
[occt.git] / src / OpenGl / OpenGl_Texture.cxx
CommitLineData
bf75be98 1// Created by: Kirill GAVRILOV
d5f74e42 2// Copyright (c) 2013-2014 OPEN CASCADE SAS
bf75be98 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
bf75be98 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
bf75be98 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
bf75be98 14
15#include <OpenGl_Texture.hxx>
16
01ca42b2 17#include <OpenGl_ArbFBO.hxx>
bf75be98 18#include <OpenGl_Context.hxx>
01ca42b2 19#include <OpenGl_GlCore15.hxx>
bf75be98 20#include <Graphic3d_TextureParams.hxx>
21#include <Standard_Assert.hxx>
22#include <Image_PixMap.hxx>
23
24IMPLEMENT_STANDARD_HANDLE (OpenGl_Texture, OpenGl_Resource)
25IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_Resource)
26
74706083 27//! Simple class to reset unpack alignment settings
28struct OpenGl_UnpackAlignmentSentry
29{
30
31 //! Reset unpack alignment settings to safe values
32 void Reset()
33 {
34 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
ca3c13d1 35 #if !defined(GL_ES_VERSION_2_0)
74706083 36 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
ca3c13d1 37 #endif
74706083 38 }
39
40 ~OpenGl_UnpackAlignmentSentry()
41 {
42 Reset();
43 }
44
45};
46
bf75be98 47// =======================================================================
48// function : OpenGl_Texture
49// purpose :
50// =======================================================================
51OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams)
52: OpenGl_Resource(),
53 myTextureId (NO_TEXTURE),
54 myTarget (GL_TEXTURE_2D),
55 mySizeX (0),
56 mySizeY (0),
57 myTextFormat (GL_FLOAT),
58 myHasMipmaps (Standard_False),
59 myParams (theParams)
60{
61 if (myParams.IsNull())
62 {
63 myParams = new Graphic3d_TextureParams();
64 }
65}
66
67// =======================================================================
68// function : ~OpenGl_Texture
69// purpose :
70// =======================================================================
71OpenGl_Texture::~OpenGl_Texture()
72{
73 Release (NULL);
74}
75
76// =======================================================================
77// function : HasMipmaps
78// purpose :
79// =======================================================================
80const Standard_Boolean OpenGl_Texture::HasMipmaps() const
81{
82 return myHasMipmaps;
83}
84
85// =======================================================================
86// function : GetParams
87// purpose :
88// =======================================================================
89const Handle(Graphic3d_TextureParams)& OpenGl_Texture::GetParams() const
90{
91 return myParams;
92}
93
94// =======================================================================
95// function : SetParams
96// purpose :
97// =======================================================================
98void OpenGl_Texture::SetParams (const Handle(Graphic3d_TextureParams)& theParams)
99{
100 myParams = theParams;
101}
102
103// =======================================================================
104// function : Create
105// purpose :
106// =======================================================================
107bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& )
108{
109 if (myTextureId == NO_TEXTURE)
110 {
111 glGenTextures (1, &myTextureId);
112 }
113 return myTextureId != NO_TEXTURE;
114}
115
116// =======================================================================
117// function : Release
118// purpose :
119// =======================================================================
10b9c7df 120void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
bf75be98 121{
122 if (myTextureId == NO_TEXTURE)
123 {
124 return;
125 }
126
127 // application can not handle this case by exception - this is bug in code
128 Standard_ASSERT_RETURN (theGlCtx != NULL,
129 "OpenGl_Texture destroyed without GL context! Possible GPU memory leakage...",);
130
ec2eeb2d 131 if (theGlCtx->IsValid())
132 {
133 glDeleteTextures (1, &myTextureId);
134 }
bf75be98 135 myTextureId = NO_TEXTURE;
136 mySizeX = mySizeY = 0;
137}
138
139// =======================================================================
140// function : Bind
141// purpose :
142// =======================================================================
143void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
144 const GLenum theTextureUnit) const
145{
01ca42b2 146 if (theCtx->IsGlGreaterEqual (1, 5))
bf75be98 147 {
01ca42b2 148 theCtx->core15fwd->glActiveTexture (theTextureUnit);
bf75be98 149 }
150 glBindTexture (myTarget, myTextureId);
151}
152
153// =======================================================================
154// function : Unbind
155// purpose :
156// =======================================================================
157void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
158 const GLenum theTextureUnit) const
159{
01ca42b2 160 if (theCtx->IsGlGreaterEqual (1, 5))
bf75be98 161 {
01ca42b2 162 theCtx->core15fwd->glActiveTexture (theTextureUnit);
bf75be98 163 }
164 glBindTexture (myTarget, NO_TEXTURE);
165}
166
18f4e8e2 167//=======================================================================
168//function : GetDataFormat
169//purpose :
170//=======================================================================
171bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
172 const Image_PixMap& theData,
173 GLint& theTextFormat,
174 GLenum& thePixelFormat,
175 GLenum& theDataType)
bf75be98 176{
18f4e8e2 177 theTextFormat = GL_RGBA8;
178 thePixelFormat = 0;
179 theDataType = 0;
180 switch (theData.Format())
bf75be98 181 {
182 case Image_PixMap::ImgGrayF:
183 {
18f4e8e2 184 theTextFormat = GL_ALPHA8; // GL_R8, GL_R32F
185 thePixelFormat = GL_ALPHA; // GL_RED
186 theDataType = GL_FLOAT;
187 return true;
bf75be98 188 }
189 case Image_PixMap::ImgRGBAF:
190 {
18f4e8e2 191 theTextFormat = GL_RGBA8; // GL_RGBA32F
192 thePixelFormat = GL_RGBA;
193 theDataType = GL_FLOAT;
194 return true;
bf75be98 195 }
196 case Image_PixMap::ImgBGRAF:
197 {
198 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
199 {
200 return false;
201 }
ca3c13d1 202 theTextFormat = GL_RGBA8; // GL_RGBA32F
203 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
18f4e8e2 204 theDataType = GL_FLOAT;
205 return true;
bf75be98 206 }
207 case Image_PixMap::ImgRGBF:
208 {
18f4e8e2 209 theTextFormat = GL_RGB8; // GL_RGB32F
210 thePixelFormat = GL_RGB;
211 theDataType = GL_FLOAT;
212 return true;
bf75be98 213 }
214 case Image_PixMap::ImgBGRF:
215 {
ca3c13d1 216 #if !defined(GL_ES_VERSION_2_0)
217 theTextFormat = GL_RGB8; // GL_RGB32F
18f4e8e2 218 thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
219 theDataType = GL_FLOAT;
220 return true;
ca3c13d1 221 #else
222 return false;
223 #endif
bf75be98 224 }
225 case Image_PixMap::ImgRGBA:
226 {
18f4e8e2 227 theTextFormat = GL_RGBA8;
228 thePixelFormat = GL_RGBA;
229 theDataType = GL_UNSIGNED_BYTE;
230 return true;
bf75be98 231 }
232 case Image_PixMap::ImgBGRA:
233 {
234 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
235 {
236 return false;
237 }
ca3c13d1 238 theTextFormat = GL_RGBA8;
239 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
18f4e8e2 240 theDataType = GL_UNSIGNED_BYTE;
241 return true;
bf75be98 242 }
243 case Image_PixMap::ImgRGB32:
244 {
18f4e8e2 245 theTextFormat = GL_RGB8;
246 thePixelFormat = GL_RGBA;
247 theDataType = GL_UNSIGNED_BYTE;
248 return true;
bf75be98 249 }
250 case Image_PixMap::ImgBGR32:
251 {
252 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
253 {
254 return false;
255 }
ca3c13d1 256 theTextFormat = GL_RGB8;
257 thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
18f4e8e2 258 theDataType = GL_UNSIGNED_BYTE;
259 return true;
bf75be98 260 }
261 case Image_PixMap::ImgRGB:
262 {
18f4e8e2 263 theTextFormat = GL_RGB8;
264 thePixelFormat = GL_RGB;
265 theDataType = GL_UNSIGNED_BYTE;
266 return true;
bf75be98 267 }
268 case Image_PixMap::ImgBGR:
269 {
ca3c13d1 270 #if !defined(GL_ES_VERSION_2_0)
bf75be98 271 if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
272 {
273 return false;
274 }
18f4e8e2 275 theTextFormat = GL_RGB8;
276 thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
277 theDataType = GL_UNSIGNED_BYTE;
278 return true;
ca3c13d1 279 #else
280 return false;
281 #endif
bf75be98 282 }
283 case Image_PixMap::ImgGray:
284 {
18f4e8e2 285 theTextFormat = GL_ALPHA8; // GL_R8
286 thePixelFormat = GL_ALPHA; // GL_RED
287 theDataType = GL_UNSIGNED_BYTE;
288 return true;
bf75be98 289 }
290 default:
291 {
292 return false;
293 }
294 }
18f4e8e2 295}
bf75be98 296
18f4e8e2 297// =======================================================================
298// function : Init
299// purpose :
300// =======================================================================
301bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
302 const Standard_Integer theTextFormat,
303 const GLenum thePixelFormat,
304 const GLenum theDataType,
305 const Standard_Integer theSizeX,
306 const Standard_Integer theSizeY,
307 const Graphic3d_TypeOfTexture theType,
308 const Image_PixMap* theImage)
309{
310 if (!Create (theCtx))
311 {
312 Release (theCtx.operator->());
313 return false;
314 }
315 myHasMipmaps = Standard_False;
316 myTextFormat = theTextFormat;
317 const GLsizei aWidth = theSizeX;
318 const GLsizei aHeight = theSizeY;
bf75be98 319 const GLsizei aMaxSize = theCtx->MaxTextureSize();
bf75be98 320
321 // Notice that formally general NPOT textures are required by OpenGL 2.0 specifications
322 // however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT!
68333c8f 323 // Trying to create NPOT textures on such hardware will not fail
bf75be98 324 // but driver will fall back into software rendering,
325 const bool toForceP2 = !theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW;
a174a3c5 326 const GLsizei aWidthOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aWidth, aMaxSize) : Min (aWidth, aMaxSize);
327 const GLsizei aHeightOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize) : Min (aHeight, aMaxSize);
bf75be98 328
ca3c13d1 329#if !defined(GL_ES_VERSION_2_0)
bf75be98 330 GLint aTestWidth = 0;
331 GLint aTestHeight = 0;
ca3c13d1 332#endif
18f4e8e2 333 GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL;
bf75be98 334
74706083 335 // setup the alignment
336 OpenGl_UnpackAlignmentSentry anUnpackSentry;
18f4e8e2 337 if (aDataPtr != NULL)
338 {
339 const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
340 glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
74706083 341
ca3c13d1 342 #if !defined(GL_ES_VERSION_2_0)
18f4e8e2 343 // notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
344 const GLint anExtraBytes = GLint(theImage->RowExtraBytes());
345 const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes());
346 glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
ca3c13d1 347 #endif
18f4e8e2 348 }
74706083 349
bf75be98 350 switch (theType)
351 {
352 case Graphic3d_TOT_1D:
353 {
ca3c13d1 354 #if !defined(GL_ES_VERSION_2_0)
bf75be98 355 myTarget = GL_TEXTURE_1D;
356 Bind (theCtx);
357 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
358 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
359
360 Image_PixMap aCopy;
18f4e8e2 361 if (aDataPtr != NULL)
bf75be98 362 {
18f4e8e2 363 if (aWidth != aWidthOut)
bf75be98 364 {
18f4e8e2 365 glPixelStorei (GL_PACK_ALIGNMENT, 1);
366 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
367 if (!aCopy.InitTrash (theImage->Format(), Standard_Size(aWidthOut), 1)
368 || gluScaleImage (thePixelFormat,
369 aWidth, 1, theDataType, theImage->Data(),
370 aWidthOut, 1, theDataType, aCopy.ChangeData()) != 0)
371 {
372 Unbind (theCtx);
373 Release (theCtx.operator->());
374 return false;
375 }
376
377 aDataPtr = (GLvoid* )aCopy.Data();
378 anUnpackSentry.Reset();
bf75be98 379 }
bf75be98 380 }
381
382 // use proxy to check texture could be created or not
a577aaab 383 glTexImage1D (GL_PROXY_TEXTURE_1D, 0, myTextFormat,
bf75be98 384 aWidthOut, 0,
18f4e8e2 385 thePixelFormat, theDataType, NULL);
bf75be98 386 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
387 if (aTestWidth == 0)
388 {
389 // no memory or broken input parameters
390 Unbind (theCtx);
18f4e8e2 391 Release (theCtx.operator->());
bf75be98 392 return false;
393 }
394
a577aaab 395 glTexImage1D (GL_TEXTURE_1D, 0, myTextFormat,
bf75be98 396 aWidthOut, 0,
18f4e8e2 397 thePixelFormat, theDataType, aDataPtr);
a174a3c5 398 if (glGetError() != GL_NO_ERROR)
399 {
400 Unbind (theCtx);
18f4e8e2 401 Release (theCtx.operator->());
a174a3c5 402 return false;
403 }
404
405 mySizeX = aWidthOut;
406 mySizeY = 1;
bf75be98 407
408 Unbind (theCtx);
409 return true;
ca3c13d1 410 #else
411 return false;
412 #endif
bf75be98 413 }
414 case Graphic3d_TOT_2D:
415 {
416 myTarget = GL_TEXTURE_2D;
417 Bind (theCtx);
418 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
419 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
420
421 Image_PixMap aCopy;
18f4e8e2 422 if (aDataPtr != NULL)
bf75be98 423 {
18f4e8e2 424 if (aWidth != aWidthOut || aHeight != aHeightOut)
bf75be98 425 {
ca3c13d1 426 #if !defined(GL_ES_VERSION_2_0)
18f4e8e2 427 // scale texture
428 glPixelStorei (GL_PACK_ALIGNMENT, 1);
429 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
430 if (!aCopy.InitTrash (theImage->Format(), Standard_Size(aWidthOut), Standard_Size(aHeightOut))
431 || gluScaleImage (thePixelFormat,
432 aWidth, aHeight, theDataType, theImage->Data(),
433 aWidthOut, aHeightOut, theDataType, aCopy.ChangeData()) != 0)
434 {
435 Unbind (theCtx);
436 Release (theCtx.operator->());
437 return false;
438 }
439
440 aDataPtr = (GLvoid* )aCopy.Data();
441 anUnpackSentry.Reset();
ca3c13d1 442 #else
443 Unbind (theCtx);
444 Release (theCtx.operator->());
445 return false;
446 #endif
bf75be98 447 }
bf75be98 448 }
449
ca3c13d1 450 #if !defined(GL_ES_VERSION_2_0)
bf75be98 451 // use proxy to check texture could be created or not
a577aaab 452 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, myTextFormat,
bf75be98 453 aWidthOut, aHeightOut, 0,
18f4e8e2 454 thePixelFormat, theDataType, NULL);
bf75be98 455 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
456 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
457 if (aTestWidth == 0 || aTestHeight == 0)
458 {
459 // no memory or broken input parameters
460 Unbind (theCtx);
18f4e8e2 461 Release (theCtx.operator->());
bf75be98 462 return false;
463 }
ca3c13d1 464 #endif
bf75be98 465
a577aaab 466 glTexImage2D (GL_TEXTURE_2D, 0, myTextFormat,
bf75be98 467 aWidthOut, aHeightOut, 0,
18f4e8e2 468 thePixelFormat, theDataType, aDataPtr);
a174a3c5 469 if (glGetError() != GL_NO_ERROR)
470 {
471 Unbind (theCtx);
18f4e8e2 472 Release (theCtx.operator->());
a174a3c5 473 return false;
474 }
475
476 mySizeX = aWidthOut;
477 mySizeY = aHeightOut;
bf75be98 478
479 Unbind (theCtx);
480 return true;
481 }
482 case Graphic3d_TOT_2D_MIPMAP:
483 {
484 myTarget = GL_TEXTURE_2D;
485 myHasMipmaps = Standard_True;
486 Bind (theCtx);
487 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
488 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
489
01ca42b2 490 if (theCtx->arbFBO != NULL
1a7dfdb7 491 && aWidth == aWidthOut && aHeight == aHeightOut)
492 {
ca3c13d1 493 #if !defined(GL_ES_VERSION_2_0)
1a7dfdb7 494 // use proxy to check texture could be created or not
a577aaab 495 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, myTextFormat,
1a7dfdb7 496 aWidthOut, aHeightOut, 0,
18f4e8e2 497 thePixelFormat, theDataType, NULL);
1a7dfdb7 498 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
499 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
500 if (aTestWidth == 0 || aTestHeight == 0)
501 {
502 // no memory or broken input parameters
503 Unbind (theCtx);
18f4e8e2 504 Release (theCtx.operator->());
1a7dfdb7 505 return false;
506 }
ca3c13d1 507 #endif
1a7dfdb7 508
509 // upload main picture
a577aaab 510 glTexImage2D (GL_TEXTURE_2D, 0, myTextFormat,
1a7dfdb7 511 aWidthOut, aHeightOut, 0,
18f4e8e2 512 thePixelFormat, theDataType, theImage->Data());
a174a3c5 513 if (glGetError() != GL_NO_ERROR)
514 {
515 Unbind (theCtx);
18f4e8e2 516 Release (theCtx.operator->());
a174a3c5 517 return false;
518 }
519
520 mySizeX = aWidthOut;
521 mySizeY = aHeightOut;
1a7dfdb7 522
523 // generate mipmaps
524 //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST);
01ca42b2 525 theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D);
1a7dfdb7 526
527 Unbind (theCtx);
528 return true;
529 }
530 else
531 {
ca3c13d1 532 #if !defined(GL_ES_VERSION_2_0)
a577aaab 533 bool isCreated = gluBuild2DMipmaps (GL_TEXTURE_2D, myTextFormat,
1a7dfdb7 534 aWidth, aHeight,
18f4e8e2 535 thePixelFormat, theDataType, theImage->Data()) == 0;
a174a3c5 536 if (isCreated)
537 {
538 glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &mySizeX);
539 glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &mySizeY);
540 }
541
1a7dfdb7 542 Unbind (theCtx);
543 return isCreated;
ca3c13d1 544 #else
545 Unbind (theCtx);
546 return false;
547 #endif
1a7dfdb7 548 }
bf75be98 549 }
550 default:
551 {
18f4e8e2 552 Release (theCtx.operator->());
bf75be98 553 return false;
554 }
555 }
556}
68333c8f 557
558// =======================================================================
18f4e8e2 559// function : Init
560// purpose :
561// =======================================================================
562bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
563 const Image_PixMap& theImage,
564 const Graphic3d_TypeOfTexture theType)
565{
566 if (theImage.IsEmpty())
567 {
568 Release (theCtx.operator->());
569 return false;
570 }
571
572 GLenum aPixelFormat;
573 GLenum aDataType;
574 GLint aTextFormat;
575 if (!GetDataFormat (theCtx, theImage, aTextFormat, aPixelFormat, aDataType))
576 {
577 Release (theCtx.operator->());
578 return false;
579 }
580
581 return Init (theCtx,
582 aTextFormat, aPixelFormat, aDataType,
583 (Standard_Integer)theImage.SizeX(),
584 (Standard_Integer)theImage.SizeY(),
585 theType, &theImage);
586}
587
588// =======================================================================
68333c8f 589// function : InitRectangle
590// purpose :
591// =======================================================================
592bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
593 const Standard_Integer theSizeX,
594 const Standard_Integer theSizeY,
595 const OpenGl_TextureFormat& theFormat)
596{
597 if (!Create (theCtx) || !theCtx->IsGlGreaterEqual (3, 0))
598 {
599 return false;
600 }
ca3c13d1 601
602#if !defined(GL_ES_VERSION_2_0)
68333c8f 603 myTarget = GL_TEXTURE_RECTANGLE;
604
605 const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
606 const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
ca3c13d1 607
68333c8f 608 Bind (theCtx);
609
610 if (myParams->Filter() == Graphic3d_TOTF_NEAREST)
611 {
612 glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
613 glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
614 }
615 else
616 {
617 glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
618 glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
619 }
620
621 myTextFormat = theFormat.Internal();
622
623 glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE,
624 0,
625 myTextFormat,
626 aSizeX,
627 aSizeY,
628 0,
629 theFormat.Format(),
630 GL_FLOAT,
631 NULL);
632
633 GLint aTestSizeX = 0;
634 GLint aTestSizeY = 0;
635
636 glGetTexLevelParameteriv (
637 GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
638 glGetTexLevelParameteriv (
639 GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
640
641 if (aTestSizeX == 0 || aTestSizeY == 0)
642 {
643 Unbind (theCtx);
644 return false;
645 }
646
647 glTexImage2D (myTarget,
648 0,
649 myTextFormat,
650 aSizeX,
651 aSizeY,
652 0,
653 theFormat.Format(),
654 GL_FLOAT,
655 NULL);
656
657 if (glGetError() != GL_NO_ERROR)
658 {
659 Unbind (theCtx);
660 return false;
661 }
662
663 mySizeX = aSizeX;
664 mySizeY = aSizeY;
665
666 Unbind (theCtx);
667 return true;
ca3c13d1 668#else
669 return false;
670#endif
68333c8f 671}