std::string AbstractObject::getLabelImplementationKhr(const GLenum identifier, const GLuint name) { /* Get label size (w/o null terminator). Specifying 0 as size is not allowed, thus we pass the maximum instead. */ GLsizei size = 0; #ifndef MAGNUM_TARGET_GLES glGetObjectLabel(identifier, name, maxLabelLength(), &size, nullptr); #elif !defined(CORRADE_TARGET_NACL) glGetObjectLabelKHR(identifier, name, maxLabelLength(), &size, nullptr); #else static_cast<void>(identifier); static_cast<void>(name); CORRADE_ASSERT_UNREACHABLE(); #endif /* Make place also for the null terminator */ std::string label; label.resize(size+1); #ifndef MAGNUM_TARGET_GLES glGetObjectLabel(identifier, name, size+1, nullptr, &label[0]); #elif !defined(CORRADE_TARGET_NACL) glGetObjectLabelKHR(identifier, name, size+1, nullptr, &label[0]); #else CORRADE_ASSERT_UNREACHABLE(); #endif /* Pop null terminator and return the string */ label.resize(size); return label; }
std::string AbstractObject::getLabelImplementationExt(const GLenum identifier, const GLuint name) { GLsizei size = 0; /* Get label size (w/o null terminator) */ #ifndef CORRADE_TARGET_NACL const GLenum type = extTypeFromKhrIdentifier(identifier); glGetObjectLabelEXT(type, name, 0, &size, nullptr); #else static_cast<void>(identifier); static_cast<void>(name); CORRADE_ASSERT_UNREACHABLE(); #endif /* Make place also for the null terminator */ std::string label; label.resize(size+1); #ifndef CORRADE_TARGET_NACL glGetObjectLabelEXT(identifier, name, size+1, nullptr, &label[0]); #else CORRADE_ASSERT_UNREACHABLE(); #endif /* Pop null terminator and return the string */ label.resize(size); return label; }
Shader::Shader(const Version version, const Type type): _type(type), _id(0) { _id = glCreateShader(static_cast<GLenum>(_type)); switch(version) { #ifndef MAGNUM_TARGET_GLES case Version::GL210: sources.push_back("#version 120\n"); return; case Version::GL300: sources.push_back("#version 130\n"); return; case Version::GL310: sources.push_back("#version 140\n"); return; case Version::GL320: sources.push_back("#version 150\n"); return; case Version::GL330: sources.push_back("#version 330\n"); return; case Version::GL400: sources.push_back("#version 400\n"); return; case Version::GL410: sources.push_back("#version 410\n"); return; case Version::GL420: sources.push_back("#version 420\n"); return; case Version::GL430: sources.push_back("#version 430\n"); return; case Version::GL440: sources.push_back("#version 440\n"); return; #else case Version::GLES200: sources.push_back("#version 100\n"); return; case Version::GLES300: sources.push_back("#version 300\n"); return; #endif case Version::None: CORRADE_ASSERT(false, "Shader::Shader(): unsupported version" << version, ); } CORRADE_ASSERT_UNREACHABLE(); }
void AbstractQuery::createImplementationDefault() { #ifndef MAGNUM_TARGET_GLES2 glGenQueries(1, &_id); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) glGenQueriesEXT(1, &_id); #else CORRADE_ASSERT_UNREACHABLE(); #endif }
Vector2 doGlyphAdvance(const UnsignedInt glyph) { switch(glyph) { case 0: return {8, 0}; case 1: return {12, 0}; case 2: return {23, 0}; } CORRADE_ASSERT_UNREACHABLE(); }
void Renderbuffer::storageMultisampleImplementationNV(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) { #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) bind(); glRenderbufferStorageMultisampleNV(GL_RENDERBUFFER, samples, GLenum(internalFormat), size.x(), size.y()); #else static_cast<void>(samples); static_cast<void>(internalFormat); static_cast<void>(size); CORRADE_ASSERT_UNREACHABLE(); #endif }
void AbstractFramebuffer::drawBuffersImplementationNV(GLsizei count, const GLenum* buffers) { bindInternal(FramebufferTarget::Draw); #ifndef CORRADE_TARGET_NACL glDrawBuffersNV(count, buffers); #else static_cast<void>(count); static_cast<void>(buffers); CORRADE_ASSERT_UNREACHABLE(); #endif }
void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments) { #ifndef MAGNUM_TARGET_GLES2 glInvalidateFramebuffer(GLenum(bindInternal()), count, attachments); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) glDiscardFramebufferEXT(GLenum(bindInternal()), count, attachments); #else static_cast<void>(count); static_cast<void>(attachments); CORRADE_ASSERT_UNREACHABLE(); #endif }
void AbstractObject::labelImplementationExt(const GLenum identifier, const GLuint name, const Containers::ArrayView<const char> label) { #ifndef CORRADE_TARGET_NACL const GLenum type = extTypeFromKhrIdentifier(identifier); glLabelObjectEXT(type, name, label.size(), label); #else static_cast<void>(identifier); static_cast<void>(name); static_cast<void>(label); CORRADE_ASSERT_UNREACHABLE(); #endif }
template<> Long AbstractQuery::result<Long>() { Long result; #ifndef MAGNUM_TARGET_GLES glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &result); #elif !defined(CORRADE_TARGET_NACL) glGetQueryObjecti64vEXT(_id, GL_QUERY_RESULT_EXT, &result); #else CORRADE_ASSERT_UNREACHABLE(); #endif return result; }
void AbstractObject::labelImplementationKhr(const GLenum identifier, const GLuint name, const Containers::ArrayView<const char> label) { #ifndef MAGNUM_TARGET_GLES glObjectLabel(identifier, name, label.size(), label); #elif !defined(CORRADE_TARGET_NACL) glObjectLabelKHR(identifier, name, label.size(), label); #else static_cast<void>(identifier); static_cast<void>(name); static_cast<void>(label); CORRADE_ASSERT_UNREACHABLE(); #endif }
void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) { bindInternal(FramebufferTarget::Read); #ifndef MAGNUM_TARGET_GLES2 glReadBuffer(buffer); #elif !defined(CORRADE_TARGET_NACL) glReadBufferNV(buffer); #else static_cast<void>(buffer); CORRADE_ASSERT_UNREACHABLE(); #endif }
AbstractQuery::~AbstractQuery() { /* Moved out, nothing to do */ if(!_id) return; #ifndef MAGNUM_TARGET_GLES2 glDeleteQueries(1, &_id); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) glDeleteQueriesEXT(1, &_id); #else CORRADE_ASSERT_UNREACHABLE(); #endif }
AbstractQuery::~AbstractQuery() { /* Moved out or not deleting on destruction, nothing to do */ if(!_id || !(_flags & ObjectFlag::DeleteOnDestruction)) return; #ifndef MAGNUM_TARGET_GLES2 glDeleteQueries(1, &_id); #elif !defined(CORRADE_TARGET_EMSCRIPTEN) glDeleteQueriesEXT(1, &_id); #else CORRADE_ASSERT_UNREACHABLE(); #endif _flags |= ObjectFlag::Created; }
void AbstractFramebuffer::readImplementationRobustness(const Range2Di& rectangle, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { #ifndef MAGNUM_TARGET_GLES glReadnPixelsARB(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), dataSize, data); #elif !defined(CORRADE_TARGET_NACL) glReadnPixelsEXT(rectangle.min().x(), rectangle.min().y(), rectangle.sizeX(), rectangle.sizeY(), GLenum(format), GLenum(type), dataSize, data); #else static_cast<void>(rectangle); static_cast<void>(format); static_cast<void>(type); static_cast<void>(dataSize); static_cast<void>(data); CORRADE_ASSERT_UNREACHABLE(); #endif }
void Emitter::disconnectInternal(const Implementation::SignalData& signal, Implementation::AbstractConnectionData* data) { /* Find given connection, disconnect it and erase */ auto range = data->emitter->connections.equal_range(signal); for(auto it = range.first; it != range.second; ++it) { if(it->second != data) continue; data->emitter->disconnectInternal(it); data->emitter->connections.erase(it); data->emitter->connectionsChanged = true; return; } /* The connection must be found */ CORRADE_ASSERT_UNREACHABLE(); }
void AbstractFramebuffer::blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) { #ifndef CORRADE_TARGET_NACL source.bindInternal(FramebufferTarget::Read); destination.bindInternal(FramebufferTarget::Draw); glBlitFramebufferNV(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter)); #else static_cast<void>(source); static_cast<void>(destination); static_cast<void>(sourceRectangle); static_cast<void>(destinationRectangle); static_cast<void>(mask); static_cast<void>(filter); CORRADE_ASSERT_UNREACHABLE(); #endif }
inline #endif void AbstractFramebuffer::bindImplementationDefault(FramebufferTarget target) { Implementation::FramebufferState& state = *Context::current()->state().framebuffer; if(target == FramebufferTarget::Read) { if(state.readBinding == _id) return; state.readBinding = _id; } else if(target == FramebufferTarget::Draw) { if(state.drawBinding == _id) return; state.drawBinding = _id; } else CORRADE_ASSERT_UNREACHABLE(); /* Binding the framebuffer finally creates it */ _flags |= ObjectFlag::Created; glBindFramebuffer(GLenum(target), _id); }
std::optional<ImageData2D> StbImageImporter::doImage2D(UnsignedInt) { Vector2i size; Int components; stbi_uc* const data = stbi_load_from_memory(_in, _in.size(), &size.x(), &size.y(), &components, 0); if(!data) { Error() << "Trade::StbImageImporter::image2D(): cannot open the image:" << stbi_failure_reason(); return std::nullopt; } ColorFormat format; switch(components) { case 1: #ifndef MAGNUM_TARGET_GLES2 format = ColorFormat::Red; #else format = Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ? ColorFormat::Red : ColorFormat::Luminance; #endif break; case 2: #ifndef MAGNUM_TARGET_GLES2 format = ColorFormat::RG; #else format = Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ? ColorFormat::RG : ColorFormat::LuminanceAlpha; #endif break; case 3: format = ColorFormat::RGB; break; case 4: format = ColorFormat::RGBA; break; default: CORRADE_ASSERT_UNREACHABLE(); } /* Copy the data with reversed row order to a new[]-allocated array so we can delete[] it later (the original data with must be deleted with free()) */ unsigned char* const imageData = new unsigned char[size.product()*components]; for(Int y = 0; y != size.y(); ++y) { const Int stride = size.x()*components; std::copy(data + y*stride, data + (y + 1)*stride, imageData + (size.y() - y - 1)*stride); } stbi_image_free(data); return Trade::ImageData2D(format, ColorType::UnsignedByte, size, imageData); }
std::size_t BufferState::indexForTarget(Buffer::TargetHint target) { switch(target) { case Buffer::TargetHint::Array: return 1; case Buffer::TargetHint::ElementArray: return 2; #ifndef MAGNUM_TARGET_GLES2 case Buffer::TargetHint::CopyRead: return 3; case Buffer::TargetHint::CopyWrite: return 4; case Buffer::TargetHint::PixelPack: return 5; case Buffer::TargetHint::PixelUnpack: return 6; case Buffer::TargetHint::TransformFeedback: return 7; case Buffer::TargetHint::Uniform: return 8; case Buffer::TargetHint::AtomicCounter: return 9; case Buffer::TargetHint::DispatchIndirect: return 10; case Buffer::TargetHint::DrawIndirect: return 11; case Buffer::TargetHint::ShaderStorage: return 12; #ifndef MAGNUM_TARGET_GLES case Buffer::TargetHint::Texture: return 13; #endif #endif } CORRADE_ASSERT_UNREACHABLE(); }
std::size_t AbstractImage::pixelSize(ColorFormat format, ColorType type) { std::size_t size = 0; switch(type) { case ColorType::UnsignedByte: #ifndef MAGNUM_TARGET_GLES2 case ColorType::Byte: #endif size = 1; break; case ColorType::UnsignedShort: #ifndef MAGNUM_TARGET_GLES2 case ColorType::Short: #endif case ColorType::HalfFloat: size = 2; break; case ColorType::UnsignedInt: #ifndef MAGNUM_TARGET_GLES2 case ColorType::Int: #endif case ColorType::Float: size = 4; break; #ifndef MAGNUM_TARGET_GLES case ColorType::UnsignedByte332: case ColorType::UnsignedByte233Rev: return 1; #endif case ColorType::UnsignedShort565: #ifndef MAGNUM_TARGET_GLES case ColorType::UnsignedShort565Rev: #endif case ColorType::UnsignedShort4444: #ifndef MAGNUM_TARGET_WEBGL case ColorType::UnsignedShort4444Rev: #endif case ColorType::UnsignedShort5551: #ifndef MAGNUM_TARGET_WEBGL case ColorType::UnsignedShort1555Rev: #endif return 2; #ifndef MAGNUM_TARGET_GLES case ColorType::UnsignedInt8888: case ColorType::UnsignedInt8888Rev: case ColorType::UnsignedInt1010102: #endif #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) case ColorType::UnsignedInt2101010Rev: #endif #ifndef MAGNUM_TARGET_GLES2 case ColorType::UnsignedInt10F11F11FRev: case ColorType::UnsignedInt5999Rev: #endif case ColorType::UnsignedInt248: return 4; #ifndef MAGNUM_TARGET_GLES2 case ColorType::Float32UnsignedInt248Rev: return 8; #endif } switch(format) { #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) case ColorFormat::Red: #endif #ifndef MAGNUM_TARGET_GLES2 case ColorFormat::RedInteger: #endif #ifndef MAGNUM_TARGET_GLES case ColorFormat::Green: case ColorFormat::Blue: case ColorFormat::GreenInteger: case ColorFormat::BlueInteger: #endif #ifdef MAGNUM_TARGET_GLES2 case ColorFormat::Luminance: #endif case ColorFormat::DepthComponent: #ifndef MAGNUM_TARGET_WEBGL case ColorFormat::StencilIndex: #endif return 1*size; #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) case ColorFormat::RG: #endif #ifndef MAGNUM_TARGET_GLES2 case ColorFormat::RGInteger: #endif #ifdef MAGNUM_TARGET_GLES2 case ColorFormat::LuminanceAlpha: #endif return 2*size; case ColorFormat::RGB: #ifndef MAGNUM_TARGET_GLES2 case ColorFormat::RGBInteger: #endif #ifndef MAGNUM_TARGET_GLES case ColorFormat::BGR: case ColorFormat::BGRInteger: #endif return 3*size; case ColorFormat::RGBA: #ifndef MAGNUM_TARGET_GLES2 case ColorFormat::RGBAInteger: #endif #ifndef MAGNUM_TARGET_WEBGL case ColorFormat::BGRA: #endif #ifndef MAGNUM_TARGET_GLES case ColorFormat::BGRAInteger: #endif return 4*size; /* Handled above */ case ColorFormat::DepthStencil: CORRADE_ASSERT(false, "AbstractImage::pixelSize(): invalid ColorType specified for depth/stencil ColorFormat", 0); } CORRADE_ASSERT_UNREACHABLE(); }
Containers::Array<char> TgaImageConverter::doExportToData(const ImageView2D& image) { #ifndef MAGNUM_TARGET_GLES if(image.storage().swapBytes()) { Error() << "Trade::TgaImageConverter::exportToData(): pixel byte swap is not supported"; return nullptr; } #endif if(image.format() != PixelFormat::RGB && image.format() != PixelFormat::RGBA #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) && image.format() != PixelFormat::Red #endif #ifdef MAGNUM_TARGET_GLES2 && image.format() != PixelFormat::Luminance #endif ) { Error() << "Trade::TgaImageConverter::exportToData(): unsupported color format" << image.format(); return nullptr; } if(image.type() != PixelType::UnsignedByte) { Error() << "Trade::TgaImageConverter::exportToData(): unsupported color type" << image.type(); return nullptr; } /* Initialize data buffer */ const auto pixelSize = UnsignedByte(image.pixelSize()); Containers::Array<char> data{Containers::ValueInit, sizeof(TgaHeader) + pixelSize*image.size().product()}; /* Fill header */ auto header = reinterpret_cast<TgaHeader*>(data.begin()); switch(image.format()) { case PixelFormat::RGB: case PixelFormat::RGBA: header->imageType = 2; break; #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) case PixelFormat::Red: #endif #ifdef MAGNUM_TARGET_GLES2 case PixelFormat::Luminance: #endif header->imageType = 3; break; default: CORRADE_ASSERT_UNREACHABLE(); } header->bpp = pixelSize*8; header->width = UnsignedShort(Utility::Endianness::littleEndian(image.size().x())); header->height = UnsignedShort(Utility::Endianness::littleEndian(image.size().y())); /* Image data pointer including skip */ const char* imageData = image.data() + std::get<0>(image.dataProperties()); /* Fill data or copy them row by row if we need to drop the padding */ const std::size_t rowSize = image.size().x()*pixelSize; const std::size_t rowStride = std::get<1>(image.dataProperties()).x(); if(rowStride != rowSize) { for(std::int_fast32_t y = 0; y != image.size().y(); ++y) std::copy_n(imageData + y*rowStride, rowSize, data.begin() + sizeof(TgaHeader) + y*rowSize); } else std::copy_n(imageData, pixelSize*image.size().product(), data.begin() + sizeof(TgaHeader)); if(image.format() == PixelFormat::RGB) { auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.begin()+sizeof(TgaHeader)); std::transform(pixels, pixels + image.size().product(), pixels, [](Math::Vector3<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r'>(pixel); }); } else if(image.format() == PixelFormat::RGBA) { auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.begin()+sizeof(TgaHeader)); std::transform(pixels, pixels + image.size().product(), pixels, [](Math::Vector4<UnsignedByte> pixel) { return Math::swizzle<'b', 'g', 'r', 'a'>(pixel); }); } return data; }