mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
Redesign Graphic3d_ArrayOfPrimitives Store vertices data in buffer objects managed using smart-pointers - no more low-level memory corruption by memory releasing after VBO creation. Remove broken hasEdgeInfos. Interleave vertex attributes (position, color, normal, uv) in single buffer. Remove from Graphic3d_ArrayOfPrimitives methods ::Orientate(). Remove structures Graphic3d_PrimitiveArray, CALL_DEF_PARRAY. Add support for 2D vertex arrays. Graphic3d_Group - remove array or primitive arrays. Introduce more universal method Graphic3d_Group::AddPrimitiveArray(). Fix warning
288 lines
9.3 KiB
C++
288 lines
9.3 KiB
C++
// Created by: Kirill GAVRILOV
|
|
// Copyright (c) 2013-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_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...",);
|
|
|
|
if (theGlCtx->IsValid())
|
|
{
|
|
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 void* theData,
|
|
const GLenum theDataType,
|
|
const GLsizei theStride)
|
|
{
|
|
if (!Create (theGlCtx))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Bind (theGlCtx);
|
|
myDataType = theDataType;
|
|
myComponentsNb = theComponentsNb;
|
|
myElemsNb = theElemsNb;
|
|
theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, 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 void* theData,
|
|
const GLenum theDataType)
|
|
{
|
|
if (!IsValid() || myDataType != theDataType ||
|
|
theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Bind (theGlCtx);
|
|
const size_t aDataSize = sizeOfGlType (theDataType);
|
|
theGlCtx->core15->glBufferSubData (GetTarget(),
|
|
GLintptr(theElemFrom) * GLintptr (myComponentsNb) * aDataSize, // offset in bytes
|
|
GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size in bytes
|
|
theData);
|
|
bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
|
|
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);
|
|
glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
|
glEnable (GL_COLOR_MATERIAL);
|
|
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);
|
|
if (theMode == GL_COLOR_ARRAY)
|
|
{
|
|
glDisable (GL_COLOR_MATERIAL);
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : BindFixed
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& ) const
|
|
{
|
|
//
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : BindFixedPosition
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_VertexBuffer::BindFixedPosition (const Handle(OpenGl_Context)& ) const
|
|
{
|
|
//
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : UnbindFixed
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& ) const
|
|
{
|
|
//
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : HasColorAttribute
|
|
// purpose :
|
|
// =======================================================================
|
|
bool OpenGl_VertexBuffer::HasColorAttribute() const
|
|
{
|
|
return false;
|
|
}
|