void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) { int nx= power_of_2_min_i(x); int ny= power_of_2_min_i(y); ImBuf *ibuf = IMB_allocFromBuffer(pix, NULL, x, y); IMB_scaleImBuf(ibuf, nx, ny); glBindTexture(GL_TEXTURE_2D, mTexture ); if ( mipmap ) { int i; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); IMB_makemipmap(ibuf, true); for (i = 0; i < ibuf->miptot; i++) { ImBuf *mip = IMB_getmipmap(ibuf, i); glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect); } } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect ); } if (GLEW_EXT_texture_filter_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic()); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); IMB_freeImBuf(ibuf); }
static void split_width(int x, int n, int *splitx, int *nx) { int a, newnx, waste; /* if already power of two just use it */ if (is_power_of_2_i(x)) { splitx[0] = x; (*nx)++; return; } if (n == 1) { /* last part, we have to go larger */ splitx[0] = power_of_2_max_i(x); (*nx)++; } else { /* two or more parts to go, use smaller part */ splitx[0] = power_of_2_min_i(x); newnx = ++(*nx); split_width(x - splitx[0], n - 1, splitx + 1, &newnx); for (waste = 0, a = 0; a < n; a++) waste += splitx[a]; /* if we waste more space or use the same amount, * revert deeper splits and just use larger */ if (waste >= power_of_2_max_i(x)) { splitx[0] = power_of_2_max_i(x); memset(splitx + 1, 0, sizeof(int) * (n - 1)); } else *nx = newnx; } }
int BL_Texture::GetPow2(int n) { if (!is_power_of_2_i(n)) n = power_of_2_min_i(n); return n; }