void ImageViewerPanel::updateTexture() { makeCurrent(); if (textures != nullptr) { switch (texType) { case DISPLAY_TYPE::BEAUTY: glTextureStorage2D(tex, 1, GL_RGBA32F, imgsize[0], imgsize[1]); glTextureSubImage2D(tex, 0, 0, 0, imgsize[0], imgsize[1], GL_RGBA, GL_FLOAT, textures); break; case DISPLAY_TYPE::P: case DISPLAY_TYPE::N: case DISPLAY_TYPE::DPDU: case DISPLAY_TYPE::DPDV: glTextureStorage2D(tex, 1, GL_RGB32F, imgsize[0], imgsize[1]); glTextureSubImage2D(tex, 0, 0, 0, imgsize[0], imgsize[1], GL_RGB, GL_FLOAT, textures); break; default: break; } } else { glTextureStorage2D(tex, 1, GL_RGBA32F, 0, 0); glTextureSubImage2D(tex, 0, 0, 0, 0, 0, GL_RGBA, GL_FLOAT, 0); } doneCurrent(); }
static bool test_cube_texture(void) { const GLint width = 16, height = 16; const GLenum target = GL_TEXTURE_CUBE_MAP; GLuint tex; bool pass = true; /* Test valid cube dimensions */ glCreateTextures(target, 1, &tex); glBindTextureUnit(0, tex); glTextureStorage2D(tex, 1, GL_RGBA8, width, height); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glDeleteTextures(1, &tex); /* Test invalid cube dimensions */ if (!piglit_khr_no_error) { glCreateTextures(target, 1, &tex); glBindTextureUnit(0, tex); glTextureStorage2D(tex, 1, GL_RGBA8, width, height+2); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glDeleteTextures(1, &tex); } return pass; }
void OceanMesh::GenBuffers() { MeshActor::GenBuffers(); glGenBuffers(1, &uvBuffer); glEnable(GL_TEXTURE_2D); // OCEAN DEPTH HEIGHTMAP glActiveTexture(GL_TEXTURE0); glGenTextures(1, &oceanDepthTexID); glBindTexture(GL_TEXTURE_2D, oceanDepthTexID); glTextureStorage2D(oceanDepthTexID, 1, GL_RGBA8, oceanDepth->x, oceanDepth->y); glTextureSubImage2D(oceanDepthTexID, 0, 0, 0, oceanDepth->x, oceanDepth->y, GL_RGBA, GL_UNSIGNED_BYTE, oceanDepth->data); // WATER FLOW MAP glActiveTexture(GL_TEXTURE1); glGenTextures(1, &flowMapTexID); glBindTexture(GL_TEXTURE_2D, flowMapTexID); glTextureStorage2D(flowMapTexID, 1, GL_RGBA8, flowMap->x, flowMap->y); glTextureSubImage2D(flowMapTexID, 0, 0, 0, flowMap->x, flowMap->y, GL_RGBA, GL_UNSIGNED_BYTE, flowMap->data); // OCEAN NORMAL MAP glActiveTexture(GL_TEXTURE2); glGenTextures(1, &oceanNormalMapID); glBindTexture(GL_TEXTURE_2D, oceanNormalMapID); glTextureStorage2D(oceanNormalMapID, 1, GL_RGBA8_SNORM, oceanNormalMap->x, oceanNormalMap->y); glTextureSubImage2D(oceanNormalMapID, 0, 0, 0, oceanNormalMap->x, oceanNormalMap->y, GL_RGBA, GL_UNSIGNED_BYTE, oceanNormalMap->data); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // OCEAN NORMAL MAP glActiveTexture(GL_TEXTURE3); glGenTextures(1, &oceanNormalMapAltID); glBindTexture(GL_TEXTURE_2D, oceanNormalMapAltID); glTextureStorage2D(oceanNormalMapAltID, 1, GL_RGBA8_SNORM, oceanNormalMapAlt->x, oceanNormalMapAlt->y); glTextureSubImage2D(oceanNormalMapAltID, 0, 0, 0, oceanNormalMapAlt->x, oceanNormalMapAlt->y, GL_RGBA, GL_UNSIGNED_BYTE, oceanNormalMapAlt->data); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // PERLIN NOISE glActiveTexture(GL_TEXTURE4); glGenTextures(1, &perlinID); glBindTexture(GL_TEXTURE_2D, perlinID); glTextureStorage2D(perlinID, 1, GL_RGBA8, perlinNoise->x, perlinNoise->y); glTextureSubImage2D(perlinID, 0, 0, 0, perlinNoise->x, perlinNoise->y, GL_RGBA, GL_UNSIGNED_BYTE, perlinNoise->data); }
void __init_frame_buffer()try { isOK=true; if (width_<=0) { throw QString("width is null"); } if (height_<=0) {throw QString("height is null");} glCreateFramebuffers(1,&fbo_); glCreateTextures(GL_TEXTURE_2D,1,&depth_texture_); glCreateTextures(GL_TEXTURE_2D,1,&color1_texture_); glCreateTextures(GL_TEXTURE_2D,1,&color0_texture_); glTextureStorage2D(depth_texture_,1,GL_DEPTH_COMPONENT32,width_,height_); glTextureStorage2D(color1_texture_,1,GL_RGB16F,width_,height_); glTextureStorage2D(color0_texture_,1,GL_RGB16F,width_,height_); glNamedFramebufferTexture(fbo_,GL_DEPTH_ATTACHMENT,depth_texture_,0); glNamedFramebufferTexture(fbo_,GL_COLOR_ATTACHMENT0,color0_texture_, 0 ); glNamedFramebufferTexture(fbo_,GL_COLOR_ATTACHMENT1,color1_texture_, 0 ); #if defined(_DEBUG) /*check*/ GLenum fboStatus = glCheckNamedFramebufferStatus( fbo_,GL_DRAW_FRAMEBUFFER); if (fboStatus!=GL_FRAMEBUFFER_COMPLETE){ isOK=false; switch ( fboStatus ) { case GL_FRAMEBUFFER_UNDEFINED: qDebug() << "GL_FRAMEBUFFER_UNDEFINED"; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:qDebug() << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:qDebug() << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:qDebug() << "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:qDebug() << "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break; case GL_FRAMEBUFFER_UNSUPPORTED:qDebug() << "GL_FRAMEBUFFER_UNSUPPORTED"; break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:qDebug() << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break; case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:qDebug() << "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break; default: break; } return ; } #endif }/*__init_frame_buffer*/ catch (const QString & error) { isOK=false; qDebug().noquote()<<error; }
void init2DTexture(const graphics::Context::InitTextureParams & _params) override { if (_params.msaaLevel == 0) { if (m_handle != _params.handle) { m_handle = _params.handle; glTextureStorage2D(GLuint(_params.handle), _params.mipMapLevels, GLenum(_params.internalFormat), _params.width, _params.height); } if (_params.data != nullptr) { glTextureSubImage2D(GLuint(_params.handle), _params.mipMapLevel, 0, 0, _params.width, _params.height, GLuint(_params.format), GLenum(_params.dataType), _params.data); } } else { glTexStorage2DMultisample(GLuint(_params.handle), _params.msaaLevel, GLenum(_params.internalFormat), _params.width, _params.height, GL_FALSE); } }
// TODO: support mip maps GLTextureCubeMap::GLTextureCubeMap( int sideLength, GLImageInternalFormat internalFormat ) : GLTexture( GLTexture::Target::TEXTURE_CUBE_MAP, internalFormat, 1 ), m_sideLength( sideLength ) { assert( sideLength > 0 ); assert( sideLength <= GLTexture::maxSizeCubeMap() ); glTextureStorage2D( id(), 1, glInternalFormat(), sideLength, sideLength ); }
bool initTexture() { gli::texture2d Texture(gli::load(getDataDirectory() + TEXTURE_DIFFUSE)); if(Texture.empty()) return 0; gli::gl GL(gli::gl::PROFILE_GL33); gli::gl::format const Format = GL.translate(Texture.format(), Texture.swizzles()); GLenum const Target = GL.translate(Texture.target()); glm::tvec2<GLsizei> const Dimensions(Texture.extent()); glCreateTextures(GL_TEXTURE_2D, 1, &TextureName[texture::TEXTURE]); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(Texture.levels() - 1)); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_SWIZZLE_R, Format.Swizzles[0]); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_SWIZZLE_G, Format.Swizzles[1]); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_SWIZZLE_B, Format.Swizzles[2]); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_SWIZZLE_A, Format.Swizzles[3]); glTextureStorage2D(TextureName[texture::TEXTURE], static_cast<GLint>(Texture.levels()), Format.Internal, Dimensions.x, Texture.target() == gli::TARGET_2D ? Dimensions.y : static_cast<GLsizei>(Texture.layers() * Texture.faces())); for(gli::texture2d::size_type Level = 0; Level < Texture.levels(); ++Level) { glTextureSubImage2D(TextureName[texture::TEXTURE], static_cast<GLint>(Level), 0, 0, static_cast<GLsizei>(Texture[Level].extent().x), static_cast<GLsizei>(Texture[Level].extent().y), Format.External, Format.Type, Texture[Level].data()); } glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &TextureName[texture::MULTISAMPLE]); glTextureParameteri(TextureName[texture::MULTISAMPLE], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::MULTISAMPLE], GL_TEXTURE_MAX_LEVEL, 0); glTextureStorage2DMultisample(TextureName[texture::MULTISAMPLE], 4, GL_RGBA8, FRAMEBUFFER_SIZE.x, FRAMEBUFFER_SIZE.y, GL_FALSE); glCreateTextures(GL_TEXTURE_2D, 1, &TextureName[texture::COLORBUFFER]); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MAX_LEVEL, 0); glTextureStorage2D(TextureName[texture::COLORBUFFER], 1, GL_RGBA8, GLsizei(FRAMEBUFFER_SIZE.x), GLsizei(FRAMEBUFFER_SIZE.y)); return true; }
bool initTexture() { bool Validated(true); gli::gl GL(gli::gl::PROFILE_GL33); gli::texture2d Texture(gli::load_dds((getDataDirectory() + TEXTURE_DIFFUSE).c_str())); assert(!Texture.empty()); gli::gl::format const Format = GL.translate(Texture.format(), Texture.swizzles()); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glCreateTextures(GL_TEXTURE_2D, texture::MAX, &TextureName[0]); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_MAX_LEVEL, GLint(Texture.levels() - 1)); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_SWIZZLE_R, GL_RED); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_SWIZZLE_G, GL_GREEN); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_SWIZZLE_B, GL_BLUE); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_SWIZZLE_A, GL_ALPHA); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTextureParameteri(TextureName[texture::DIFFUSE], GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureStorage2D(TextureName[texture::DIFFUSE], static_cast<GLint>(Texture.levels()), Format.Internal, static_cast<GLsizei>(Texture.extent().x), static_cast<GLsizei>(Texture.extent().y)); for(std::size_t Level = 0; Level < Texture.levels(); ++Level) { glTextureSubImage2D(TextureName[texture::DIFFUSE], static_cast<GLint>(Level), 0, 0, static_cast<GLsizei>(Texture[Level].extent().x), static_cast<GLsizei>(Texture[Level].extent().y), Format.External, Format.Type, Texture[Level].data()); } glm::ivec2 WindowSize(this->getWindowSize()); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MAX_LEVEL, 0); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureStorage2D(TextureName[texture::COLORBUFFER], static_cast<GLint>(1), GL_RGBA8, static_cast<GLsizei>(WindowSize.x * this->Supersampling), static_cast<GLsizei>(WindowSize.y * this->Supersampling)); return Validated; }
// TODO: support mip maps GLTextureRectangle::GLTextureRectangle( const Vector2i& size, GLImageInternalFormat internalFormat ) : GLTexture( GLTexture::Target::TEXTURE_RECTANGLE, internalFormat, 1 ), m_size( size ) { assert( size.x > 0 ); assert( size.y > 0 ); assert( size.x <= GLTexture::maxSize2D() ); assert( size.y <= GLTexture::maxSize2D() ); glTextureStorage2D( id(), 1, static_cast< GLenum >( internalFormat ), size.x, size.y ); }
GLuint glCreateTextureGTC(GLenum target, GLsizei layers, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples, GLboolean fixedsamplelocations) { GLuint texture = 0; glCreateTextures(target, 1, &texture); glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_NEAREST); switch (target) { case GL_TEXTURE_2D: assert(layers == 1 && width >= 1 && height >= 1 && depth == 1 && samples == 1 && fixedsamplelocations == GL_TRUE); glTextureStorage2D(texture, levels, internalformat, width, height); break; case GL_TEXTURE_2D_ARRAY: assert(layers >= 1 && width >= 1 && height >= 1 && depth == 1 && samples == 1 && fixedsamplelocations == GL_TRUE); glTextureStorage3D(texture, levels, internalformat, width, height, layers); break; case GL_TEXTURE_2D_MULTISAMPLE: assert(layers == 1 && width >= 1 && height >= 1 && depth == 1 && samples >= 1); glTextureStorage2DMultisample(texture, samples, internalformat, width, height, fixedsamplelocations); break; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: assert(layers >= 1 && width >= 1 && height >= 1 && depth == 1 && samples >= 1); glTextureStorage3DMultisample(texture, samples, internalformat, width, height, layers, fixedsamplelocations); break; case GL_TEXTURE_3D: assert(layers == 1 && width >= 1 && height >= 1 && depth >= 1 && samples == 1 && fixedsamplelocations == GL_TRUE); glTextureStorage3D(texture, levels, internalformat, width, height, depth); break; case GL_TEXTURE_CUBE_MAP: assert(layers == 1 && width >= 1 && height >= 1 && depth == 1 && samples == 1 && fixedsamplelocations == GL_TRUE); glTextureStorage2D(texture, levels, internalformat, width, height); break; case GL_TEXTURE_CUBE_MAP_ARRAY: assert(layers >= 1 && width >= 1 && height >= 1 && depth == 1 && samples == 1 && fixedsamplelocations == GL_TRUE); glTextureStorage3D(texture, levels, internalformat, width, height, layers * 6); break; } return texture; }
bool initTexture() { glCreateTextures(GL_TEXTURE_2D, texture::MAX, &TextureName[0]); glm::vec2 const FramwbufferSize = glm::vec2(this->getWindowSize()) * FRAMEBUFFER_SCALE; glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MAX_LEVEL, 0); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTextureStorage2D(TextureName[texture::COLORBUFFER], GLint(1), GL_RGBA8, GLsizei(FramwbufferSize.x), GLsizei(FramwbufferSize.y)); glTextureParameteri(TextureName[texture::RENDERBUFFER], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::RENDERBUFFER], GL_TEXTURE_MAX_LEVEL, 0); glTextureStorage2D(TextureName[texture::RENDERBUFFER], GLint(1), GL_DEPTH_COMPONENT24, GLsizei(FramwbufferSize.x), GLsizei(FramwbufferSize.y)); glTextureParameteri(TextureName[texture::INVOCATION_COUNT], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::INVOCATION_COUNT], GL_TEXTURE_MAX_LEVEL, 0); glTextureStorage2D(TextureName[texture::INVOCATION_COUNT], GLint(1), GL_R32UI, GLsizei(FramwbufferSize.x), GLsizei(FramwbufferSize.y)); return true; }
bool initTexture() { gli::texture2d Texture(gli::load_dds((getDataDirectory() + TEXTURE_DIFFUSE).c_str())); if(Texture.empty()) return false; gli::gl GL; gli::gl::format const Format = GL.translate(Texture.format()); glCreateTextures(GL_TEXTURE_2D, 1, &TextureName[texture::TEXTURE]); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(Texture.levels() - 1)); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(TextureName[texture::TEXTURE], GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureStorage2D(TextureName[texture::TEXTURE], GLint(Texture.levels()), Format.Internal, GLsizei(Texture[0].extent().x), GLsizei(Texture[0].extent().y)); for(std::size_t Level = 0; Level < Texture.levels(); ++Level) { glTextureSubImage2D(TextureName[texture::TEXTURE], GLint(Level), 0, 0, GLsizei(Texture[Level].extent().x), GLsizei(Texture[Level].extent().y), Format.External, Format.Type, Texture[Level].data()); } glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &TextureName[texture::MULTISAMPLE]); glTextureParameteri(TextureName[texture::MULTISAMPLE], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::MULTISAMPLE], GL_TEXTURE_MAX_LEVEL, 0); glTextureStorage2DMultisample(TextureName[texture::MULTISAMPLE], 4, GL_RGBA8, FRAMEBUFFER_SIZE.x, FRAMEBUFFER_SIZE.y, GL_FALSE); glCreateTextures(GL_TEXTURE_2D, 1, &TextureName[texture::COLORBUFFER]); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(TextureName[texture::COLORBUFFER], GL_TEXTURE_MAX_LEVEL, 0); glTextureStorage2D(TextureName[texture::COLORBUFFER], 1, GL_RGBA8, GLsizei(FRAMEBUFFER_SIZE.x), GLsizei(FRAMEBUFFER_SIZE.y)); return true; }
kit::Texture::Ptr kit::Texture::create2DFromFile(std::string filename, kit::Texture::InternalFormat format, kit::Texture::EdgeSamplingMode edgemode, kit::Texture::FilteringMode minfilter, kit::Texture::FilteringMode magfilter) { std::cout << "Loading texture from file " << filename.c_str() << std::endl; kit::Texture::Ptr returner = std::make_shared<kit::Texture>(Texture2D); returner->m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(1); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_ERR(stbi_failure_reason()); x = 1; y = 1; n = 4; bufferdata = new unsigned char[4]; bufferdata[0] = 255; bufferdata[1] = 0; bufferdata[2] = 0; bufferdata[3] = 255; } // Set resolution returner->m_resolution = glm::uvec3(x, y, 0); // Specify storage and upload data to GPU KIT_GL(glTextureStorage2D(returner->m_glHandle, returner->calculateMipLevels(), returner->m_internalFormat, returner->m_resolution.x, returner->m_resolution.y)); KIT_GL(glTextureSubImage2D(returner->m_glHandle, 0, 0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata)); // Free loaded data stbi_image_free(bufferdata); // Set parameters returner->setEdgeSamplingMode(edgemode); returner->setMinFilteringMode(minfilter); returner->setMagFilteringMode(magfilter); returner->setAnisotropicLevel(8.0f); // Generate mipmap returner->generateMipmap(); return returner; }
void piglit_init(int argc, char **argv) { int i; piglit_require_extension("GL_ARB_direct_state_access"); piglit_require_extension("GL_ARB_texture_storage"); for(i = 0; i < 4096; ++i) data[i] = rand() & 0xff; glCreateTextures(GL_TEXTURE_2D, 1, &name); glTextureParameteri(name, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTextureParameteri(name, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTextureStorage2D(name, 1, GL_RGBA8, 64, 16); glTextureSubImage2D(name, 0, 0, 0, 64, 16, GL_RGBA, GL_UNSIGNED_BYTE, data); piglit_gen_ortho_projection(0.0, 1.0, 0.0, 1.0, -2.0, 6.0, GL_FALSE); }
static bool test_immutablity(GLenum target) { GLuint tex; GLint level; GLint immutable_format; bool pass = true; glCreateTextures(target, 1, &tex); glBindTextureUnit(0, tex); glTextureStorage2D(tex, 3, GL_RGBA8, 256, 256); glTextureParameteri(tex, GL_TEXTURE_MAX_LEVEL, 4); glGetTextureParameteriv(tex, GL_TEXTURE_MAX_LEVEL, &level); glGetTextureParameteriv(tex, GL_TEXTURE_IMMUTABLE_FORMAT, &immutable_format); if (immutable_format != GL_TRUE) { printf("%s: GL_TEXTURE_IMMUTABLE_FORMAT was not set to " "GL_TRUE after glTextureStorage2D\n", TestName); pass = false; } if (level != 2) { /* The ARB_texture_storage spec says: * * "However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then * level_base is clamped to the range [0, <levels> - 1] * and level_max is then clamped to the range [level_base, * <levels> - 1], where <levels> is the parameter passed * the call to TexStorage* for the texture object" */ printf("%s: GL_TEXTURE_MAX_LEVEL changed to %d, which is " "outside the clamp range for immutables\n", TestName, level); pass = false; } /* Other immutable tests happen per-format above */ glDeleteTextures(1, &tex); return pass; }
kit::Texture::Ptr kit::Texture::create2D(glm::uvec2 resolution, kit::Texture::InternalFormat format, kit::Texture::EdgeSamplingMode edgemode, kit::Texture::FilteringMode minfilter, kit::Texture::FilteringMode magfilter) { kit::Texture::Ptr returner = std::make_shared<kit::Texture>(Texture2D); returner->m_internalFormat = format; returner->m_resolution = glm::uvec3(resolution, 0); KIT_GL(glTextureStorage2D(returner->m_glHandle, returner->calculateMipLevels(), returner->m_internalFormat, returner->m_resolution.x, returner->m_resolution.y)); returner->setEdgeSamplingMode(edgemode); // Stupid AMD bug https://gist.github.com/haikarainen/97959adfe4e3ca10968a //std::vector<GLubyte> data(returner->m_resolution.x * returner->m_resolution.y, 0); //KIT_GL(glTextureSubImage2D(returner->m_glHandle, 0, 0, 0, returner->m_resolution.x, returner->m_resolution.y, GL_RED, GL_UNSIGNED_BYTE, &data[0])); returner->setMinFilteringMode(minfilter); returner->setMagFilteringMode(magfilter); returner->setAnisotropicLevel(8.0f); return returner; }
GLuint LoadTexture(WORD resourceId) { HRSRC hrsrc = FindResource( nullptr, MAKEINTRESOURCE(resourceId), RT_BITMAP); HGLOBAL hglobal = LoadResource(nullptr, hrsrc); const GLbyte *data = static_cast<const GLbyte *>(LockResource(hglobal)); const int width = *reinterpret_cast<const int *>(data + 4); const int height = *reinterpret_cast<const int *>(data + 8); GLuint texture; glCreateTextures(GL_TEXTURE_2D, 1, &texture); glTextureStorage2D(texture, 1, GL_RGB8, width, height); glTextureSubImage2D(texture, 0, 0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, data + 40); glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); return texture; }
kit::Texture::Texture(glm::uvec2 resolution, kit::Texture::InternalFormat format, uint8_t levels) : kit::Texture(Type::Texture2D) { m_internalFormat = format; m_resolution = glm::uvec3(resolution, 0); uint8_t mipLevels = levels > 0 ? levels : calculateMipLevels(); #ifndef KIT_SHITTY_INTEL glTextureStorage2D(m_glHandle, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); #else bind(); glTexStorage2D(m_type, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); #endif setEdgeSamplingMode(EdgeSamplingMode::Repeat); setMinFilteringMode(m_minFilteringMode); setMagFilteringMode(m_magFilteringMode); setAnisotropicLevel(1.0f); }
static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data) { GLNVGcontext* gl = (GLNVGcontext*)uptr; GLNVGtexture* tex = glnvg__allocTexture(gl); if (tex == NULL) return 0; const bool formatRGBA8 = type == NVG_TEXTURE_RGBA; const bool useMipmaps = (imageFlags & NVG_IMAGE_GENERATE_MIPMAPS) != 0; glCreateTextures(GL_TEXTURE_2D, 1, &tex->tex); const uint32_t mipCount = useMipmaps ? bit_fls(core::max<uint32_t>(w, h)) : 1; glTextureStorage2D(tex->tex, mipCount, formatRGBA8 ? GL_RGBA8 : GL_R8, w, h); tex->width = w; tex->height = h; tex->type = type; if (data) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glTextureSubImage2D(tex->tex, 0, 0, 0, w, h, formatRGBA8 ? GL_RGBA : GL_RED, GL_UNSIGNED_BYTE, data); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); // The new way to build mipmaps on GLES and GL3 if (useMipmaps) { glGenerateTextureMipmap(tex->tex); } } glTextureParameteri(tex->tex, GL_TEXTURE_MIN_FILTER, useMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTextureParameteri(tex->tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); return tex->id; }
void ImageViewerPanel::initializeGL() { //glewInit(); glGetIntegerv(GL_MAJOR_VERSION, &ogl_ver_major); glGetIntegerv(GL_MINOR_VERSION, &ogl_ver_minor); shaderP = make_unique<GLSLProgram>( "resources/shaders/img_vs.glsl", "resources/shaders/img_fs.glsl"); if (ogl_ver_major == 4 && ogl_ver_minor >= 5) { // DSA // Create VAO glCreateBuffers(1, &vbo); glNamedBufferData(vbo, sizeof(frame), frame, GL_STATIC_DRAW); // IBO GLuint indices[] = { 0,1,2,2,3,0 }; glCreateBuffers(1, &ibo); glNamedBufferData(ibo, sizeof(indices), indices, GL_STATIC_DRAW); // VAO glCreateVertexArrays(1, &vao); glEnableVertexArrayAttrib(vao, 0); // Setup the formats glVertexArrayAttribFormat(vao, 0, 2, GL_FLOAT, GL_FALSE, 0); glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(float) * 2); glVertexArrayAttribBinding(vao, 0, 0); glVertexArrayElementBuffer(vao, ibo); // Setup textures int texSize = 4; glCreateTextures(GL_TEXTURE_2D, 1, &tex); glTextureParameteri(tex, GL_TEXTURE_WRAP_S, GL_REPEAT); glTextureParameteri(tex, GL_TEXTURE_WRAP_T, GL_REPEAT); glTextureParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTextureParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTextureStorage2D(tex, 1, GL_RGB32F, imgsize[0], imgsize[1]); if (texLen > 0) { glTextureSubImage2D(tex, 0, 0, 0, imgsize[0], imgsize[1], GL_RGB, GL_FLOAT, textures); } texHandle = glGetTextureHandleARB(tex); glMakeTextureHandleResidentARB(texHandle); } else { // Non-DSA glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Bind UV values glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(frame), frame, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } }
bool glPixelBuffer::create(GLushort width, GLushort height, GLushort depth, GFXImageFormat formatEnum, GFXDataFormat dataTypeEnum) { GLenum textureTypeEnum = GLUtil::glTextureTypeTable[to_U32(_textureType)]; _internalFormat = GLUtil::internalFormat(formatEnum, dataTypeEnum, false); _format = GLUtil::glImageFormatTable[to_U32(formatEnum)]; _dataType = GLUtil::glDataFormat[to_U32(dataTypeEnum)]; Console::printfn(Locale::get(_ID("GL_PB_GEN")), width, height); _width = width; _height = height; _depth = depth; _bufferSize = _width * 4; switch (_pbtype) { case PBType::PB_TEXTURE_2D: _bufferSize *= _height; break; case PBType::PB_TEXTURE_3D: _bufferSize *= _height * _depth; break; }; switch (_dataType) { case GL_SHORT: case GL_HALF_FLOAT: case GL_UNSIGNED_SHORT: _dataSizeBytes = 2; break; case GL_FLOAT: case GL_INT: case GL_UNSIGNED_INT: _dataSizeBytes = 4; break; default: break; } _bufferSize *= _dataSizeBytes; GL_API::deleteTextures(1, &_textureID, _textureType); glCreateTextures(textureTypeEnum, 1, &_textureID); glTextureParameteri(_textureID, GL_GENERATE_MIPMAP, 0); glTextureParameteri(_textureID, GL_TEXTURE_MIN_FILTER, to_I32(GL_NEAREST)); glTextureParameteri(_textureID, GL_TEXTURE_MAG_FILTER, to_I32(GL_NEAREST)); glTextureParameteri(_textureID, GL_TEXTURE_BASE_LEVEL, 0); glTextureParameteri(_textureID, GL_TEXTURE_MAX_LEVEL, 1000); glTextureParameteri(_textureID, GL_TEXTURE_WRAP_S, to_I32(GL_REPEAT)); if (_pbtype != PBType::PB_TEXTURE_1D) { glTextureParameteri(_textureID, GL_TEXTURE_WRAP_T, to_I32(GL_REPEAT)); } if (_pbtype == PBType::PB_TEXTURE_3D) { glTextureParameteri(_textureID, GL_TEXTURE_WRAP_R, to_I32(GL_REPEAT)); } U16 mipLevels = to_U16(std::floor(std::log2(std::max(_width, _height))) + 1); GL_API::getStateTracker().setPixelPackUnpackAlignment(); switch (_pbtype) { case PBType::PB_TEXTURE_1D: glTextureStorage1D(_textureID, mipLevels, _internalFormat, _width); break; case PBType::PB_TEXTURE_2D: glTextureStorage2D(_textureID, mipLevels, _internalFormat, _width, _height); break; case PBType::PB_TEXTURE_3D: glTextureStorage3D(_textureID, mipLevels, _internalFormat, _width, _height, _depth); break; }; if (_pixelBufferHandle > 0) { GLUtil::freeBuffer(_pixelBufferHandle); } GLUtil::createAndAllocBuffer(_bufferSize, GL_STREAM_DRAW, _pixelBufferHandle, NULL, _name.empty() ? nullptr : _name.c_str()); return _pixelBufferHandle != 0 && _textureID != 0; }
enum piglit_result piglit_display(void) { bool pass = true; GLuint name; GLubyte *data = malloc(50 * 50 * 6 * 4 * sizeof(GLubyte)); GLubyte *image = malloc(50 * 50 * 4 * sizeof(GLubyte)); /* Throw some invalid inputs at glGetTextureImage. */ /* Non-gen-ed name */ glGetTextureImage(3, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data); pass &= piglit_check_gl_error(GL_INVALID_OPERATION); /* Unsupported target. */ glGenTextures(1, &name); glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X, name); glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data); pass &= piglit_check_gl_error(GL_INVALID_ENUM); glDeleteTextures(1, &name); /* Unsupported dsa target for non-dsa version. */ glGetTexImage(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); pass &= piglit_check_gl_error(GL_INVALID_ENUM); /* No Storage * * The spec doesn't say what should happen in this case. This is * addressed by Khronos Bug 13223. */ glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &name); glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data); pass &= piglit_check_gl_error(GL_INVALID_OPERATION); glDeleteTextures(1, &name); /* Insufficient storage * * The spec doesn't say what should happen in this case. This is * addressed by Khronos Bug 13223. */ glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &name); glBindTexture(GL_TEXTURE_CUBE_MAP, name); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); /* Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set */ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data); pass &= piglit_check_gl_error(GL_INVALID_OPERATION); glDeleteTextures(1, &name); /* Trivial, but should work. */ glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &name); glTextureStorage2D(name, 1, GL_RGBA8, 50, 50); glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 50 * 50 * 6 * 4, data); pass &= piglit_check_gl_error(GL_NO_ERROR); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
/** * Do error-check tests for a non-mipmapped texture. */ static bool test_one_level_errors(GLenum target) { const GLint width = 64, height = 4, depth = 8; GLuint tex; GLint v; assert(target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || target == GL_TEXTURE_3D); glCreateTextures(target, 1, &tex); glBindTextureUnit(0, tex); if (target == GL_TEXTURE_1D) { glTextureStorage1D(tex, 1, GL_RGBA8, width); } else if (target == GL_TEXTURE_2D) { glTextureStorage2D(tex, 1, GL_RGBA8, width, height); } else if (target == GL_TEXTURE_3D) { glTextureStorage3D(tex, 1, GL_RGBA8, width, height, depth); } piglit_check_gl_error(GL_NO_ERROR); glGetTextureLevelParameteriv(tex, 0, GL_TEXTURE_WIDTH, &v); if (v != width) { printf("%s: bad width: %d, should be %d\n", TestName, v, width); return false; } if (target != GL_TEXTURE_1D) { glGetTextureLevelParameteriv(tex, 0, GL_TEXTURE_HEIGHT, &v); if (v != height) { printf("%s: bad height: %d, should be %d\n", TestName, v, height); return false; } } if (target == GL_TEXTURE_3D) { glGetTextureLevelParameteriv(tex, 0, GL_TEXTURE_DEPTH, &v); if (v != depth) { printf("%s: bad depth: %d, should be %d\n", TestName, v, depth); return false; } } /* The ARB_texture_storage spec says: * * "Using any of the following commands with the same texture will * result in the error INVALID_OPERATION being generated, even if * it does not affect the dimensions or format: * * - TexImage* * - CompressedTexImage* * - CopyTexImage* * - TexStorage*" */ if (!piglit_khr_no_error && target == GL_TEXTURE_2D) { glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); if (glGetError() != GL_INVALID_OPERATION) { printf("%s: glTexImage2D failed to generate error\n", TestName); return false; } glTextureStorage2D(tex, 1, GL_RGBA8, width, height); if (glGetError() != GL_INVALID_OPERATION) { printf("%s: glTextureStorage2D() failed to generate " "error\n", TestName); return false; } glCopyTexImage2D(target, 0, GL_RGBA, 0, 0, width, height, 0); if (glGetError() != GL_INVALID_OPERATION) { printf("%s: glCopyTexImage2D() failed to generate " "error\n", TestName); return false; } } glDeleteTextures(1, &tex); return true; }
/** * Per issue 27 of the spec, only sized internalFormat values are allowed. * Ex: GL_RGBA8 is OK but GL_RGBA is illegal. * Check some common formats here. These lists aren't exhaustive since * there are many extensions/versions that could effect the lists (ex: * integer formats, etc.) */ static bool test_internal_formats(void) { const GLenum target = GL_TEXTURE_2D; static const GLenum legal_formats[] = { GL_RGB4, GL_RGB5, GL_RGB8, GL_RGBA2, GL_RGBA4, GL_RGBA8, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32 }; static const GLenum illegal_formats[] = { GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT, GL_COMPRESSED_ALPHA, GL_COMPRESSED_LUMINANCE_ALPHA, GL_COMPRESSED_LUMINANCE, GL_COMPRESSED_INTENSITY, GL_COMPRESSED_RGB, GL_COMPRESSED_RGBA, GL_COMPRESSED_RGBA, GL_COMPRESSED_SRGB, GL_COMPRESSED_SRGB_ALPHA, GL_COMPRESSED_SLUMINANCE, GL_COMPRESSED_SLUMINANCE_ALPHA }; GLuint tex; bool pass = true; int i; for (i = 0; i < ARRAY_SIZE(legal_formats); i++) { glCreateTextures(target, 1, &tex); glBindTextureUnit(0, tex); glTextureStorage2D(tex, 1, legal_formats[i], 32, 32); if (!piglit_check_gl_error(GL_NO_ERROR)) { printf("%s: internal format %s should be legal" " but raised an error.", TestName, piglit_get_gl_enum_name(legal_formats[i])); pass = false; } glDeleteTextures(1, &tex); } /* Return early if KHR_no_error is enabled */ if (piglit_khr_no_error) return pass; for (i = 0; i < ARRAY_SIZE(illegal_formats); i++) { glCreateTextures(target, 1, &tex); glBindTextureUnit(0, tex); glTextureStorage2D(tex, 1, illegal_formats[i], 32, 32); if (!piglit_check_gl_error(GL_INVALID_ENUM)) { printf("%s: internal format %s should be illegal" " but didn't raised an error.", TestName, piglit_get_gl_enum_name(illegal_formats[i])); pass = false; } glDeleteTextures(1, &tex); } return pass; }
GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read) : m_pbo_size(0), m_clean(false), m_local_buffer(NULL), m_r_x(0), m_r_y(0), m_r_w(0), m_r_h(0) { // OpenGL didn't like dimensions of size 0 m_size.x = max(1,w); m_size.y = max(1,h); m_format = format; m_type = type; m_fbo_read = fbo_read; m_texture_id = 0; // Bunch of constant parameter switch (m_format) { // 1 Channel integer case GL_R32UI: case GL_R32I: m_int_format = GL_RED_INTEGER; m_int_type = (m_format == GL_R32UI) ? GL_UNSIGNED_INT : GL_INT; m_int_shift = 2; break; case GL_R16UI: m_int_format = GL_RED_INTEGER; m_int_type = GL_UNSIGNED_SHORT; m_int_shift = 1; break; // 1 Channel normalized case GL_R8: m_int_format = GL_RED; m_int_type = GL_UNSIGNED_BYTE; m_int_shift = 0; break; // 4 channel normalized case GL_RGBA16: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_SHORT; m_int_shift = 3; break; case GL_RGBA8: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_BYTE; m_int_shift = 2; break; // 4 channel integer case GL_RGBA16I: case GL_RGBA16UI: m_int_format = GL_RGBA_INTEGER; m_int_type = (m_format == GL_R16UI) ? GL_UNSIGNED_SHORT : GL_SHORT; m_int_shift = 3; break; // 4 channel float case GL_RGBA32F: m_int_format = GL_RGBA; m_int_type = GL_FLOAT; m_int_shift = 4; break; case GL_RGBA16F: m_int_format = GL_RGBA; m_int_type = GL_HALF_FLOAT; m_int_shift = 3; break; // Depth buffer case GL_DEPTH32F_STENCIL8: m_int_format = GL_DEPTH_STENCIL; m_int_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; m_int_shift = 3; // 4 bytes for depth + 4 bytes for stencil by texels break; // Backbuffer case 0: m_int_format = 0; m_int_type = 0; m_int_shift = 2; // 4 bytes by texels break; default: m_int_format = 0; m_int_type = 0; m_int_shift = 0; ASSERT(0); } m_mem_usage = (m_size.x * m_size.y) << m_int_shift; static int every_512 = 0; GLState::available_vram -= m_mem_usage; if ((GLState::available_vram < 0) && (every_512 % 512 == 0)) { fprintf(stderr, "Available VRAM is very low (%lld), a crash is expected ! Disable Larger framebuffer or reduce upscaling!\n", GLState::available_vram); every_512++; // Pull emergency break throw GSDXErrorOOM(); } // Generate & Allocate the buffer switch (m_type) { case GSTexture::Offscreen: // Offscreen is only used to read color. So it only requires 4B by pixel m_local_buffer = (uint8*)_aligned_malloc(m_size.x * m_size.y * 4, 32); case GSTexture::Texture: case GSTexture::RenderTarget: case GSTexture::DepthStencil: glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id); glTextureStorage2D(m_texture_id, 1+GL_TEX_LEVEL_0, m_format, m_size.x, m_size.y); if (m_format == GL_R8) { // Emulate DX behavior, beside it avoid special code in shader to differentiate // palette texture from a GL_RGBA target or a GL_R texture. glTextureParameteri(m_texture_id, GL_TEXTURE_SWIZZLE_A, GL_RED); } break; case GSTexture::Backbuffer: default: break; } }
GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read, bool mipmap) : m_clean(false), m_generate_mipmap(true), m_local_buffer(nullptr), m_r_x(0), m_r_y(0), m_r_w(0), m_r_h(0), m_layer(0) { // OpenGL didn't like dimensions of size 0 m_size.x = std::max(1,w); m_size.y = std::max(1,h); m_format = format; m_type = type; m_fbo_read = fbo_read; m_texture_id = 0; m_sparse = false; m_max_layer = 1; // Bunch of constant parameter switch (m_format) { // 1 Channel integer case GL_R32UI: case GL_R32I: m_int_format = GL_RED_INTEGER; m_int_type = (m_format == GL_R32UI) ? GL_UNSIGNED_INT : GL_INT; m_int_shift = 2; break; case GL_R16UI: m_int_format = GL_RED_INTEGER; m_int_type = GL_UNSIGNED_SHORT; m_int_shift = 1; break; // 1 Channel normalized case GL_R8: m_int_format = GL_RED; m_int_type = GL_UNSIGNED_BYTE; m_int_shift = 0; break; // 4 channel normalized case GL_RGBA16: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_SHORT; m_int_shift = 3; break; case GL_RGBA8: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_BYTE; m_int_shift = 2; break; // 4 channel integer case GL_RGBA16I: case GL_RGBA16UI: m_int_format = GL_RGBA_INTEGER; m_int_type = (m_format == GL_R16UI) ? GL_UNSIGNED_SHORT : GL_SHORT; m_int_shift = 3; break; // 4 channel float case GL_RGBA32F: m_int_format = GL_RGBA; m_int_type = GL_FLOAT; m_int_shift = 4; break; case GL_RGBA16F: m_int_format = GL_RGBA; m_int_type = GL_HALF_FLOAT; m_int_shift = 3; break; // Depth buffer case GL_DEPTH32F_STENCIL8: m_int_format = GL_DEPTH_STENCIL; m_int_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; m_int_shift = 3; // 4 bytes for depth + 4 bytes for stencil by texels break; // Backbuffer case 0: m_int_format = 0; m_int_type = 0; m_int_shift = 2; // 4 bytes by texels break; default: m_int_format = 0; m_int_type = 0; m_int_shift = 0; ASSERT(0); } switch (m_type) { case GSTexture::Backbuffer: return; // backbuffer isn't a real texture case GSTexture::Offscreen: // Offscreen is only used to read color. So it only requires 4B by pixel m_local_buffer = (uint8*)_aligned_malloc(m_size.x * m_size.y * 4, 32); break; case GSTexture::Texture: // Only 32 bits input texture will be supported for mipmap m_max_layer = mipmap && m_format == GL_RGBA8 ? (int)log2(std::max(w,h)) : 1; break; case SparseRenderTarget: case SparseDepthStencil: m_sparse = true; break; default: break; } switch (m_format) { case GL_R16UI: case GL_R8: m_sparse &= GLLoader::found_compatible_GL_ARB_sparse_texture2; SetGpuPageSize(GSVector2i(255, 255)); break; case GL_R32UI: case GL_R32I: case GL_RGBA16: case GL_RGBA8: case GL_RGBA16I: case GL_RGBA16UI: case GL_RGBA16F: case 0: m_sparse &= GLLoader::found_compatible_GL_ARB_sparse_texture2; SetGpuPageSize(GSVector2i(127, 127)); break; case GL_RGBA32F: m_sparse &= GLLoader::found_compatible_GL_ARB_sparse_texture2; SetGpuPageSize(GSVector2i(63, 63)); break; case GL_DEPTH32F_STENCIL8: m_sparse &= GLLoader::found_compatible_sparse_depth; SetGpuPageSize(GSVector2i(127, 127)); break; default: ASSERT(0); } // Create a gl object (texture isn't allocated here) glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id); if (m_format == GL_R8) { // Emulate DX behavior, beside it avoid special code in shader to differentiate // palette texture from a GL_RGBA target or a GL_R texture. glTextureParameteri(m_texture_id, GL_TEXTURE_SWIZZLE_A, GL_RED); } if (m_sparse) { GSVector2i old_size = m_size; m_size = RoundUpPage(m_size); if (m_size != old_size) { fprintf(stderr, "Sparse texture size (%dx%d) isn't a multiple of gpu page size (%dx%d)\n", old_size.x, old_size.y, m_gpu_page_size.x, m_gpu_page_size.y); } glTextureParameteri(m_texture_id, GL_TEXTURE_SPARSE_ARB, true); } else { m_committed_size = m_size; } m_mem_usage = (m_committed_size.x * m_committed_size.y) << m_int_shift; static int every_512 = 0; GLState::available_vram -= m_mem_usage; if ((GLState::available_vram < 0) && (every_512 % 512 == 0)) { fprintf(stderr, "Available VRAM is very low (%lld), a crash is expected ! Disable Larger framebuffer or reduce upscaling!\n", GLState::available_vram); every_512++; // Pull emergency break throw std::bad_alloc(); } glTextureStorage2D(m_texture_id, m_max_layer + GL_TEX_LEVEL_0, m_format, m_size.x, m_size.y); }
kit::Texture::Texture(const std::string & filename, kit::Texture::InternalFormat format, uint8_t levels, Type t) : kit::Texture(t) { std::cout << "Loading texture from file \"" << filename.c_str() << "\"" << std::endl; m_filename = filename; if(t == Type::Texture2D) { m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(1); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_THROW(stbi_failure_reason()); } // Set resolution m_resolution = glm::uvec3(x, y, 0); uint8_t mipLevels = levels > 0 ? levels : calculateMipLevels(); // Specify storage and upload data to GPU #ifndef KIT_SHITTY_INTEL glTextureStorage2D(m_glHandle, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); glTextureSubImage2D(m_glHandle, 0, 0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #else bind(); glTexStorage2D(m_type, mipLevels, m_internalFormat, m_resolution.x, m_resolution.y); glTexSubImage2D(m_type, 0, 0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #endif // Free loaded data stbi_image_free(bufferdata); // Set parameters setEdgeSamplingMode(EdgeSamplingMode::Repeat); setMinFilteringMode(m_minFilteringMode); setMagFilteringMode(m_magFilteringMode); setAnisotropicLevel(1.0f); } if(t == Type::Texture3D) { m_internalFormat = format; // Try to load data from file unsigned char* bufferdata; int x, y, n; stbi_set_flip_vertically_on_load(0); bufferdata = stbi_load(filename.c_str(), &x, &y, &n, 4); if (bufferdata == nullptr) { KIT_THROW(stbi_failure_reason()); } if (y != x*x || y%y != 0) { KIT_THROW("Failed to load 3d texture from file, not perfectly cubical"); } // Set resolution m_resolution = glm::uvec3(x, x, x); // Specify storage and upload data to GPU #ifndef KIT_SHITTY_INTEL glTextureStorage3D(m_glHandle, 1, m_internalFormat, x, x, x); glTextureSubImage3D(m_glHandle, 0, 0, 0, 0, x, x, x, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #else returner->bind(); glTexStorage3D(returner->m_type, 1, m_internalFormat, x, x, x); glTexSubImage3D(returner->m_type, 0, 0, 0, 0, x, x, x, GL_RGBA, GL_UNSIGNED_BYTE, bufferdata); #endif // Free loaded data stbi_image_free(bufferdata); setEdgeSamplingMode(EdgeSamplingMode::Repeat); setMinFilteringMode(m_minFilteringMode); setMagFilteringMode(m_magFilteringMode); setAnisotropicLevel(1.0f); } }
GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read) : m_pbo_size(0), m_dirty(false), m_clean(false), m_local_buffer(NULL) { // OpenGL didn't like dimensions of size 0 m_size.x = max(1,w); m_size.y = max(1,h); m_format = format; m_type = type; m_fbo_read = fbo_read; m_texture_id = 0; // Bunch of constant parameter switch (m_format) { // 1 Channel integer case GL_R32UI: case GL_R32I: m_int_format = GL_RED_INTEGER; m_int_type = (m_format == GL_R32UI) ? GL_UNSIGNED_INT : GL_INT; m_int_alignment = 4; m_int_shift = 2; break; case GL_R16UI: m_int_format = GL_RED_INTEGER; m_int_type = GL_UNSIGNED_SHORT; m_int_alignment = 2; m_int_shift = 1; break; // 1 Channel normalized case GL_R8: m_int_format = GL_RED; m_int_type = GL_UNSIGNED_BYTE; m_int_alignment = 1; m_int_shift = 0; break; // 4 channel normalized case GL_RGBA16: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_SHORT; m_int_alignment = 8; m_int_shift = 3; break; case GL_RGBA8: m_int_format = GL_RGBA; m_int_type = GL_UNSIGNED_BYTE; m_int_alignment = 4; m_int_shift = 2; break; // 4 channel integer case GL_RGBA16I: case GL_RGBA16UI: m_int_format = GL_RGBA_INTEGER; m_int_type = (m_format == GL_R16UI) ? GL_UNSIGNED_SHORT : GL_SHORT; m_int_alignment = 8; m_int_shift = 3; break; // 4 channel float case GL_RGBA32F: m_int_format = GL_RGBA; m_int_type = GL_FLOAT; m_int_alignment = 16; m_int_shift = 4; break; case GL_RGBA16F: m_int_format = GL_RGBA; m_int_type = GL_HALF_FLOAT; m_int_alignment = 8; m_int_shift = 3; break; // Special case 0: case GL_DEPTH32F_STENCIL8: // Backbuffer & dss aren't important m_int_format = 0; m_int_type = 0; m_int_alignment = 0; m_int_shift = 0; break; default: ASSERT(0); } // Generate & Allocate the buffer switch (m_type) { case GSTexture::Offscreen: // 8B is the worst case for depth/stencil // FIXME I think it is only used for color. So you can save half of the size m_local_buffer = (uint8*)_aligned_malloc(m_size.x * m_size.y * 4, 32); case GSTexture::Texture: case GSTexture::RenderTarget: case GSTexture::DepthStencil: glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id); glTextureStorage2D(m_texture_id, 1+GL_TEX_LEVEL_0, m_format, m_size.x, m_size.y); if (m_format == GL_R8) { // Emulate DX behavior, beside it avoid special code in shader to differentiate // palette texture from a GL_RGBA target or a GL_R texture. glTextureParameteri(m_texture_id, GL_TEXTURE_SWIZZLE_A, GL_RED); } break; case GSTexture::Backbuffer: default: break; } }
void OGLTexture1D::CreateHWResource(ArrayRef<ElementInitData> init_data, float4 const * clear_value_hint) { KFL_UNUSED(clear_value_hint); GLint glinternalFormat; GLenum glformat; GLenum gltype; OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_); if (sample_count_ <= 1) { uint32_t const pbo_size = mipmap_start_offset_.back() * array_size_; if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glTextureParameteri(texture_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1); glNamedBufferStorage(pbo_, pbo_size, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT); uint32_t const w0 = this->Width(0); if (array_size_ > 1) { glTextureStorage2D(texture_, num_mip_maps_, glinternalFormat, w0, array_size_); } else { glTextureStorage1D(texture_, num_mip_maps_, glinternalFormat, w0); } if (!init_data.empty()) { for (uint32_t array_index = 0; array_index < array_size_; ++ array_index) { for (uint32_t level = 0; level < num_mip_maps_; ++ level) { uint32_t const w = this->Width(level); GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data; if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * block_size; if (array_size_ > 1) { glCompressedTextureSubImage2D(texture_, level, 0, array_index, w, 1, glformat, image_size, data); } else { glCompressedTextureSubImage1D(texture_, level, 0, w, glformat, image_size, data); } } else { if (array_size_ > 1) { glTextureSubImage2D(texture_, level, 0, array_index, w, 1, glformat, gltype, data); } else { glTextureSubImage1D(texture_, level, 0, w, glformat, gltype, data); } } } } } } else { auto& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindTexture(0, target_type_, texture_); glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1); re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_); if (glloader_GL_VERSION_4_4() || glloader_GL_ARB_buffer_storage()) { glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_DYNAMIC_STORAGE_BIT); } else { glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_STREAM_COPY); } re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if (glloader_GL_VERSION_4_2() || glloader_GL_ARB_texture_storage()) { uint32_t const w0 = this->Width(0); if (array_size_ > 1) { glTexStorage2D(target_type_, num_mip_maps_, glinternalFormat, w0, array_size_); } else { glTexStorage1D(target_type_, num_mip_maps_, glinternalFormat, w0); } if (!init_data.empty()) { for (uint32_t array_index = 0; array_index < array_size_; ++ array_index) { for (uint32_t level = 0; level < num_mip_maps_; ++ level) { uint32_t const w = this->Width(level); GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data; if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * block_size; if (array_size_ > 1) { glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1, glformat, image_size, data); } else { glCompressedTexSubImage1D(target_type_, level, 0, w, glformat, image_size, data); } } else { if (array_size_ > 1) { glTexSubImage2D(target_type_, level, 0, array_index, w, 1, glformat, gltype, data); } else { glTexSubImage1D(target_type_, level, 0, w, glformat, gltype, data); } } } } } } else { for (uint32_t array_index = 0; array_index < array_size_; ++ array_index) { for (uint32_t level = 0; level < num_mip_maps_; ++ level) { uint32_t const w = this->Width(level); if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * block_size; if (array_size_ > 1) { if (0 == array_index) { glCompressedTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, image_size * array_size_, nullptr); } if (!init_data.empty()) { glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1, glformat, image_size, init_data[array_index * num_mip_maps_ + level].data); } } else { glCompressedTexImage1D(target_type_, level, glinternalFormat, w, 0, image_size, init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data); } } else { if (array_size_ > 1) { if (0 == array_index) { glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr); } if (!init_data.empty()) { glTexSubImage2D(target_type_, level, 0, array_index, w, 1, glformat, gltype, init_data[array_index * num_mip_maps_ + level].data); } } else { glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype, init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data); } } } } } } } else { glBindRenderbuffer(GL_RENDERBUFFER, texture_); glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1); } hw_res_ready_ = true; }
Image2D::Image2D(std::string const &path) : AbstractTexture(GL_TEXTURE_2D, true, true) { ImageLoader il(path); GLsizei levels = log2(std::max(il.width(), il.height())) + 1; glTextureStorage2D(mId, levels, il.internalFormat(), il.width(), il.height()); glTextureSubImage2D(mId, 0, 0, 0, il.width(), il.height(), il.format(), GL_UNSIGNED_BYTE, il.data()); glGenerateTextureMipmap(mId); makeResident(); }