42#include <ACG/GL/acg_glew.hh>
43#include <ACG/GL/globjects.hh>
44#include <ACG/GL/GLFormatInfo.hh>
45#include <ACG/ShaderUtils/GLSLShader.hh>
46#include <ACG/Utils/ImageConversion.hh>
49#if QT_VERSION_MAJOR < 6
52 #include <QtOpenGLWidgets/QOpenGLWidget>
60Texture::Texture( GLenum tgt, GLenum _unit )
61 : target(tgt), unit(_unit), valid(false), texture(0u), internalFormat_(0)
65void Texture::bindAsImage(GLuint _index, GLenum _access)
67#if defined(GL_ARB_shader_image_load_store)
69 glBindImageTexture(_index,
id(), 0, GL_FALSE, 0, _access, getInternalFormat());
71 std::cerr <<
"Texture::bindAsImage - error: texture not initialized!" << std::endl;
73 std::cerr <<
"Texture::bindAsImage - glBindImageTexture symbol not loaded!" << std::endl;
78GLint Texture::getInternalFormat()
83 glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat_);
86 return internalFormat_;
125bool Texture::clear(
const ACG::Vec4f& _color )
127#ifdef GL_ARB_clear_texture
128 if (supportsClearTexture() && texture)
130 glClearTexImage(texture, 0, GL_RGBA, GL_FLOAT, _color.
data());
139#ifdef GL_ARB_clear_texture
140 if (supportsClearTexture() && texture)
142 glClearTexImage(texture, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, _color.
data());
149bool Texture::clear(
const ACG::Vec4i& _color )
151#ifdef GL_ARB_clear_texture
152 if (supportsClearTexture() && texture)
154 glClearTexImage(texture, 0, GL_RGBA_INTEGER, GL_INT, _color.
data());
161bool Texture::supportsImageLoadStore()
163 static int status = -1;
167#if defined(GL_ARB_shader_image_load_store)
180bool Texture::supportsTextureBuffer()
182 static int status = -1;
194bool Texture::supportsClearTexture()
196 static int status = -1;
200#if defined(GL_ARB_clear_texture)
211bool Texture::supportsGenerateMipmap()
213 static int status = -1;
217#if defined(GL_SGIS_generate_mipmap)
231Texture1D::Texture1D( GLenum unit ) :
Texture(GL_TEXTURE_1D, unit),
236void Texture1D::setData(GLint _level,
237 GLint _internalFormat,
241 const GLvoid* _data) {
245 glTexImage1D(GL_TEXTURE_1D, _level, _internalFormat, _width, 0, _format, _type, _data);
248 internalFormat_ = _internalFormat;
254void Texture1D::setStorage( GLsizei _levels, GLenum _internalFormat, GLsizei _width ) {
255#ifdef GL_ARB_texture_storage
257 glTexStorage1D(GL_TEXTURE_1D, _levels, _internalFormat, _width);
260 internalFormat_ = _internalFormat;
262 GLFormatInfo finfo(_internalFormat);
263 format_ = finfo.format();
264 type_ = finfo.type();
269bool Texture1D::getData( GLint _level,
void* _dst ) {
272 glGetIntegerv(GL_TEXTURE_BINDING_1D, &curTex);
275 glGetTexImage(GL_TEXTURE_1D, _level, format_, type_, _dst);
277 glBindTexture(GL_TEXTURE_1D, curTex);
284bool Texture1D::getData( GLint _level, std::vector<char>& _dst ) {
287 GLFormatInfo finfo(internalFormat_);
289 if (finfo.isValid()) {
290 size_t bufSize = finfo.elemSize() * width_;
292 if (_dst.size() < bufSize)
293 _dst.resize(bufSize);
296 return getData(_level, &_dst[0]);
308Texture2D::Texture2D(GLenum unit)
309 :
Texture(GL_TEXTURE_2D, unit),
310 width_(0), height_(0),
311 format_(0), type_(0),
317bool Texture2D::autogenerateMipMaps()
326#ifdef GL_SGIS_generate_mipmap
327 if (supportsGenerateMipmap())
329 parameter(GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
334 buildMipsCPU_ =
true;
340void Texture2D::disableAutogenerateMipMaps()
342#ifdef GL_SGIS_generate_mipmap
343 if (supportsGenerateMipmap())
344 parameter(GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
346 buildMipsCPU_ =
false;
351void Texture2D::setData(GLint _level,
352 GLint _internalFormat,
360 if (getUnit() == GL_NONE)
361 setUnit(GL_TEXTURE0);
365 if (buildMipsCPU_ && _level == 0)
366 buildMipMaps(_internalFormat, _width, _height, _format, _type, _data);
368 glTexImage2D(GL_TEXTURE_2D, _level, _internalFormat, _width, _height, 0, _format, _type, _data);
372 glGenerateMipmap(GL_TEXTURE_2D);
376 internalFormat_ = _internalFormat;
382void Texture2D::setStorage( GLsizei _levels, GLenum _internalFormat, GLsizei _width, GLsizei _height ) {
383#ifdef GL_ARB_texture_storage
385 glTexStorage2D(GL_TEXTURE_2D, _levels, _internalFormat, _width, _height);
389 internalFormat_ = _internalFormat;
391 GLFormatInfo finfo(_internalFormat);
392 format_ = finfo.format();
393 type_ = finfo.type();
398bool Texture2D::getData( GLint _level,
void* _dst ) {
401 glGetIntegerv(GL_TEXTURE_BINDING_2D, &curTex);
404 glGetTexImage(GL_TEXTURE_2D, _level, format_, type_, _dst);
406 glBindTexture(GL_TEXTURE_2D, curTex);
413bool Texture2D::getData( GLint _level, std::vector<char>& _dst ) {
416 GLFormatInfo finfo(internalFormat_);
418 if (finfo.isValid()) {
419 size_t bufSize = finfo.elemSize() * width_ * height_;
421 if (_dst.size() < bufSize)
422 _dst.resize(bufSize);
425 return getData(_level, &_dst[0]);
432void Texture2D_buildMipMaps_DataInterpreter(
Vec4f* _dst,
int _numChannels,
int _srcOffset,
const void* _src)
434 const T* dataT =
static_cast<const T*
>(_src);
436 for (
int i = 0; i < _numChannels; ++i)
437 (*_dst)[i] = float(dataT[_srcOffset + i]);
440void Texture2D::buildMipMaps( GLenum _internalfmt,
452 GLFormatInfo finfo(_internalfmt);
454 if (finfo.isValid() && (finfo.isFloat() || finfo.isNormalized()))
456 int numChannels = finfo.channelCount();
467 std::vector<int> mipMemsize(1, 0);
468 std::vector<Vec2i> mipSize(1, curSize);
470 mipMemsize.reserve(16);
476 while (curSize[0] > 1 || curSize[1] > 1)
478 for (
int k = 0; k < 2; ++k)
479 curSize[k] = std::max(1, curSize[k] >> 1);
482 mipSize.push_back(curSize);
485 int numPixels = curSize[0] * curSize[1];
486 mipMemsize.push_back(numPixels * numChannels * 4);
492 std::vector<int> mipOffset;
493 mipOffset.reserve(16);
494 int totalMemSize = 0;
495 for (
int mipID = 0; mipID < numMips; ++mipID)
497 mipOffset.push_back(totalMemSize);
498 totalMemSize += mipMemsize[mipID];
503 std::vector<float> mipData(totalMemSize / 4);
506 for (
int mipID = 1; mipID < numMips; ++mipID)
508 Vec2i srcSize = mipSize[mipID-1];
509 Vec2i dstSize = mipSize[mipID];
511 int srcOffset = mipOffset[mipID-1];
512 int dstOffset = mipOffset[mipID];
514 int dstNumPixels = dstSize[0] * dstSize[1];
520 for (
int dstPixel = 0; dstPixel < dstNumPixels; ++dstPixel)
522 int x = dstPixel % dstSize[0];
523 int y = dstPixel / dstSize[0];
527 Vec2i srcPixelPos[4] =
530 Vec2i(x * 2, y * 2 + 1),
Vec2i(x * 2 + 1, y * 2 + 1)
533 Vec4f avgColor =
Vec4f(0.0f, 0.0f, 0.0f, 0.0f);
536 for (
int srcPixel = 0; srcPixel < 4; ++srcPixel)
539 pixelData[srcPixel] =
Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
542 srcPixelPos[srcPixel][0] = std::min(srcPixelPos[srcPixel][0], srcSize[0] - 1);
543 srcPixelPos[srcPixel][1] = std::min(srcPixelPos[srcPixel][1], srcSize[1] - 1);
546 int srcPixelPosLinear = srcSize[0] * srcPixelPos[srcPixel][1] + srcPixelPos[srcPixel][0];
553 case GL_DOUBLE: Texture2D_buildMipMaps_DataInterpreter<double>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
break;
554 case GL_FLOAT: Texture2D_buildMipMaps_DataInterpreter<float>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
break;
555 case GL_INT: Texture2D_buildMipMaps_DataInterpreter<int>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
break;
556 case GL_UNSIGNED_INT: Texture2D_buildMipMaps_DataInterpreter<unsigned int>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
break;
557 case GL_SHORT: Texture2D_buildMipMaps_DataInterpreter<short>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
break;
558 case GL_UNSIGNED_SHORT: Texture2D_buildMipMaps_DataInterpreter<unsigned short>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
break;
561 Texture2D_buildMipMaps_DataInterpreter<char>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
563 if (finfo.isNormalized())
564 pixelData[srcPixel] /= 127.0f;
566 case GL_UNSIGNED_BYTE:
568 Texture2D_buildMipMaps_DataInterpreter<unsigned char>(pixelData + srcPixel, numChannels, srcPixelPosLinear * numChannels, _data);
570 if (finfo.isNormalized())
571 pixelData[srcPixel] /= 255.0f;
574 default: std::cerr <<
"MipMaps: unknown data type: " << _type << std::endl;
581 for (
int c = 0; c < numChannels; ++c)
582 pixelData[srcPixel][c] = mipData[srcOffset/4 + srcPixelPosLinear * numChannels + c];
585 avgColor += pixelData[srcPixel];
591 int dstPixelPosLinear = y * dstSize[0] + x;
592 for (
int c = 0; c < numChannels; ++c)
593 mipData[dstOffset / 4 + dstPixelPosLinear * numChannels + c] = avgColor[c];
601 for (
int mipID = 0; mipID < numMips; ++mipID)
604 const void* mipDataPtr = _data;
605 GLenum mipDataType = _type;
612 mipDataPtr = &mipData[mipOffset[mipID] / 4];
613 mipDataType = GL_FLOAT;
616 glTexImage2D(getTarget(), mipID, _internalfmt, mipSize[mipID][0], mipSize[mipID][1], 0, _format, mipDataType, mipDataPtr);
623bool Texture2D::loadFromFile(
const std::string& _filename, GLenum _minFilter, GLenum _magFilter )
625 bool success =
false;
627 const int numMipmapEnums = 4;
628 GLenum mipmapEnums[numMipmapEnums] = {GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR};
629 bool mipmaps =
false;
631 for (
int i = 0; i < numMipmapEnums; ++i)
632 mipmaps = mipmaps || _minFilter == mipmapEnums[i];
634 if (!_filename.empty())
640 if (qtex.load(_filename.c_str()))
645 autogenerateMipMaps();
647 QImage gltex = ACG::Util::convertToGLFormat(qtex);
649 setData(0, GL_RGBA, gltex.width(), gltex.height(), GL_RGBA, GL_UNSIGNED_BYTE, gltex.bits(), mipmaps);
656 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _minFilter);
657 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _magFilter);
664void Texture2D::loadRandom( GLint _internalFormat, GLsizei _width, GLsizei _height )
668 if (finfo.isValid() && _width && _height)
670 int n = _width * _height * finfo.channelCount();
674 std::vector<float> randF;
675 std::vector<int> randI;
679 if (finfo.isFloat() || finfo.isNormalized())
683 bool isSigned = finfo.isInt();
685 for (
int i = 0; i < n; ++i)
687 float r = float(rand()) / float(RAND_MAX);
702 for (
int i = 0; i < n; ++i)
710 setData(0, _internalFormat, _width, _height, finfo.format(), gltype, dataPtr);
714bool Texture2D::checkTextureMem( GLenum _internalFormat, GLsizei _width, GLsizei _height, GLenum _format)
717 glGenTextures(1, &t);
724 glGetIntegerv(GL_TEXTURE_BINDING_2D, &savedTex);
727 glBindTexture(GL_TEXTURE_2D, t);
728 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, _internalFormat, _width, _height, 0, _format, GL_FLOAT, 0);
731 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
735 glBindTexture(GL_TEXTURE_2D, savedTex);
736 glDeleteTextures(1, &t);
744#if defined(GL_VERSION_1_5)
746void VertexBufferObject::del() {
748 glDeleteBuffers(1, &vbo);
752void VertexBufferObject::upload(
753 GLsizeiptr size,
const GLvoid* data, GLenum usage) {
760 glBufferData(target, size, data, usage);
763void VertexBufferObject::uploadSubData(
764 GLuint _offset, GLuint _size,
const GLvoid* _data ) {
766 glBufferSubData(target, _offset, _size, _data);
769void VertexBufferObject::gen() {
770 glGenBuffers(1, &vbo);
775int VertexBufferObject::size() {
778 glGetBufferParameteriv(target, GL_BUFFER_SIZE, &bufsize);
787TextureBuffer::TextureBuffer(GLenum u)
790 bufferSize_(0), buffer_(0), usage_(0), fmt_(0) {
794TextureBuffer::~TextureBuffer() {
796 glDeleteBuffers(1, &buffer_);
799void TextureBuffer::setBufferData(
800 size_t _size,
const void* _data, GLenum _internalFormat, GLenum _usage) {
801 if (supportsTextureBuffer()) {
804 glGenBuffers(1, &buffer_);
806 glBindBuffer(GL_TEXTURE_BUFFER, buffer_);
807 glBufferData(GL_TEXTURE_BUFFER,
static_cast<GLsizei
>(_size), _data, _usage);
810 fmt_ = _internalFormat;
813 if (getUnit() == GL_NONE)
814 setUnit(GL_TEXTURE0);
818 glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, buffer_);
823 std::cerr <<
"TextureBuffer::setData - gpu does not support buffer textures!" << std::endl;
826bool TextureBuffer::getBufferData(
void* _dst) {
830 glBindBuffer(GL_TEXTURE_BUFFER, buffer_);
831 glGetBufferSubData(GL_TEXTURE_BUFFER, 0, bufferSize_, _dst);
835 std::cerr <<
"TextureBuffer::getBufferData - gpu does not support buffer textures!" << std::endl;
837 std::cerr <<
"TextureBuffer::getBufferData - currently only in core profile available!" << std::endl;
842bool TextureBuffer::getBufferData(std::vector<char>& _dst) {
843 if (_dst.size() <
size_t(bufferSize_))
844 _dst.resize(bufferSize_);
847 return getBufferData(&_dst[0]);
857#if defined(GL_NV_vertex_program) || defined(GL_NV_fragment_program)
859void ProgramBaseNV::bind() {
862 glBindProgramARB(target, program);
865void ProgramBaseNV::unbind() {
866 glBindProgramARB(target, 0);
869bool ProgramBaseNV::load(
const char* prog_text) {
870 int size = int(strlen(prog_text));
873 glLoadProgramNV(target, program, size, (
const GLubyte *) prog_text);
875 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errpos);
877 fprintf(stderr,
"\nprogram error:\n");
878 int bgn = std::max(0, errpos - 10), end = std::min(size, bgn + 30);
879 for (
int i = bgn; i < end; ++i)
880 fputc(prog_text[i], stderr);
888void ProgramBaseNV::gen() {
889 glGenProgramsARB(1, &program);
893void ProgramBaseNV::del() {
895 glDeleteProgramsARB(1, &program);
901#if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
903void ProgramBaseARB::bind() {
906 glBindProgramARB(target, program);
908void ProgramBaseARB::unbind() {
909 glBindProgramARB(target, 0);
912bool ProgramBaseARB::load(
const char* prog_text) {
913 int size = int(strlen(prog_text));
917 glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB, size, prog_text);
919 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errpos);
921 fprintf(stderr,
"\nprogram error:\n");
922 int bgn = std::max(0, errpos - 10), end = std::min(size, bgn + 30);
923 for (
int i = bgn; i < end; ++i)
924 fputc(prog_text[i], stderr);
931void ProgramBaseARB::gen() {
932 glGenProgramsARB(1, &program);
935void ProgramBaseARB::del() {
937 glDeleteProgramsARB(1, &program);
947int VertexArrayObject::supportStatus_ = -1;
949VertexArrayObject::VertexArrayObject()
954VertexArrayObject::~VertexArrayObject()
956#ifdef GL_ARB_vertex_array_object
958 glDeleteVertexArrays(1, &id_);
963void VertexArrayObject::bind()
965#ifdef GL_ARB_vertex_array_object
970 glBindVertexArray(id_);
974void VertexArrayObject::unbind()
976#ifdef GL_ARB_vertex_array_object
977 glBindVertexArray(0);
981void VertexArrayObject::init()
983#ifdef GL_ARB_vertex_array_object
985 glDeleteVertexArrays(1, &id_);
987 glGenVertexArrays(1, &id_);
991bool VertexArrayObject::isSupported()
993#ifndef GL_ARB_vertex_array_object
998 if (supportStatus_ < 0)
1004 return supportStatus_ > 0;
1014int AtomicCounter::supportStatus_ = -1;
1016AtomicCounter::AtomicCounter(
int _numCounters)
1017 : numCounters_(_numCounters), buffer_(0)
1021AtomicCounter::~AtomicCounter()
1024 glDeleteBuffers(1, &buffer_);
1027void AtomicCounter::init()
1030#ifdef GL_ARB_shader_atomic_counters
1031 if (isSupported() && numCounters_ > 0)
1033 glGenBuffers(1, &buffer_);
1035 glBufferData(GL_ATOMIC_COUNTER_BUFFER, numCounters_ *
sizeof(
unsigned int), 0, GL_DYNAMIC_COPY);
1041 std::cerr <<
"atomic counter failed to initialize!" << std::endl;
1044void AtomicCounter::bind()
1046#ifdef GL_ARB_shader_atomic_counters
1052 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer_);
1056void AtomicCounter::bind(GLuint _index)
1058#ifdef GL_ARB_shader_atomic_counters
1064 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, _index, buffer_);
1068void AtomicCounter::unbind()
1070#ifdef GL_ARB_shader_atomic_counters
1071 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
1075void AtomicCounter::set(
unsigned int _value)
1077#ifdef GL_ARB_shader_atomic_counters
1083 const size_t bufSize = numCounters_ *
sizeof(
unsigned int);
1090 void* bufPtr = glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
1091 memset(bufPtr,
int(_value), bufSize);
1092 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
1099void AtomicCounter::get(
unsigned int* _out)
1101#ifdef GL_ARB_shader_atomic_counters
1106 const size_t bufSize = numCounters_ *
sizeof(
unsigned int);
1111 void* bufPtr = glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufSize, GL_MAP_READ_BIT);
1112 memcpy(_out, bufPtr, bufSize);
1113 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
1120bool AtomicCounter::isSupported()
1122#ifndef GL_ARB_shader_atomic_counters
1127 if (supportStatus_ < 0)
1131 return supportStatus_ > 0;
1134bool AtomicCounter::isValid()
const
1136 return buffer_ && numCounters_ > 0;
1141QueryObject::QueryObject(GLenum _type)
1142 : id_(0), state_(-1), type_(_type)
1147QueryObject::~QueryObject()
1150 glDeleteQueries(1, &id_);
1153void QueryObject::begin()
1156 glGenQueries(1, &id_);
1158 glBeginQuery(type_, id_);
1162void QueryObject::end()
1171bool QueryObject::available()
const
1175 glGetQueryObjectiv(id_, GL_QUERY_RESULT_AVAILABLE, &r);
1176 return r != GL_FALSE;
1179GLuint QueryObject::result()
const
1181 GLuint r = 0xffffffff;
1183 glGetQueryObjectuiv(id_, GL_QUERY_RESULT, &r);
1190int QueryCounter::supportStatus_ = -1;
1192QueryCounter::QueryCounter()
1195 queryObjects_[0] = queryObjects_[1] = 0;
1198QueryCounter::~QueryCounter()
1200 if (queryObjects_[0])
1201 glDeleteQueries(2, queryObjects_);
1205void QueryCounter::restart()
1207#ifdef GL_ARB_timer_query
1212 if (!queryObjects_[0])
1213 glGenQueries(2, queryObjects_);
1215 glQueryCounter(queryObjects_[0], GL_TIMESTAMP);
1220void QueryCounter::stop()
1222#ifdef GL_ARB_timer_query
1225 glQueryCounter(queryObjects_[1], GL_TIMESTAMP);
1233 GLuint64 timing = 0;
1234#ifdef GL_ARB_timer_query
1239 GLint available = 0;
1241 glGetQueryObjectiv(queryObjects_[1], GL_QUERY_RESULT_AVAILABLE, &available);
1244 glGetQueryObjectui64v(queryObjects_[0], GL_QUERY_RESULT, &timeStart);
1245 glGetQueryObjectui64v(queryObjects_[1], GL_QUERY_RESULT, &timing);
1246 timing -= timeStart;
1261 return float(ms) / 1000.0f;
1266#ifndef GL_ARB_timer_query
1271 if (supportStatus_ < 0)
1275 return supportStatus_ > 0;
1283int UniformBufferObject::supportStatus_ = -1;
1284int UniformBufferObject::maxBlockSize_ = -1;
1285int UniformBufferObject::maxBindings_ = -1;
1286int UniformBufferObject::maxCombinedShaderBlocks_ = -1;
1287int UniformBufferObject::offsetAlignment_ = -1;
1289UniformBufferObject::UniformBufferObject()
1290 : VertexBufferObject(
1291#ifndef GL_ARB_uniform_buffer_object
1301UniformBufferObject::~UniformBufferObject()
1305void UniformBufferObject::bind( GLuint _index )
1307#ifdef GL_ARB_uniform_buffer_object
1308 glBindBufferBase(GL_UNIFORM_BUFFER, _index,
id());
1313bool UniformBufferObject::isSupported()
1315#ifndef GL_ARB_uniform_buffer_object
1320 if (supportStatus_ < 0)
1324 return supportStatus_ > 0;
1327void UniformBufferObject::queryCaps()
1329#ifdef GL_ARB_uniform_buffer_object
1332 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxBindings_);
1333 glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBlockSize_);
1334 glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &maxCombinedShaderBlocks_);
1335 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment_);
1340int UniformBufferObject::getMaxBindings()
1342 if (maxBindings_ < 0)
1345 return maxBindings_;
1348int UniformBufferObject::getMaxBlocksize()
1350 if (maxBlockSize_ < 0)
1353 return maxBlockSize_;
1356int UniformBufferObject::getMaxCombinedShaderBlocks()
1358 if (maxCombinedShaderBlocks_ < 0)
1361 return maxCombinedShaderBlocks_;
1364int UniformBufferObject::getOffsetAlignment()
1366 if (offsetAlignment_ < 0)
1369 return offsetAlignment_;
1372void UniformBufferObject::setUniformData(
GLSL::Program* _prog,
const char* _bufferName,
const char* _uniformName,
const void* _data,
int _datasize,
bool _delay )
1374 if (_prog && _bufferName && _uniformName && _data)
1378 if (idx != GL_INVALID_INDEX)
1382 if (data_.size() != bufsize)
1383 data_.resize(bufsize, 0);
1390 memcpy(&data_[offset], _data, _datasize);
1394 VertexBufferObject::bind();
1396 if (size() !=
int(bufsize))
1397 VertexBufferObject::upload(bufsize, &data_[0], GL_DYNAMIC_DRAW);
1399 uploadSubData(offset, _datasize, _data);
1406void UniformBufferObject::upload()
1410 VertexBufferObject::bind();
1412 VertexBufferObject::upload(data_.size(), &data_[0], GL_DYNAMIC_DRAW);
1422int ShaderStorageBufferObject::supportStatus_ = -1;
1423int ShaderStorageBufferObject::maxBlockSize_ = -1;
1424int ShaderStorageBufferObject::maxBindings_ = -1;
1425int ShaderStorageBufferObject::maxCombinedShaderBlocks_ = -1;
1427ShaderStorageBufferObject::ShaderStorageBufferObject()
1428 : VertexBufferObject(
1429#ifndef GL_ARB_shader_storage_buffer_object
1432 GL_SHADER_STORAGE_BUFFER
1438ShaderStorageBufferObject::~ShaderStorageBufferObject()
1442void ShaderStorageBufferObject::bind( GLuint _index )
1444#ifdef GL_ARB_shader_storage_buffer_object
1445 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, _index,
id());
1449bool ShaderStorageBufferObject::isSupported()
1451#ifndef GL_ARB_shader_storage_buffer_object
1456 if (supportStatus_ < 0)
1460 return supportStatus_ > 0;
1463void ShaderStorageBufferObject::queryCaps()
1465#ifdef GL_ARB_shader_storage_buffer_object
1468 glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxBindings_);
1469 glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxBlockSize_);
1470 glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedShaderBlocks_);
1475int ShaderStorageBufferObject::getMaxBindings()
1477 if (maxBindings_ < 0)
1480 return maxBindings_;
1483int ShaderStorageBufferObject::getMaxBlocksize()
1485 if (maxBlockSize_ < 0)
1488 return maxBlockSize_;
1491int ShaderStorageBufferObject::getMaxCombinedShaderBlocks()
1493 if (maxCombinedShaderBlocks_ < 0)
1496 return maxCombinedShaderBlocks_;
float elapsedSecs()
elapsed gpu time in seconds
GLuint64 elapsedMs()
elapsed gpu time in millisecs
GLuint64 elapsedNs()
elapsed gpu time since restart() in nanosecs
static bool isSupported()
check hw support
void getUniformBlockOffsets(int _numUniforms, const char **_names, int *_outOffsets)
Get offsets of uniforms in a uniform buffer.
int getUniformBlockSize(GLuint _index)
Get size in bytes of a uniform buffer.
GLuint getUniformBlockIndex(const char *_name)
Get location of the specified uniform buffer.
Scalar * data()
access to Scalar array
Namespace providing different geometric functions concerning angles.
bool checkExtensionSupported(const std::string &_extension)
bool openGLVersion(const int _major, const int _minor, bool _verbose)
VectorT< signed int, 2 > Vec2i
bool compatibilityProfile()
get opengl core profile setting
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)