void Texture2D::writeData(const unsigned char *data) { GLuint internalFormat; GLuint format; switch (_information.format) { case Pixmap::Information::Format::ALPHA: internalFormat = GL_ALPHA; format = GL_ALPHA; break; case Pixmap::Information::Format::RGB: internalFormat = GL_RGB; format = GL_BGR; break; case Pixmap::Information::Format::RGBA: internalFormat = GL_RGBA; format = GL_BGRA; break; default: //This should never be reached and will probably be removed in release builds //(not that it would cause a performance problem anyway) std::stringstream err; err << "Pixmap format (" << _information.format << ") is not supported by Texture2D"; throw std::exception(err.str().data()); } glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, _information.size.x, _information.size.y, 0, format, GL_UNSIGNED_BYTE, data); generateMipmap(); }
//---------------------------------------------------------- void ofTexture::loadData(const void * data, int w, int h, int glFormat, int glType){ if(w > texData.tex_w || h > texData.tex_h) { allocate(w, h, glFormat, glFormat, glType); } // compute new tex co-ords based on the ratio of data's w, h to texture w,h; #ifndef TARGET_OPENGLES if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ texData.tex_t = w; texData.tex_u = h; } else #endif { texData.tex_t = (float)(w) / (float)texData.tex_w; texData.tex_u = (float)(h) / (float)texData.tex_h; } // bind texture glBindTexture(texData.textureTarget, (GLuint) texData.textureID); //update the texture image: glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, glFormat, glType, data); // unbind texture target by binding 0 glBindTexture(texData.textureTarget, 0); if (bWantsMipmap) { // auto-generate mipmap, since this ofTexture wants us to. generateMipmap(); } }
/*----------------------------------------------------------------------------*/ bool Texture1d::reload() { if (fileName_) { // not a render texture GLsizei width, height, pixelSize; GLint format; GLenum srcDataFormat, srcDataType; void *srcData = loadRawData(fileName_, &width, &height, &pixelSize, &format, &srcDataFormat, &srcDataType); if (!srcData) return false; // (re) upload to texture object: bind(); // must ensure texture is bound for upload operation! // use SRGB if necessary: if (checkOptionMask(TEX_SRGB)) { if (format == GL_RGB) format = GL_SRGB; else if (format == GL_SRGB_ALPHA) format = GL_SRGB_ALPHA; } /*if (!proxy(format, width, height, checkOptionMask(TEX_MIPMAP))) { oogl::logEvent("Error: could not create texture %ux%u %s", width, height, oogl::getEnumString(format)); freeRawData(srcData); return false; }*/ image(0, format, width, srcDataFormat, srcDataType, srcData); freeRawData(srcData); if (checkOptionMask(TEX_MIPMAP)) generateMipmap(); } return true; }
void Texture2D::loadImage(const char * path, GLint index) { assert(index >= 0 && index <= 31); int channel; activeTexture(index); bind(index); unsigned char * image = SOIL_load_image(path, &width[index], &height[index], &channel, SOIL_LOAD_RGBA); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width[index], height[index], 0, GL_RGBA, GL_UNSIGNED_BYTE, image); generateMipmap(index); SOIL_free_image_data(image); unbind(); }
std::shared_ptr<ge::gl::Texture>createFontTexture(){ const uint32_t w=ge::res::font::width; const uint32_t h=ge::res::font::height; uint8_t bytes[w*h]; auto result = std::make_shared<ge::gl::Texture>(GL_TEXTURE_2D,GL_R8,0,w,h); for(uint32_t i=0;i<w*h/8;++i) for(size_t k=0;k<8;++k) bytes[i*8+k]=255*((ge::res::font::data[i]>>k)&0x1); result->setData2D(bytes,GL_RED,GL_UNSIGNED_BYTE,0,0,0,w,h,w); result->generateMipmap(); result->texParameteri(GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); result->texParameteri(GL_TEXTURE_MAG_FILTER,GL_LINEAR); result->texParameteri(GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); result->texParameteri(GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); return result; }
//---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ int screenHeight = ofGetViewportHeight(); // this call fails if we are in a different viewport or FBO: ofGetHeight(); y = screenHeight - y; y -= h; // top, bottom issues texData.bFlipTexture = true; if ( w > texData.tex_w || h > texData.tex_h) { ofLogError("ofTexture") << "loadScreenData(): " << w << "x" << h << " image data too big for " << texData.tex_w << "x " << texData.tex_h << " allocated texture, not uploading"; return; } //update our size with the new dimensions - this should be the same size or smaller than the allocated texture size texData.width = w; texData.height = h; //texData.glType = GL_RGB; // this was probably a bug, because you might be resetting the glType to something other than what the texture was created for //compute new tex co-ords based on the ratio of data's w, h to texture w,h; #ifndef TARGET_OPENGLES // DAMIAN if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ texData.tex_t = (float)(w); texData.tex_u = (float)(h); } else #endif { texData.tex_t = (float)(w) / (float)texData.tex_w; texData.tex_u = (float)(h) / (float)texData.tex_h; } enableTextureTarget(0); glBindTexture(texData.textureTarget, (GLuint)texData.textureID); glCopyTexSubImage2D(texData.textureTarget, 0,0,0,x,y,w,h); disableTextureTarget(0); if (bWantsMipmap) { generateMipmap(); } }
std::shared_ptr<kit::Texture> kit::Texture::load(const std::string & name, bool sRGB) { std::string key = name + (sRGB ? ".sRGB" : ".linear"); InternalFormat format = sRGB ? SRGB8Alpha8 : RGBA8; std::string path = kit::getDataDirectory() + "textures/" + name; auto & entry = m_cache[key]; auto sharedEntry = entry.lock(); if(!sharedEntry) { entry = sharedEntry = std::make_shared<kit::Texture>(path, format); sharedEntry->setMinFilteringMode(FilteringMode::LinearMipmapLinear); sharedEntry->setMagFilteringMode(FilteringMode::Linear); sharedEntry->setAnisotropicLevel(4.0f); sharedEntry->generateMipmap(); } return sharedEntry; }
//---------------------------------------------------------- void ofTexture::loadScreenData(int x, int y, int w, int h){ // TODO: this should go into the renderers so it // doesn't depend on global calls int screenHeight = ofGetViewportHeight(); y = screenHeight - y; y -= h; // top, bottom issues texData.bFlipTexture = true; if ( w > texData.tex_w || h > texData.tex_h) { ofLogError("ofTexture") << "loadScreenData(): " << w << "x" << h << " image data too big for " << texData.tex_w << "x " << texData.tex_h << " allocated texture, not uploading"; return; } //update our size with the new dimensions - this should be the same size or smaller than the allocated texture size texData.width = w; texData.height = h; //compute new tex co-ords based on the ratio of data's w, h to texture w,h; #ifndef TARGET_OPENGLES // DAMIAN if (texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB){ texData.tex_t = (float)(w); texData.tex_u = (float)(h); } else #endif { texData.tex_t = (float)(w) / (float)texData.tex_w; texData.tex_u = (float)(h) / (float)texData.tex_h; } glBindTexture(texData.textureTarget,texData.textureID); glCopyTexSubImage2D(texData.textureTarget, 0,0,0,x,y,w,h); glBindTexture(texData.textureTarget,0); if (bWantsMipmap) { generateMipmap(); } }
void gle::Texture::setData(const char* data, GLuint width, GLuint height, Target target, bool bindTexture) { if (bindTexture) bind(); if (width && height) { _width = width; _height = height; } glTexImage2D(target, // Texture type 0, // Level of detail (0 = max) _internalFormat, // Internal format _width, // Width _height, // Height 0, // This value must be 0 _internalFormat == Depth ? GL_DEPTH_COMPONENT : GL_RGBA, // Format of the pixel datas GL_UNSIGNED_BYTE, // Data type of the pixel datas data); gle::Exception::CheckOpenGLError("Texture::setData"); generateMipmap(); if (bindTexture) unbind(); }
bool D3D9texture::loadFile2D() { D3D9_SCOPELOCK; HRESULT hr; const byte_t* data; int flags = 0; if (!(m_initFlags.isSet(IF_NoMipmap))) flags |= Image::Mipmap; flags |= Image::ExpandAlpha; std::auto_ptr<Image> imagefile(new Image); if (!imagefile->loadFile(m_name, flags)) { // Debugf("D3D9texture::loadFile2D: can't find image file for %s\n", m_name.c_str()); return false; } m_width = imagefile->getWidth(); m_height = imagefile->getHeight(); // mDesc.format = imagefile->getFormat(); if (!Math::isPowerOfTwo(m_width) || !Math::isPowerOfTwo(m_height)) { // if (!(mDesc.flags & TexFlag_allowNPOT)) Errorf("GLtexture::loadFile2D: texture %s size isn't power of two", m_name.c_str()); // else // Debugf("GLtexture::loadFile2D: texture %s size isn't power of two\n", mDesc.name.c_str()); } m_format = imagefile->getFormat(); D3DFORMAT d3dformat; trTexFormat(imagefile->getFormat(), d3dformat); DWORD d3dusage = 0; int mipdown = image_mip->getInteger(); if (m_initFlags.isSet(IF_NoMipmap) || imagefile->getNumMipmapLevels() <= 1) { m_isMipmaped = false; mipdown = 0; } else { m_isMipmaped = true; mipdown = Math::clamp(mipdown, 0, imagefile->getNumMipmapLevels()-1); m_width >>= mipdown; m_height >>= mipdown; if (m_width < 1) m_width = 1; if (m_height < 1) m_height = 1; } // m_initFlags = 0; if (m_initFlags.isSet(Texture::IF_RenderTarget)) { Errorf("Can't load render target from a file"); } if (m_initFlags.isSet(Texture::IF_AutoGenMipmap)) { d3dusage |= D3DUSAGE_AUTOGENMIPMAP; m_isMipmaped = true; m_hardwareGenMipmap = checkIfSupportHardwareMipmapGeneration(d3dformat, d3dusage); if (!m_hardwareGenMipmap) { d3dusage &= ~D3DUSAGE_AUTOGENMIPMAP; } } if (m_object == 0) { V(d3d9Device->CreateTexture(m_width, m_height, !m_isMipmaped, d3dusage, d3dformat, D3DPOOL_MANAGED, &m_object, 0)); } int width, height; width = m_width; height = m_height; for (DWORD i = 0; i < m_object->GetLevelCount(); i++) { if (i + mipdown >= (DWORD)imagefile->getNumMipmapLevels()) { // if no image for this level, break break; } uint_t datasize = imagefile->getFormat().calculateDataSize(width, height); m_videoMemoryUsed += datasize; data = imagefile->getData(i + mipdown); #if 0 LPDIRECT3DSURFACE9 surface; V(m_object->GetSurfaceLevel(i, &surface)); D3DXLoadSurfaceFromMemory(surface, 0, 0, data, d3dformat, pitch, 0, rect, D3DX_FILTER_NONE, 0); #else D3DLOCKED_RECT lockedRect; V(m_object->LockRect(i, &lockedRect, 0, 0)); int mypitch = m_format.calculateDataSize(width, 1); if (mypitch != lockedRect.Pitch) { Errorf("mypitch != lockedRect.Pitch"); } memcpy(lockedRect.pBits, data, datasize); V(m_object->UnlockRect(i)); #endif width >>= 1; height >>= 1; if (width < 1) width = 1; if (height < 1) height = 1; if (m_initFlags.isSet(Texture::IF_AutoGenMipmap)) { // break; } } if (m_initFlags.isSet(Texture::IF_AutoGenMipmap)) { generateMipmap(); } if (m_isMipmaped) { setFilterMode(FM_Trilinear); } else { setFilterMode(FM_Linear); } setClampMode(CM_Repeat); setPrivateData(); g_statistic->addValue(stat_textureMemory, m_videoMemoryUsed); return true; }
// cocos2d-x doesn't support Samplers yet. But will be added soon bool Material::parseSampler(GLProgramState* glProgramState, Properties* samplerProperties) { CCASSERT(samplerProperties->getId(), "Sampler must have an id. The id is the uniform name"); // required auto filename = samplerProperties->getString("path"); auto texture = Director::getInstance()->getTextureCache()->addImage(filename); if (!texture) { CCLOG("Invalid filepath"); return false; } // optionals { Texture2D::TexParams texParams; // mipmap bool usemipmap = false; const char* mipmap = getOptionalString(samplerProperties, "mipmap", "false"); if (mipmap && strcasecmp(mipmap, "true")==0) { texture->generateMipmap(); usemipmap = true; } // valid options: REPEAT, CLAMP const char* wrapS = getOptionalString(samplerProperties, "wrapS", "CLAMP_TO_EDGE"); if (strcasecmp(wrapS, "REPEAT")==0) texParams.wrapS = GL_REPEAT; else if(strcasecmp(wrapS, "CLAMP_TO_EDGE")==0) texParams.wrapS = GL_CLAMP_TO_EDGE; else CCLOG("Invalid wrapS: %s", wrapS); // valid options: REPEAT, CLAMP const char* wrapT = getOptionalString(samplerProperties, "wrapT", "CLAMP_TO_EDGE"); if (strcasecmp(wrapT, "REPEAT")==0) texParams.wrapT = GL_REPEAT; else if(strcasecmp(wrapT, "CLAMP_TO_EDGE")==0) texParams.wrapT = GL_CLAMP_TO_EDGE; else CCLOG("Invalid wrapT: %s", wrapT); // valid options: NEAREST, LINEAR, NEAREST_MIPMAP_NEAREST, LINEAR_MIPMAP_NEAREST, NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_LINEAR const char* minFilter = getOptionalString(samplerProperties, "minFilter", usemipmap ? "LINEAR_MIPMAP_NEAREST" : "LINEAR"); if (strcasecmp(minFilter, "NEAREST")==0) texParams.minFilter = GL_NEAREST; else if(strcasecmp(minFilter, "LINEAR")==0) texParams.minFilter = GL_LINEAR; else if(strcasecmp(minFilter, "NEAREST_MIPMAP_NEAREST")==0) texParams.minFilter = GL_NEAREST_MIPMAP_NEAREST; else if(strcasecmp(minFilter, "LINEAR_MIPMAP_NEAREST")==0) texParams.minFilter = GL_LINEAR_MIPMAP_NEAREST; else if(strcasecmp(minFilter, "NEAREST_MIPMAP_LINEAR")==0) texParams.minFilter = GL_NEAREST_MIPMAP_LINEAR; else if(strcasecmp(minFilter, "LINEAR_MIPMAP_LINEAR")==0) texParams.minFilter = GL_LINEAR_MIPMAP_LINEAR; else CCLOG("Invalid minFilter: %s", minFilter); // valid options: NEAREST, LINEAR const char* magFilter = getOptionalString(samplerProperties, "magFilter", "LINEAR"); if (strcasecmp(magFilter, "NEAREST")==0) texParams.magFilter = GL_NEAREST; else if(strcasecmp(magFilter, "LINEAR")==0) texParams.magFilter = GL_LINEAR; else CCLOG("Invalid magFilter: %s", magFilter); texture->setTexParameters(texParams); } glProgramState->setUniformTexture(samplerProperties->getId(), texture); return true; }