1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-07 18:30:55 +03:00
occt/src/OpenGl/OpenGl_FrameBuffer.cxx

180 lines
6.3 KiB
C++

// Created by: Kirill GAVRILOV
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_ArbFBO.hxx>
#include <Standard_Assert.hxx>
IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource)
static inline bool isOddNumber (const GLsizei theNumber)
{
return theNumber & 0x01;
}
static inline GLsizei getEvenNumber (const GLsizei theNumber)
{
return isOddNumber (theNumber) ? (theNumber + 1) : theNumber;
}
//! Notice - 0 is not power of two here
static inline bool isPowerOfTwo (const GLsizei theNumber)
{
return !(theNumber & (theNumber - 1));
}
// =======================================================================
// function : OpenGl_FrameBuffer
// purpose :
// =======================================================================
OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
: myVPSizeX (0),
myVPSizeY (0),
myTextFormat (theTextureFormat),
myGlFBufferId (NO_FRAMEBUFFER),
myColorTexture (new OpenGl_Texture()),
myDepthStencilTexture (new OpenGl_Texture())
{
//
}
// =======================================================================
// function : ~OpenGl_FrameBuffer
// purpose :
// =======================================================================
OpenGl_FrameBuffer::~OpenGl_FrameBuffer()
{
Release (NULL);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
const GLsizei theViewportSizeX,
const GLsizei theViewportSizeY)
{
if (theGlContext->arbFBO == NULL)
{
return Standard_False;
}
// clean up previous state
Release (theGlContext.operator->());
// setup viewport sizes as is
myVPSizeX = theViewportSizeX;
myVPSizeY = theViewportSizeY;
// Create the textures (will be used as color buffer and depth-stencil buffer)
if (!initTrashTextures (theGlContext))
{
Release (theGlContext.operator->());
return Standard_False;
}
// Build FBO and setup it as texture
theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
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)
{
Release (theGlContext.operator->());
return Standard_False;
}
UnbindBuffer (theGlContext);
return Standard_True;
}
// =======================================================================
// function : Release
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::Release (const OpenGl_Context* theGlCtx)
{
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 (theGlCtx->IsValid())
{
theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
}
myGlFBufferId = NO_FRAMEBUFFER;
}
myColorTexture->Release (theGlCtx);
myDepthStencilTexture->Release (theGlCtx);
}
// =======================================================================
// function : initTrashTexture
// purpose :
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext)
{
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);
}
// =======================================================================
// function : SetupViewport
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& /*theGlCtx*/)
{
glViewport (0, 0, myVPSizeX, myVPSizeY);
}
// =======================================================================
// function : ChangeViewport
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::ChangeViewport (const GLsizei theVPSizeX,
const GLsizei theVPSizeY)
{
myVPSizeX = theVPSizeX;
myVPSizeY = theVPSizeY;
}
// =======================================================================
// function : BindBuffer
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx)
{
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
}
// =======================================================================
// function : UnbindBuffer
// purpose :
// =======================================================================
void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
{
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);
}