0025442: Visualization, TKOpenGl - prevent inclusion of system header glxext.h
[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),
8625ef7e 57 myTextFormat (GL_RGBA),
bf75be98 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;
8625ef7e 316 myTextFormat = thePixelFormat;
317#if !defined(GL_ES_VERSION_2_0)
318 const GLint anIntFormat = theTextFormat;
319#else
320 // ES does not support sized formats and format conversions - them detected from data type
321 const GLint anIntFormat = thePixelFormat;
322#endif
18f4e8e2 323 const GLsizei aWidth = theSizeX;
324 const GLsizei aHeight = theSizeY;
bf75be98 325 const GLsizei aMaxSize = theCtx->MaxTextureSize();
bf75be98 326
327 // Notice that formally general NPOT textures are required by OpenGL 2.0 specifications
328 // however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT!
68333c8f 329 // Trying to create NPOT textures on such hardware will not fail
bf75be98 330 // but driver will fall back into software rendering,
331 const bool toForceP2 = !theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW;
a174a3c5 332 const GLsizei aWidthOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aWidth, aMaxSize) : Min (aWidth, aMaxSize);
333 const GLsizei aHeightOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize) : Min (aHeight, aMaxSize);
bf75be98 334
ca3c13d1 335#if !defined(GL_ES_VERSION_2_0)
bf75be98 336 GLint aTestWidth = 0;
337 GLint aTestHeight = 0;
ca3c13d1 338#endif
18f4e8e2 339 GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL;
bf75be98 340
74706083 341 // setup the alignment
342 OpenGl_UnpackAlignmentSentry anUnpackSentry;
18f4e8e2 343 if (aDataPtr != NULL)
344 {
345 const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
346 glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
74706083 347
ca3c13d1 348 #if !defined(GL_ES_VERSION_2_0)
18f4e8e2 349 // notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
350 const GLint anExtraBytes = GLint(theImage->RowExtraBytes());
351 const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes());
352 glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
ca3c13d1 353 #endif
18f4e8e2 354 }
74706083 355
bf75be98 356 switch (theType)
357 {
358 case Graphic3d_TOT_1D:
359 {
ca3c13d1 360 #if !defined(GL_ES_VERSION_2_0)
bf75be98 361 myTarget = GL_TEXTURE_1D;
362 Bind (theCtx);
363 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
364 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
365
366 Image_PixMap aCopy;
18f4e8e2 367 if (aDataPtr != NULL)
bf75be98 368 {
18f4e8e2 369 if (aWidth != aWidthOut)
bf75be98 370 {
18f4e8e2 371 glPixelStorei (GL_PACK_ALIGNMENT, 1);
372 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
373 if (!aCopy.InitTrash (theImage->Format(), Standard_Size(aWidthOut), 1)
374 || gluScaleImage (thePixelFormat,
375 aWidth, 1, theDataType, theImage->Data(),
376 aWidthOut, 1, theDataType, aCopy.ChangeData()) != 0)
377 {
378 Unbind (theCtx);
379 Release (theCtx.operator->());
380 return false;
381 }
382
383 aDataPtr = (GLvoid* )aCopy.Data();
384 anUnpackSentry.Reset();
bf75be98 385 }
bf75be98 386 }
387
388 // use proxy to check texture could be created or not
8625ef7e 389 glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat,
bf75be98 390 aWidthOut, 0,
18f4e8e2 391 thePixelFormat, theDataType, NULL);
bf75be98 392 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
393 if (aTestWidth == 0)
394 {
395 // no memory or broken input parameters
396 Unbind (theCtx);
18f4e8e2 397 Release (theCtx.operator->());
bf75be98 398 return false;
399 }
400
8625ef7e 401 glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat,
bf75be98 402 aWidthOut, 0,
18f4e8e2 403 thePixelFormat, theDataType, aDataPtr);
a174a3c5 404 if (glGetError() != GL_NO_ERROR)
405 {
406 Unbind (theCtx);
18f4e8e2 407 Release (theCtx.operator->());
a174a3c5 408 return false;
409 }
410
411 mySizeX = aWidthOut;
412 mySizeY = 1;
bf75be98 413
414 Unbind (theCtx);
415 return true;
ca3c13d1 416 #else
417 return false;
418 #endif
bf75be98 419 }
420 case Graphic3d_TOT_2D:
421 {
422 myTarget = GL_TEXTURE_2D;
423 Bind (theCtx);
424 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
425 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
426
427 Image_PixMap aCopy;
18f4e8e2 428 if (aDataPtr != NULL)
bf75be98 429 {
18f4e8e2 430 if (aWidth != aWidthOut || aHeight != aHeightOut)
bf75be98 431 {
ca3c13d1 432 #if !defined(GL_ES_VERSION_2_0)
18f4e8e2 433 // scale texture
434 glPixelStorei (GL_PACK_ALIGNMENT, 1);
435 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
436 if (!aCopy.InitTrash (theImage->Format(), Standard_Size(aWidthOut), Standard_Size(aHeightOut))
437 || gluScaleImage (thePixelFormat,
438 aWidth, aHeight, theDataType, theImage->Data(),
439 aWidthOut, aHeightOut, theDataType, aCopy.ChangeData()) != 0)
440 {
441 Unbind (theCtx);
442 Release (theCtx.operator->());
443 return false;
444 }
445
446 aDataPtr = (GLvoid* )aCopy.Data();
447 anUnpackSentry.Reset();
ca3c13d1 448 #else
449 Unbind (theCtx);
450 Release (theCtx.operator->());
451 return false;
452 #endif
bf75be98 453 }
bf75be98 454 }
455
ca3c13d1 456 #if !defined(GL_ES_VERSION_2_0)
bf75be98 457 // use proxy to check texture could be created or not
8625ef7e 458 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
bf75be98 459 aWidthOut, aHeightOut, 0,
18f4e8e2 460 thePixelFormat, theDataType, NULL);
bf75be98 461 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
462 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
463 if (aTestWidth == 0 || aTestHeight == 0)
464 {
465 // no memory or broken input parameters
466 Unbind (theCtx);
18f4e8e2 467 Release (theCtx.operator->());
bf75be98 468 return false;
469 }
ca3c13d1 470 #endif
bf75be98 471
8625ef7e 472 glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
bf75be98 473 aWidthOut, aHeightOut, 0,
18f4e8e2 474 thePixelFormat, theDataType, aDataPtr);
a174a3c5 475 if (glGetError() != GL_NO_ERROR)
476 {
477 Unbind (theCtx);
18f4e8e2 478 Release (theCtx.operator->());
a174a3c5 479 return false;
480 }
481
482 mySizeX = aWidthOut;
483 mySizeY = aHeightOut;
bf75be98 484
485 Unbind (theCtx);
486 return true;
487 }
488 case Graphic3d_TOT_2D_MIPMAP:
489 {
490 myTarget = GL_TEXTURE_2D;
491 myHasMipmaps = Standard_True;
492 Bind (theCtx);
493 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
494 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
495
01ca42b2 496 if (theCtx->arbFBO != NULL
1a7dfdb7 497 && aWidth == aWidthOut && aHeight == aHeightOut)
498 {
ca3c13d1 499 #if !defined(GL_ES_VERSION_2_0)
1a7dfdb7 500 // use proxy to check texture could be created or not
8625ef7e 501 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
1a7dfdb7 502 aWidthOut, aHeightOut, 0,
18f4e8e2 503 thePixelFormat, theDataType, NULL);
1a7dfdb7 504 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
505 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
506 if (aTestWidth == 0 || aTestHeight == 0)
507 {
508 // no memory or broken input parameters
509 Unbind (theCtx);
18f4e8e2 510 Release (theCtx.operator->());
1a7dfdb7 511 return false;
512 }
ca3c13d1 513 #endif
1a7dfdb7 514
515 // upload main picture
8625ef7e 516 glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
1a7dfdb7 517 aWidthOut, aHeightOut, 0,
18f4e8e2 518 thePixelFormat, theDataType, theImage->Data());
a174a3c5 519 if (glGetError() != GL_NO_ERROR)
520 {
521 Unbind (theCtx);
18f4e8e2 522 Release (theCtx.operator->());
a174a3c5 523 return false;
524 }
525
526 mySizeX = aWidthOut;
527 mySizeY = aHeightOut;
1a7dfdb7 528
529 // generate mipmaps
530 //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST);
01ca42b2 531 theCtx->arbFBO->glGenerateMipmap (GL_TEXTURE_2D);
1a7dfdb7 532
533 Unbind (theCtx);
534 return true;
535 }
536 else
537 {
ca3c13d1 538 #if !defined(GL_ES_VERSION_2_0)
8625ef7e 539 bool isCreated = gluBuild2DMipmaps (GL_TEXTURE_2D, anIntFormat,
1a7dfdb7 540 aWidth, aHeight,
18f4e8e2 541 thePixelFormat, theDataType, theImage->Data()) == 0;
a174a3c5 542 if (isCreated)
543 {
544 glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &mySizeX);
545 glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &mySizeY);
546 }
547
1a7dfdb7 548 Unbind (theCtx);
549 return isCreated;
ca3c13d1 550 #else
551 Unbind (theCtx);
552 return false;
553 #endif
1a7dfdb7 554 }
bf75be98 555 }
556 default:
557 {
18f4e8e2 558 Release (theCtx.operator->());
bf75be98 559 return false;
560 }
561 }
562}
68333c8f 563
564// =======================================================================
18f4e8e2 565// function : Init
566// purpose :
567// =======================================================================
568bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
569 const Image_PixMap& theImage,
570 const Graphic3d_TypeOfTexture theType)
571{
572 if (theImage.IsEmpty())
573 {
574 Release (theCtx.operator->());
575 return false;
576 }
577
578 GLenum aPixelFormat;
579 GLenum aDataType;
580 GLint aTextFormat;
581 if (!GetDataFormat (theCtx, theImage, aTextFormat, aPixelFormat, aDataType))
582 {
583 Release (theCtx.operator->());
584 return false;
585 }
586
587 return Init (theCtx,
588 aTextFormat, aPixelFormat, aDataType,
589 (Standard_Integer)theImage.SizeX(),
590 (Standard_Integer)theImage.SizeY(),
591 theType, &theImage);
592}
593
594// =======================================================================
68333c8f 595// function : InitRectangle
596// purpose :
597// =======================================================================
598bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
599 const Standard_Integer theSizeX,
600 const Standard_Integer theSizeY,
601 const OpenGl_TextureFormat& theFormat)
602{
603 if (!Create (theCtx) || !theCtx->IsGlGreaterEqual (3, 0))
604 {
605 return false;
606 }
ca3c13d1 607
608#if !defined(GL_ES_VERSION_2_0)
68333c8f 609 myTarget = GL_TEXTURE_RECTANGLE;
610
611 const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
612 const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
ca3c13d1 613
68333c8f 614 Bind (theCtx);
615
616 if (myParams->Filter() == Graphic3d_TOTF_NEAREST)
617 {
618 glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
619 glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
620 }
621 else
622 {
623 glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
624 glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
625 }
626
8625ef7e 627 const GLint anIntFormat = theFormat.Internal();
628 myTextFormat = theFormat.Format();
68333c8f 629
630 glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE,
631 0,
8625ef7e 632 anIntFormat,
68333c8f 633 aSizeX,
634 aSizeY,
635 0,
636 theFormat.Format(),
637 GL_FLOAT,
638 NULL);
639
640 GLint aTestSizeX = 0;
641 GLint aTestSizeY = 0;
642
643 glGetTexLevelParameteriv (
644 GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
645 glGetTexLevelParameteriv (
646 GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
647
648 if (aTestSizeX == 0 || aTestSizeY == 0)
649 {
650 Unbind (theCtx);
651 return false;
652 }
653
654 glTexImage2D (myTarget,
655 0,
8625ef7e 656 anIntFormat,
68333c8f 657 aSizeX,
658 aSizeY,
659 0,
660 theFormat.Format(),
661 GL_FLOAT,
662 NULL);
663
664 if (glGetError() != GL_NO_ERROR)
665 {
666 Unbind (theCtx);
667 return false;
668 }
669
670 mySizeX = aSizeX;
671 mySizeY = aSizeY;
672
673 Unbind (theCtx);
674 return true;
ca3c13d1 675#else
676 return false;
677#endif
68333c8f 678}