1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0024894: TKOpenGl - refactor OpenGl_FrameBuffer and OpenGl_Texture classes.

This commit is contained in:
osa 2014-05-05 16:10:00 +04:00 committed by bugmaster
parent eb1ebea490
commit 18f4e8e28d
5 changed files with 245 additions and 322 deletions

View File

@ -33,7 +33,7 @@ static inline GLsizei getEvenNumber (const GLsizei theNumber)
//! Notice - 0 is not power of two here
static inline bool isPowerOfTwo (const GLsizei theNumber)
{
return !(theNumber & (theNumber - 1));
return !(theNumber & (theNumber - 1));
}
// =======================================================================
@ -41,15 +41,12 @@ static inline bool isPowerOfTwo (const GLsizei theNumber)
// purpose :
// =======================================================================
OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
: mySizeX (0),
mySizeY (0),
myVPSizeX (0),
: myVPSizeX (0),
myVPSizeY (0),
myTextFormat (theTextureFormat),
myGlTextureId (NO_TEXTURE),
myGlFBufferId (NO_FRAMEBUFFER),
myGlDepthRBId (NO_RENDERBUFFER),
myGlStencilRBId (NO_RENDERBUFFER)
myColorTexture (new OpenGl_Texture()),
myDepthStencilTexture (new OpenGl_Texture())
{
//
}
@ -69,8 +66,7 @@ OpenGl_FrameBuffer::~OpenGl_FrameBuffer()
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
const GLsizei theViewportSizeX,
const GLsizei theViewportSizeY,
const GLboolean toForcePowerOfTwo)
const GLsizei theViewportSizeY)
{
if (theGlContext->arbFBO == NULL)
{
@ -80,75 +76,31 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
// clean up previous state
Release (theGlContext.operator->());
// upscale width/height if numbers are odd
if (toForcePowerOfTwo)
{
mySizeX = OpenGl_Context::GetPowerOfTwo (theViewportSizeX, theGlContext->MaxTextureSize());
mySizeY = OpenGl_Context::GetPowerOfTwo (theViewportSizeY, theGlContext->MaxTextureSize());
}
else
{
mySizeX = getEvenNumber (theViewportSizeX);
mySizeY = getEvenNumber (theViewportSizeY);
}
// setup viewport sizes as is
myVPSizeX = theViewportSizeX;
myVPSizeY = theViewportSizeY;
// Create the texture (will be used as color buffer)
if (!initTrashTexture (theGlContext))
// Create the textures (will be used as color buffer and depth-stencil buffer)
if (!initTrashTextures (theGlContext))
{
if (!isPowerOfTwo (mySizeX) || !isPowerOfTwo (mySizeY))
{
return Init (theGlContext, theViewportSizeX, theViewportSizeY, GL_TRUE);
}
Release (theGlContext.operator->());
return Standard_False;
}
if (!theGlContext->extPDS)
{
// Create RenderBuffer to be used as depth buffer
theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBId);
theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBId);
theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mySizeX, mySizeY);
// Create RenderBuffer to be used as stencil buffer
theGlContext->arbFBO->glGenRenderbuffers (1, &myGlStencilRBId);
theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlStencilRBId);
theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX, mySizeX, mySizeY);
}
else
{
// Create combined depth stencil buffer
theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBId);
theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBId);
theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mySizeX, mySizeY);
myGlStencilRBId = myGlDepthRBId;
}
// Build FBO and setup it as texture
theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, myGlTextureId);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, myGlTextureId, 0);
theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, myGlDepthRBId);
theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, myGlStencilRBId);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
if (!isPowerOfTwo (mySizeX) || !isPowerOfTwo (mySizeY))
{
return Init (theGlContext, theViewportSizeX, theViewportSizeY, GL_TRUE);
}
Release (theGlContext.operator->());
return Standard_False;
}
UnbindBuffer (theGlContext);
UnbindTexture (theGlContext);
theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
UnbindBuffer (theGlContext);
return Standard_True;
}
@ -158,107 +110,34 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
// =======================================================================
void OpenGl_FrameBuffer::Release (const OpenGl_Context* theGlCtx)
{
if (isValidDepthBuffer()
|| isValidStencilBuffer()
|| isValidTexture()
|| isValidFrameBuffer())
if (isValidFrameBuffer())
{
// application can not handle this case by exception - this is bug in code
Standard_ASSERT_RETURN (theGlCtx != NULL,
"OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",);
}
if (isValidStencilBuffer())
{
if (theGlCtx->IsValid()
&& myGlStencilRBId != myGlDepthRBId)
{
theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlStencilRBId);
}
myGlStencilRBId = NO_RENDERBUFFER;
}
if (isValidDepthBuffer())
{
if (theGlCtx->IsValid())
{
theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlDepthRBId);
}
myGlDepthRBId = NO_RENDERBUFFER;
}
if (isValidTexture())
{
if (theGlCtx->IsValid())
{
glDeleteTextures (1, &myGlTextureId);
}
myGlTextureId = NO_TEXTURE;
}
mySizeX = mySizeY = myVPSizeX = myVPSizeY = 0;
if (isValidFrameBuffer())
{
if (theGlCtx->IsValid())
{
theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
}
myGlFBufferId = NO_FRAMEBUFFER;
}
}
// =======================================================================
// function : isProxySuccess
// purpose :
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::isProxySuccess() const
{
// use proxy to check texture could be created or not
glTexImage2D (GL_PROXY_TEXTURE_2D,
0, // LOD number: 0 - base image level; n is the nth mipmap reduction image
myTextFormat, // internalformat
mySizeX, mySizeY, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
GLint aTestParamX (0), aTestParamY (0);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestParamX);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestParamY);
return aTestParamX != 0 && aTestParamY != 0;
myColorTexture->Release (theGlCtx);
myDepthStencilTexture->Release (theGlCtx);
}
// =======================================================================
// function : initTrashTexture
// purpose :
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::initTrashTexture (const Handle(OpenGl_Context)& theGlContext)
Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext)
{
// Check texture size is fit dimension maximum
GLint aMaxTexDim = 2048;
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aMaxTexDim);
if (mySizeX > aMaxTexDim || mySizeY > aMaxTexDim)
{
return Standard_False;
}
// generate new id
glEnable (GL_TEXTURE_2D);
if (!isValidTexture())
{
glGenTextures (1, &myGlTextureId); // Create The Texture
}
glBindTexture (GL_TEXTURE_2D, myGlTextureId);
// texture interpolation parameters - could be overridden later
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (!isProxySuccess())
{
Release (theGlContext.operator->());
return Standard_False;
}
glTexImage2D (GL_TEXTURE_2D,
0, // LOD number: 0 - base image level; n is the nth mipmap reduction image
myTextFormat, // internalformat
mySizeX, mySizeY, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL); // NULL pointer supported from OpenGL 1.1
return Standard_True;
return myColorTexture->Init (theGlContext, myTextFormat,
GL_RGBA, GL_UNSIGNED_BYTE,
myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)
&& myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
myVPSizeX, myVPSizeY, Graphic3d_TOT_2D);
}
// =======================================================================
@ -298,23 +177,3 @@ void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
{
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);
}
// =======================================================================
// function : BindTexture
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::BindTexture (const Handle(OpenGl_Context)& /*theGlCtx*/)
{
glEnable (GL_TEXTURE_2D); // needed only for fixed pipeline rendering
glBindTexture (GL_TEXTURE_2D, myGlTextureId);
}
// =======================================================================
// function : UnbindTexture
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::UnbindTexture (const Handle(OpenGl_Context)& /*theGlCtx*/)
{
glBindTexture (GL_TEXTURE_2D, NO_TEXTURE);
glDisable (GL_TEXTURE_2D); // needed only for fixed pipeline rendering
}

View File

@ -17,6 +17,7 @@
#include <OpenGl_Context.hxx>
#include <OpenGl_Resource.hxx>
#include <OpenGl_Texture.hxx>
#include <Standard_Boolean.hxx>
#include <InterfaceGraphic.hxx>
@ -29,9 +30,7 @@ class OpenGl_FrameBuffer : public OpenGl_Resource
public:
//! Helpful constants
static const GLuint NO_TEXTURE = 0;
static const GLuint NO_FRAMEBUFFER = 0;
static const GLuint NO_RENDERBUFFER = 0;
public:
@ -44,16 +43,16 @@ public:
//! Destroy object - will release GPU memory if any.
Standard_EXPORT virtual void Release (const OpenGl_Context* theGlCtx);
//! Texture width.
//! Textures width.
GLsizei GetSizeX() const
{
return mySizeX;
return myColorTexture->SizeX();
}
//! Texture height.
//! Textures height.
GLsizei GetSizeY() const
{
return mySizeY;
return myColorTexture->SizeY();
}
//! Viewport width.
@ -71,7 +70,7 @@ public:
//! Returns true if current object was initialized
Standard_Boolean IsValid() const
{
return isValidFrameBuffer() && isValidTexture() && isValidDepthBuffer() && isValidStencilBuffer();
return isValidFrameBuffer();
}
//! Notice! Obsolete hardware (GeForce FX etc)
@ -84,8 +83,7 @@ public:
//! 3) FBO rendering will be incorrect (some obsolete Catalyst drivers).
Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theViewportSizeX,
const GLsizei theViewportSizeY,
const GLboolean toForcePowerOfTwo = GL_FALSE);
const GLsizei theViewportSizeY);
//! Setup viewport to render into FBO
Standard_EXPORT void SetupViewport (const Handle(OpenGl_Context)& theGlCtx);
@ -95,56 +93,41 @@ public:
const GLsizei theVPSizeY);
//! Bind frame buffer (to render into the texture).
Standard_EXPORT void BindBuffer (const Handle(OpenGl_Context)& theGlCtx);
Standard_EXPORT virtual void BindBuffer (const Handle(OpenGl_Context)& theGlCtx);
//! Unbind frame buffer.
Standard_EXPORT void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);
Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);
//! Bind the texture.
Standard_EXPORT void BindTexture (const Handle(OpenGl_Context)& theGlCtx);
//! Unbind the texture.
Standard_EXPORT void UnbindTexture (const Handle(OpenGl_Context)& theGlCtx);
private:
//! Check texture could be created
Standard_Boolean isProxySuccess() const;
//! Generate texture with undefined data
Standard_Boolean initTrashTexture (const Handle(OpenGl_Context)& theGlContext);
Standard_Boolean isValidTexture() const
//! Returns the color texture.
inline const Handle(OpenGl_Texture)& ColorTexture() const
{
return myGlTextureId != NO_TEXTURE;
return myColorTexture;
}
//! Returns the depth-stencil texture.
inline const Handle(OpenGl_Texture)& DepthStencilTexture() const
{
return myDepthStencilTexture;
}
protected:
//! Generate textures with undefined data
Standard_Boolean initTrashTextures (const Handle(OpenGl_Context)& theGlContext);
Standard_Boolean isValidFrameBuffer() const
{
return myGlFBufferId != NO_FRAMEBUFFER;
}
Standard_Boolean isValidDepthBuffer() const
{
return myGlDepthRBId != NO_RENDERBUFFER;
}
protected:
Standard_Boolean isValidStencilBuffer() const
{
return myGlStencilRBId != NO_RENDERBUFFER;
}
private:
GLsizei mySizeX; //!< texture width
GLsizei mySizeY; //!< texture height
GLsizei myVPSizeX; //!< viewport width (should be <= texture width)
GLsizei myVPSizeY; //!< viewport height (should be <= texture height)
GLint myTextFormat; //!< GL_RGB, GL_RGBA,...
GLuint myGlTextureId; //!< GL texture ID
GLuint myGlFBufferId; //!< FBO object ID
GLuint myGlDepthRBId; //!< RenderBuffer object for depth ID
GLuint myGlStencilRBId; //!< RenderBuffer object for stencil ID
GLsizei myVPSizeX; //!< viewport width (should be <= texture width)
GLsizei myVPSizeY; //!< viewport height (should be <= texture height)
GLint myTextFormat; //!< GL_RGB, GL_RGBA,...
GLuint myGlFBufferId; //!< FBO object ID
Handle(OpenGl_Texture) myColorTexture; //!< color texture object
Handle(OpenGl_Texture) myDepthStencilTexture; //!< depth-stencil texture object
public:

View File

@ -162,38 +162,34 @@ void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
glBindTexture (myTarget, NO_TEXTURE);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
const Image_PixMap& theImage,
const Graphic3d_TypeOfTexture theType)
//=======================================================================
//function : GetDataFormat
//purpose :
//=======================================================================
bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
const Image_PixMap& theData,
GLint& theTextFormat,
GLenum& thePixelFormat,
GLenum& theDataType)
{
myHasMipmaps = Standard_False;
if (theImage.IsEmpty() || !Create (theCtx))
{
return false;
}
myTextFormat = GL_RGBA8;
GLenum aPixelFormat = 0;
GLenum aDataType = 0;
switch (theImage.Format())
theTextFormat = GL_RGBA8;
thePixelFormat = 0;
theDataType = 0;
switch (theData.Format())
{
case Image_PixMap::ImgGrayF:
{
myTextFormat = GL_ALPHA8; // GL_R8, GL_R32F
aPixelFormat = GL_ALPHA; // GL_RED
aDataType = GL_FLOAT;
break;
theTextFormat = GL_ALPHA8; // GL_R8, GL_R32F
thePixelFormat = GL_ALPHA; // GL_RED
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgRGBAF:
{
myTextFormat = GL_RGBA8; // GL_RGBA32F
aPixelFormat = GL_RGBA;
aDataType = GL_FLOAT;
break;
theTextFormat = GL_RGBA8; // GL_RGBA32F
thePixelFormat = GL_RGBA;
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgBGRAF:
{
@ -201,31 +197,31 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
return false;
}
myTextFormat = GL_RGBA8; // GL_RGBA32F
aPixelFormat = GL_BGRA; // equals to GL_BGRA_EXT
aDataType = GL_FLOAT;
break;
theTextFormat = GL_RGBA8; // GL_RGBA32F
thePixelFormat = GL_BGRA; // equals to GL_BGRA_EXT
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgRGBF:
{
myTextFormat = GL_RGB8; // GL_RGB32F
aPixelFormat = GL_RGB;
aDataType = GL_FLOAT;
break;
theTextFormat = GL_RGB8; // GL_RGB32F
thePixelFormat = GL_RGB;
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgBGRF:
{
myTextFormat = GL_RGB8; // GL_RGB32F
aPixelFormat = GL_BGR; // equals to GL_BGR_EXT
aDataType = GL_FLOAT;
break;
theTextFormat = GL_RGB8; // GL_RGB32F
thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgRGBA:
{
myTextFormat = GL_RGBA8;
aPixelFormat = GL_RGBA;
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_RGBA8;
thePixelFormat = GL_RGBA;
theDataType = GL_UNSIGNED_BYTE;
return true;
}
case Image_PixMap::ImgBGRA:
{
@ -233,17 +229,17 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
return false;
}
myTextFormat = GL_RGBA8;
aPixelFormat = GL_BGRA; // equals to GL_BGRA_EXT
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_RGBA8;
thePixelFormat = GL_BGRA; // equals to GL_BGRA_EXT
theDataType = GL_UNSIGNED_BYTE;
return true;
}
case Image_PixMap::ImgRGB32:
{
myTextFormat = GL_RGB8;
aPixelFormat = GL_RGBA;
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_RGB8;
thePixelFormat = GL_RGBA;
theDataType = GL_UNSIGNED_BYTE;
return true;
}
case Image_PixMap::ImgBGR32:
{
@ -251,17 +247,17 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
return false;
}
myTextFormat = GL_RGB8;
aPixelFormat = GL_BGRA; // equals to GL_BGRA_EXT
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_RGB8;
thePixelFormat = GL_BGRA; // equals to GL_BGRA_EXT
theDataType = GL_UNSIGNED_BYTE;
return true;
}
case Image_PixMap::ImgRGB:
{
myTextFormat = GL_RGB8;
aPixelFormat = GL_RGB;
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_RGB8;
thePixelFormat = GL_RGB;
theDataType = GL_UNSIGNED_BYTE;
return true;
}
case Image_PixMap::ImgBGR:
{
@ -269,27 +265,48 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
return false;
}
myTextFormat = GL_RGB8;
aPixelFormat = GL_BGR; // equals to GL_BGR_EXT
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_RGB8;
thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
theDataType = GL_UNSIGNED_BYTE;
return true;
}
case Image_PixMap::ImgGray:
{
myTextFormat = GL_ALPHA8; // GL_R8
aPixelFormat = GL_ALPHA; // GL_RED
aDataType = GL_UNSIGNED_BYTE;
break;
theTextFormat = GL_ALPHA8; // GL_R8
thePixelFormat = GL_ALPHA; // GL_RED
theDataType = GL_UNSIGNED_BYTE;
return true;
}
default:
{
return false;
}
}
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
const Standard_Integer theTextFormat,
const GLenum thePixelFormat,
const GLenum theDataType,
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
const Graphic3d_TypeOfTexture theType,
const Image_PixMap* theImage)
{
if (!Create (theCtx))
{
Release (theCtx.operator->());
return false;
}
myHasMipmaps = Standard_False;
myTextFormat = theTextFormat;
const GLsizei aWidth = theSizeX;
const GLsizei aHeight = theSizeY;
const GLsizei aMaxSize = theCtx->MaxTextureSize();
const GLsizei aWidth = (GLsizei )theImage.SizeX();
const GLsizei aHeight = (GLsizei )theImage.SizeY();
// Notice that formally general NPOT textures are required by OpenGL 2.0 specifications
// however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT!
@ -301,16 +318,20 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
GLint aTestWidth = 0;
GLint aTestHeight = 0;
GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL;
// setup the alignment
OpenGl_UnpackAlignmentSentry anUnpackSentry;
const GLint anAligment = Min ((GLint )theImage.MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
if (aDataPtr != NULL)
{
const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
// notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
const GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
// notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
const GLint anExtraBytes = GLint(theImage->RowExtraBytes());
const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes());
glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
}
switch (theType)
{
@ -322,42 +343,47 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Image_PixMap aCopy;
GLvoid* aDataPtr = (GLvoid* )theImage.Data();
if (aWidth != aWidthOut)
if (aDataPtr != NULL)
{
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
if (!aCopy.InitTrash (theImage.Format(), Standard_Size(aWidthOut), 1)
|| gluScaleImage (aPixelFormat,
aWidth, 1, aDataType, theImage.Data(),
aWidthOut, 1, aDataType, aCopy.ChangeData()) != 0)
if (aWidth != aWidthOut)
{
Unbind (theCtx);
return false;
}
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
if (!aCopy.InitTrash (theImage->Format(), Standard_Size(aWidthOut), 1)
|| gluScaleImage (thePixelFormat,
aWidth, 1, theDataType, theImage->Data(),
aWidthOut, 1, theDataType, aCopy.ChangeData()) != 0)
{
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
aDataPtr = (GLvoid* )aCopy.Data();
anUnpackSentry.Reset();
aDataPtr = (GLvoid* )aCopy.Data();
anUnpackSentry.Reset();
}
}
// use proxy to check texture could be created or not
glTexImage1D (GL_PROXY_TEXTURE_1D, 0, myTextFormat,
aWidthOut, 0,
aPixelFormat, aDataType, NULL);
thePixelFormat, theDataType, NULL);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
if (aTestWidth == 0)
{
// no memory or broken input parameters
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
glTexImage1D (GL_TEXTURE_1D, 0, myTextFormat,
aWidthOut, 0,
aPixelFormat, aDataType, aDataPtr);
thePixelFormat, theDataType, aDataPtr);
if (glGetError() != GL_NO_ERROR)
{
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
@ -375,44 +401,49 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Image_PixMap aCopy;
GLvoid* aDataPtr = (GLvoid* )theImage.Data();
if (aWidth != aWidthOut || aHeight != aHeightOut)
if (aDataPtr != NULL)
{
// scale texture
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
if (!aCopy.InitTrash (theImage.Format(), Standard_Size(aWidthOut), Standard_Size(aHeightOut))
|| gluScaleImage (aPixelFormat,
aWidth, aHeight, aDataType, theImage.Data(),
aWidthOut, aHeightOut, aDataType, aCopy.ChangeData()) != 0)
if (aWidth != aWidthOut || aHeight != aHeightOut)
{
Unbind (theCtx);
return false;
}
// scale texture
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
if (!aCopy.InitTrash (theImage->Format(), Standard_Size(aWidthOut), Standard_Size(aHeightOut))
|| gluScaleImage (thePixelFormat,
aWidth, aHeight, theDataType, theImage->Data(),
aWidthOut, aHeightOut, theDataType, aCopy.ChangeData()) != 0)
{
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
aDataPtr = (GLvoid* )aCopy.Data();
anUnpackSentry.Reset();
aDataPtr = (GLvoid* )aCopy.Data();
anUnpackSentry.Reset();
}
}
// use proxy to check texture could be created or not
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, myTextFormat,
aWidthOut, aHeightOut, 0,
aPixelFormat, aDataType, NULL);
thePixelFormat, theDataType, NULL);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
if (aTestWidth == 0 || aTestHeight == 0)
{
// no memory or broken input parameters
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
glTexImage2D (GL_TEXTURE_2D, 0, myTextFormat,
aWidthOut, aHeightOut, 0,
aPixelFormat, aDataType, aDataPtr);
thePixelFormat, theDataType, aDataPtr);
if (glGetError() != GL_NO_ERROR)
{
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
@ -436,23 +467,25 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
// use proxy to check texture could be created or not
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, myTextFormat,
aWidthOut, aHeightOut, 0,
aPixelFormat, aDataType, NULL);
thePixelFormat, theDataType, NULL);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
if (aTestWidth == 0 || aTestHeight == 0)
{
// no memory or broken input parameters
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
// upload main picture
glTexImage2D (GL_TEXTURE_2D, 0, myTextFormat,
aWidthOut, aHeightOut, 0,
aPixelFormat, aDataType, theImage.Data());
thePixelFormat, theDataType, theImage->Data());
if (glGetError() != GL_NO_ERROR)
{
Unbind (theCtx);
Release (theCtx.operator->());
return false;
}
@ -470,7 +503,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
bool isCreated = gluBuild2DMipmaps (GL_TEXTURE_2D, myTextFormat,
aWidth, aHeight,
aPixelFormat, aDataType, theImage.Data()) == 0;
thePixelFormat, theDataType, theImage->Data()) == 0;
if (isCreated)
{
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &mySizeX);
@ -483,11 +516,42 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
}
default:
{
Release (theCtx.operator->());
return false;
}
}
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
const Image_PixMap& theImage,
const Graphic3d_TypeOfTexture theType)
{
if (theImage.IsEmpty())
{
Release (theCtx.operator->());
return false;
}
GLenum aPixelFormat;
GLenum aDataType;
GLint aTextFormat;
if (!GetDataFormat (theCtx, theImage, aTextFormat, aPixelFormat, aDataType))
{
Release (theCtx.operator->());
return false;
}
return Init (theCtx,
aTextFormat, aPixelFormat, aDataType,
(Standard_Integer)theImage.SizeX(),
(Standard_Integer)theImage.SizeY(),
theType, &theImage);
}
// =======================================================================
// function : InitRectangle
// purpose :

View File

@ -221,6 +221,18 @@ public:
const Image_PixMap& theImage,
const Graphic3d_TypeOfTexture theType);
//! Initialize the texture with specified format, size and texture type.
//! If theImage is empty the texture data will contain trash.
//! Notice that texture will be unbound after this call.
Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx,
const GLint theTextFormat,
const GLenum thePixelFormat,
const GLenum theDataType,
const GLsizei theSizeX,
const GLsizei theSizeY,
const Graphic3d_TypeOfTexture theType,
const Image_PixMap* theImage = NULL);
//! Allocates texture rectangle with specified format and size.
//! \note Texture data is not initialized (will contain trash).
Standard_EXPORT bool InitRectangle (const Handle(OpenGl_Context)& theCtx,
@ -237,6 +249,13 @@ public:
//! @param texture parameters
Standard_EXPORT void SetParams (const Handle(Graphic3d_TextureParams)& theParams);
//! Return texture type and format by Image_PixMap data format.
Standard_EXPORT static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
const Image_PixMap& theData,
GLint& theTextFormat,
GLenum& thePixelFormat,
GLenum& theDataType);
protected:
GLuint myTextureId; //!< GL resource ID

View File

@ -1976,10 +1976,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
return Standard_True;
}
myGlContext->core20fwd->glActiveTexture (
GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture); // texture unit for FBO texture
myRaytraceFBO1->BindTexture (myGlContext);
myRaytraceFBO1->ColorTexture()->Bind (myGlContext,
GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
myPostFSAAProgram->Bind (myGlContext);
@ -2064,7 +2062,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
if (anIt != 3) // set input for the next pass
{
aFramebuffer->BindTexture (myGlContext);
aFramebuffer->ColorTexture()->Bind (myGlContext);
aFramebuffer->UnbindBuffer (myGlContext);
}
}