1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-07-25 12:55:50 +03:00
occt/src/OpenGl/OpenGl_VertexBuffer.cxx
kgv 5e27df788d 0023226: Extend OpenGl_Context to store map of shared GPU resources
OpenGl_Resource was slightly corrected and OpenGl_Element was extended
with Release method to manage GPU resources.

OpenGl_PrimitiveArray now uses new OpenGl_VertexBuffer class (requires OpenGL 1.5+).
Strange workarounds for feedback mode were removed.

OpenGl_Context now provides access to shared GPU resources
and manages resources queue for delayed release
(replaces functionality of removed OpenGl_ResourceCleaner).
Loaded GL_ARB_texture_buffer_object and GL_ARB_draw_instanced extensions.

Global maps of views, workspaces and structures
were moved to OpenGl_GraphicDriver members.
UserDrawCallback() function moved to OpenGl_GraphicDriver methods.

Aspect_GraphicCallbackStruct now holds handle of OpenGl_Context
instead of system-dependent pointers to GL context definition.

New classes NCollection_Vec2, NCollection_Vec3 and NCollection_Vec4
implements interface to low-level data (points, vertices, colors) in GLSL-style.
Removed EnableVBO argument from vdrawparray Draw Harness command
Corrected compilation errors
Fixed wrong argument in Index VBO initialization
Fixed several cases of incorrect memory management in TKV3d

Visual3d_ViewManager::Remove()
Destroy structures before last view removed for correct GPU resources management.

Graphic3d_Structure::GraphicClear()
Remove groups to avoid usage of dead OpenGl_Group pointers.

V3d_View::Remove()
Fixed mistake in #0000280 patch.
Small correction
Fixed OCC280 test command

Replace removed view within created one in ViewerTest EventManager.
ViewerTest, do not create unused 3D view

In current design NIS_View always created and used for both - NIS objects and AIS objects.
2012-07-13 15:51:16 +04:00

291 lines
9.8 KiB
C++

// Created by: Kirill GAVRILOV
// Copyright (c) 2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_Context.hxx>
#include <Standard_Assert.hxx>
IMPLEMENT_STANDARD_HANDLE (OpenGl_VertexBuffer, OpenGl_Resource)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer, OpenGl_Resource)
// =======================================================================
// function : OpenGl_VertexBuffer
// purpose :
// =======================================================================
OpenGl_VertexBuffer::OpenGl_VertexBuffer()
: OpenGl_Resource(),
myBufferId (NO_BUFFER),
myComponentsNb (4),
myElemsNb (0),
myDataType (GL_FLOAT)
{
//
}
// =======================================================================
// function : ~OpenGl_VertexBuffer
// purpose :
// =======================================================================
OpenGl_VertexBuffer::~OpenGl_VertexBuffer()
{
Release (NULL);
}
// =======================================================================
// function : GetTarget
// purpose :
// =======================================================================
GLenum OpenGl_VertexBuffer::GetTarget() const
{
return GL_ARRAY_BUFFER;
}
// =======================================================================
// function : Create
// purpose :
// =======================================================================
bool OpenGl_VertexBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
{
if (myBufferId == NO_BUFFER)
{
theGlCtx->core15->glGenBuffers (1, &myBufferId);
}
return myBufferId != NO_BUFFER;
}
// =======================================================================
// function : Release
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::Release (const OpenGl_Context* theGlCtx)
{
if (myBufferId == NO_BUFFER)
{
return;
}
// application can not handle this case by exception - this is bug in code
Standard_ASSERT_RETURN (theGlCtx != NULL,
"OpenGl_VertexBuffer destroyed without GL context! Possible GPU memory leakage...",);
theGlCtx->core15->glDeleteBuffers (1, &myBufferId);
myBufferId = NO_BUFFER;
}
// =======================================================================
// function : Bind
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
{
theGlCtx->core15->glBindBuffer (GetTarget(), myBufferId);
}
// =======================================================================
// function : Unbind
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
{
theGlCtx->core15->glBindBuffer (GetTarget(), NO_BUFFER);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
const GLuint theComponentsNb,
const GLsizei theElemsNb,
const GLfloat* theData)
{
if (!Create (theGlCtx))
{
return false;
}
Bind (theGlCtx);
myDataType = GL_FLOAT;
myComponentsNb = theComponentsNb;
myElemsNb = theElemsNb;
theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), theData, GL_STATIC_DRAW);
bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
Unbind (theGlCtx);
return isDone;
}
// =======================================================================
// function : SubData
// purpose :
// =======================================================================
bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
const GLfloat* theData)
{
if (!IsValid() || myDataType != GL_FLOAT ||
theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
{
return false;
}
Bind (theGlCtx);
theGlCtx->core15->glBufferSubData (GetTarget(),
GLintptr(theElemFrom) * GLintptr(myComponentsNb) * sizeof(GLfloat), // offset in bytes
GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), // size in bytes
theData);
bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
Unbind (theGlCtx);
return isDone;
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
const GLuint theComponentsNb,
const GLsizei theElemsNb,
const GLuint* theData)
{
if (!Create (theGlCtx))
{
return false;
}
Bind (theGlCtx);
myDataType = GL_UNSIGNED_INT;
myComponentsNb = theComponentsNb;
myElemsNb = theElemsNb;
theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLuint), theData, GL_STATIC_DRAW);
bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
Unbind (theGlCtx);
return isDone;
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
const GLuint theComponentsNb,
const GLsizei theElemsNb,
const GLubyte* theData)
{
if (!Create (theGlCtx))
{
return false;
}
Bind (theGlCtx);
myDataType = GL_UNSIGNED_BYTE;
myComponentsNb = theComponentsNb;
myElemsNb = theElemsNb;
theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), theData, GL_STATIC_DRAW);
bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
Unbind (theGlCtx);
return isDone;
}
// =======================================================================
// function : BindVertexAttrib
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
const GLuint theAttribLoc) const
{
if (!IsValid() || theAttribLoc == GLuint (-1))
{
return;
}
Bind (theGlCtx);
theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc);
theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, NULL);
}
// =======================================================================
// function : UnbindVertexAttrib
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
const GLuint theAttribLoc) const
{
if (!IsValid() || theAttribLoc == GLuint (-1))
{
return;
}
theGlCtx->core20->glDisableVertexAttribArray (theAttribLoc);
Unbind (theGlCtx);
}
// =======================================================================
// function : BindFixed
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx,
const GLenum theMode) const
{
if (!IsValid())
{
return;
}
Bind (theGlCtx);
glEnableClientState (theMode);
switch (theMode)
{
case GL_VERTEX_ARRAY:
{
glVertexPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
break;
}
case GL_NORMAL_ARRAY:
{
glNormalPointer (myDataType, 0, NULL);
break;
}
case GL_TEXTURE_COORD_ARRAY:
{
glTexCoordPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
break;
}
case GL_COLOR_ARRAY:
{
glColorPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
break;
}
default: break;
}
}
// =======================================================================
// function : UnbindFixed
// purpose :
// =======================================================================
void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
const GLenum theMode) const
{
if (!IsValid())
{
return;
}
Unbind (theGlCtx);
glDisableClientState (theMode);
}