void Texture2D::init(int w, int h, TextureInternalFormat tf, TextureFormat f, PixelType t, const Parameters ¶ms, const Buffer::Parameters &s, const Buffer &pixels) { Texture::init(tf, params); this->w = w; this->h = h; pixels.bind(GL_PIXEL_UNPACK_BUFFER); if (isCompressed() && s.compressedSize() > 0) { glCompressedTexImage2D(textureTarget, 0, getTextureInternalFormat(internalFormat), w, h, 0, s.compressedSize(), pixels.data(0)); } else { s.set(); glTexImage2D(textureTarget, 0, getTextureInternalFormat(internalFormat), w, h, 0, getTextureFormat(f), getPixelType(t), pixels.data(0)); s.unset(); } pixels.unbind(GL_PIXEL_UNPACK_BUFFER); generateMipMap(); if (FrameBuffer::getError() != 0) { throw exception(); } }
void Texture2D::setImage(int w, int h, TextureFormat f, PixelType t, const Buffer &pixels) { this->w = w; this->h = h; bindToTextureUnit(); pixels.bind(GL_PIXEL_UNPACK_BUFFER); glTexImage2D(textureTarget, 0, getTextureInternalFormat(internalFormat), w, h, 0, getTextureFormat(f), getPixelType(t), pixels.data(0)); pixels.unbind(GL_PIXEL_UNPACK_BUFFER); generateMipMap(); assert(FrameBuffer::getError() == GL_NO_ERROR); }
void TextureRectangle::init(int w, int h, TextureInternalFormat tf, TextureFormat f, PixelType t, const Parameters ¶ms, const Buffer::Parameters &s, const Buffer &pixels) { Texture::init(tf, params); this->w = w; this->h = h; pixels.bind(GL_PIXEL_UNPACK_BUFFER); bool needToGenerateMipmaps = true; if (isCompressed() && s.compressedSize() > 0) { glCompressedTexImage2D(textureTarget, 0, getTextureInternalFormat(internalFormat), w, h, 0, s.compressedSize(), pixels.data(0)); } else { s.set(); glTexImage2D(textureTarget, 0, getTextureInternalFormat(internalFormat), w, h, 0, getTextureFormat(f), getPixelType(t), pixels.data(0)); s.unset(); GLsizei size = s.compressedSize(); // should work because size is retrieved from file descriptor. int pixelSize = getFormatSize(f, t); if (size > w * h * pixelSize) { // get the other levels from the same buffer int offset = w * h * pixelSize; int level = 0; int wl = w; int hl = h; while (wl % 2 == 0 && hl % 2 == 0 && size - offset >= (wl * hl / 4) * pixelSize) { level += 1; wl = wl / 2; hl = hl / 2; glTexImage2D(textureTarget, level, getTextureInternalFormat(internalFormat), wl, hl, 0, getTextureFormat(f), getPixelType(t), pixels.data(offset)); offset += wl * hl * pixelSize; needToGenerateMipmaps = false; } this->params.lodMax(clamp(params.lodMax(), GLfloat(0.0f), GLfloat(level))); } } pixels.unbind(GL_PIXEL_UNPACK_BUFFER); if (needToGenerateMipmaps) { generateMipMap(); } if (FrameBuffer::getError() != 0) { throw exception(); } }
void TextureCube::init(int w, int h, TextureInternalFormat tf, TextureFormat f, PixelType t, const Parameters ¶ms, Buffer::Parameters s[6], ptr<Buffer> pixels[6]) { Texture::init(tf, params); this->w = w; this->h = h; const GLenum FACES[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; if (isCompressed()) { for (int i = 0; i < 6; ++i) { pixels[i]->bind(GL_PIXEL_UNPACK_BUFFER); if (s[i].compressedSize() > 0) { glCompressedTexImage2D(FACES[i], 0, getTextureInternalFormat(internalFormat), w, h, 0, s[i].compressedSize(), pixels[i]->data(0)); } else { s[i].set(); glTexImage2D(FACES[i], 0, getTextureInternalFormat(internalFormat), w, h, 0, getTextureFormat(f), getPixelType(t), pixels[i]->data(0)); s[i].unset(); } pixels[i]->unbind(GL_PIXEL_UNPACK_BUFFER); } } else { for (int i = 0; i < 6; ++i) { pixels[i]->bind(GL_PIXEL_UNPACK_BUFFER); s[i].set(); glTexImage2D(FACES[i], 0, getTextureInternalFormat(internalFormat), w, h, 0, getTextureFormat(f), getPixelType(t), pixels[i]->data(0)); s[i].unset(); pixels[i]->unbind(GL_PIXEL_UNPACK_BUFFER); } } generateMipMap(); if (FrameBuffer::getError() != 0) { throw exception(); } }
int LRGBPtm::loadData(FILE* file, int width, int height, int basisTerm, bool urti, CallBackPos * cb,const QString& text) { w = width; h = height; if (!urti) { //Gets scale value bool eof, error; QString str = getLine(file, &eof); if (eof) return -1; QStringList list = str.split(' ', QString::SkipEmptyParts); if (list.size() != 6) return -1; for (int i = 0; i < 6; i++) { scale[i] = list[i].toDouble(&error); if (!error) return -1; } //Gets bias value str = getLine(file, &eof); if (eof) return -1; list = str.split(' ', QString::SkipEmptyParts); if (list.size() != 6) return -1; for (int i = 0; i < 6; i++) { bias[i] = list[i].toInt(&error); if (!error) return -1; } } else { } //Allocates array for polynomial coefficients and rgb components PTMCoefficient* coeffPtr = new PTMCoefficient[w*h]; unsigned char* rgbPtr = new unsigned char[w*h*3]; int offset; unsigned char c; //Reads coefficient and rgb components from file for (int y = h - 1; y >= 0; y--) { if (cb != NULL && (y % 50 == 0))(*cb)((h - y) * 40 / h, text); for (int x = 0; x < w; x++) { offset = y * w + x; for (int i = 0; i < 6; i++) { if(feof(file)) return -1; fread(&c, sizeof(unsigned char), 1, file); coeffPtr[offset][i] = static_cast<int>((c - bias[i])*scale[i]); } if (version == "PTM_1.1") { for (int i = 0; i < 3; i++) { if (feof(file)) return -1; fread(&c, sizeof(unsigned char), 1, file); rgbPtr[offset*3 + i] = c; } } } } if (version == "PTM_1.2") { for (int y = h - 1; y >= 0; y--) { if (cb != NULL && (h-y)%100==0) (*cb)(40 + (h - y) * 10 / h , "Loading LRGB PTM..."); for (int x = 0; x < w; x++) { offset = y * w + x; for (int i = 0; i < 3; i++) { if (feof(file)) return -1; fread(&c, sizeof(unsigned char), 1, file); rgbPtr[offset*3 + i] = c; } } } } fclose(file); mipMapSize[0] = QSize(w, h); coefficients.setLevel(coeffPtr, w*h, 0); rgb.setLevel(rgbPtr, w*h*3, 0); // Computes mip-mapping and normals. if (cb != NULL) (*cb)(55, "Mip mapping generation..."); generateMipMap(1, w, h, cb, 55, 20); calculateNormals(normals, coefficients, true, cb, 75, 20); return 0; }
int RGBPtm::loadData(FILE* file, int width, int height, int basisTerm, bool urti, CallBackPos * cb,const QString& text) { w = width; h = height; if (!urti) { //Gets scale value bool eof, error; QString str = getLine(file, &eof); if (eof) return -1; QStringList list = str.split(' ', QString::SkipEmptyParts); if (list.size() != 6) return -1; for (int i = 0; i < 6; i++) { scale[i] = list[i].toDouble(&error); if (!error) return -1; } //Gets bias value str = getLine(file, &eof); if (eof) return -1; list = str.split(' ', QString::SkipEmptyParts); if (list.size() != basisTerm) return -1; for (int i = 0; i < basisTerm; i++) { bias[i] = list[i].toInt(&error); if (!error) return -1; } } else { } //Allocates array for polynomial coefficients PTMCoefficient* redCoeff = new PTMCoefficient[w*h]; PTMCoefficient* greenCoeff = new PTMCoefficient[w*h]; PTMCoefficient* blueCoeff = new PTMCoefficient[w*h]; //Reads polynomial coefficients int offset; unsigned char c; for (int j = 0; j < 3; j++) { for (int y = h - 1; y >= 0; y--) { if (cb != NULL && (y % 50) == 0) (*cb)(15*j + (h - y) * 15 / h, text); for (int x = 0; x < w; x++) { offset = y * w + x; for (int i = 0; i < basisTerm; i++) { if(feof(file)) return -1; fread(&c, sizeof(unsigned char), 1, file); if (j == 0) redCoeff[offset][i] = static_cast<int>((c - bias[i])*scale[i]); else if (j == 1) greenCoeff[offset][i] = static_cast<int>((c - bias[i])*scale[i]); else blueCoeff[offset][i] = static_cast<int>((c - bias[i])*scale[i]); } } } } fclose(file); // Computes mip-mapping-level. mipMapSize[0] = QSize(w, h); redCoefficients.setLevel(redCoeff, w*h, 0); greenCoefficients.setLevel(greenCoeff, w*h, 0); blueCoefficients.setLevel(blueCoeff, w*h, 0); if (cb != NULL) (*cb)(45, "Mip mapping generation..."); generateMipMap(1, w, h, cb, 45, 15); // Computes the normals calculateNormals(normals, redCoefficients, true, cb, 60, 10); calculateNormals(normals, greenCoefficients, false, cb, 70, 10); calculateNormals(normals, blueCoefficients, false, cb, 80, 10); for(int level = 0; level < MIP_MAPPING_LEVELS; level++) { int lenght = normals.getLevelLenght(level); vcg::Point3f* tempNormals = new vcg::Point3f[lenght]; memcpy(tempNormals, normals.getLevel(level), sizeof(vcg::Point3f)*lenght); int th_id = 0; #pragma omp parallel for for (int i = 0; i < lenght; i++) { th_id = omp_get_thread_num(); if (th_id == 0) { if (cb != NULL && i%500 == 0) (*cb)(90 + level*2.5 + 2.5 * i / lenght, "Normals generation..."); } tempNormals[i] /= 3; tempNormals[i].Normalize(); } normals.setLevel(tempNormals, lenght, level); } return 0; }
BBTexture* BBTextureStore_load (BBTextureStore* texStore, const char* name, int startLodLevel) { BBTexture* texture = NULL; BBTga* tga[MAX_MIPMAPS]; char filename[256]; GLsizei level = 0; GLboolean bottomOk = GL_TRUE; GLsizei width = 1; GLsizei height = 1; BB_ASSERT(texStore && name); memset(tga, 0, sizeof(BBTga*) * MAX_MIPMAPS); texture = BBTextureStore_find(texStore, name, GL_TEXTURE_2D); if (texture) return texture; if (strlen(name) > 240) { #ifdef BB_DEVEL printf("Error: Filename too long \"%s\"\n", name); #endif return NULL; } while (width >= 1 || height >= 1) { if (width < 1) width = 1; if (height < 1) height = 1; strcpy(filename, name); catenateMipMapFilename(filename, level + startLodLevel); strcat(filename, ".tga"); tga[level] = BBTga_load(filename); if (!tga[level]) { if (level == 0) { bottomOk = GL_FALSE; break; } } else { if (level == 0) { width = tga[0]->width; height = tga[0]->height; } else { if (tga[level]->width != width || tga[level]->height != height || tga[level]->bits != tga[0]->bits) { BBTga_destroy(tga[level]); tga[level] = NULL; } } } width >>= 1; height >>= 1; level++; BB_ASSERT(level < MAX_MIPMAPS); } if (bottomOk) { void* dataList[MAX_MIPMAPS]; GLboolean generated[MAX_MIPMAPS]; GLsizei i; GLboolean errorsInMipMaps = GL_FALSE; memset(dataList, 0, sizeof(void*) * MAX_MIPMAPS); memset(generated, 0, sizeof(GLboolean) * MAX_MIPMAPS); for (i = 0; i < level; i++) { if (tga[i] && tga[i]->data) { dataList[i] = tga[i]->data; } else { GLsizei bpp = tga[0]->bits == 24 ? 3 : 4; GLsizei width = tga[0]->width >> i; GLsizei height = tga[0]->height >> i; BB_ASSERT(i != 0 || (width < 1 && height < 1)); if (width < 1) width = 1; if (height < 1) height = 1; dataList[i] = (GLubyte*)malloc(width * height * bpp * sizeof(GLubyte)); if (dataList[i]) { generateMipMap(tga[0]->data, tga[0]->width, tga[0]->height, tga[0]->bits == 24 ? GL_RGB : GL_RGBA, i, dataList[i]); { strcpy(filename, name); catenateMipMapFilename(filename, i); strcat(filename, ".tga"); if (BBTga_save(filename, width, height, tga[0]->bits == 24 ? 3 : 4, dataList[i], GL_TRUE)) { #ifdef BB_DEVEL printf("Generated mipmap level %d for texture %s.\n", i, name); #endif } else { #ifdef BB_DEVEL printf("Failed to save mipmap level %d for texture %s.\n", i, name); #endif } } generated[i] = GL_TRUE; } else { errorsInMipMaps = GL_TRUE; break; } } } if (!errorsInMipMaps) texture = BBTexture_create(name, tga[0]->width, tga[0]->height, GL_TEXTURE_2D, tga[0]->bits == 24 ? GL_RGB : GL_RGBA, (const void **)dataList); for (i = 0; i < level; i++) { if (generated[i]) free(dataList[i]); } } while (level-- > 0) { if (tga[level]) { BBTga_destroy(tga[level]); tga[level] = NULL; } } if (texture) { texture->next = texStore->firstTexture; texStore->firstTexture = texture; } return texture; }