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); }
// load texture void loadTexture(unsigned int texId, unsigned int *texture, short *size, bool mipmap) { // load texture for rendering glBindTexture(GL_TEXTURE_2D, texId); if (mipmap) { int i; ImBuf *ibuf; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ibuf = IMB_allocFromBuffer(texture, NULL, size[0], size[1]); 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); } IMB_freeImBuf(ibuf); } 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, size[0], size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); }
void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap) { if (!GPU_non_power_of_two_support() && (!is_power_of_2_i(x) || !is_power_of_2_i(y)) ) { InitNonPow2Tex(pix, x,y,mipmap); return; } glBindTexture(GL_TEXTURE_2D, mTexture ); if ( mipmap ) { int i; ImBuf *ibuf; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ibuf = IMB_allocFromBuffer(pix, NULL, x, y); 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); } IMB_freeImBuf(ibuf); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix ); } 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); }
// refresh texture static PyObject *Texture_refresh(Texture *self, PyObject *args) { // get parameter - refresh source PyObject *param; double ts = -1.0; if (!PyArg_ParseTuple(args, "O|d:refresh", ¶m, &ts) || !PyBool_Check(param)) { // report error PyErr_SetString(PyExc_TypeError, "The value must be a bool"); return NULL; } // some trick here: we are in the business of loading a texture, // no use to do it if we are still in the same rendering frame. // We find this out by looking at the engine current clock time KX_KetsjiEngine* engine = KX_GetActiveEngine(); if (engine->GetClockTime() != self->m_lastClock) { self->m_lastClock = engine->GetClockTime(); // set source refresh bool refreshSource = (param == Py_True); // try to proces texture from source try { // if source is available if (self->m_source != NULL) { // check texture code if (!self->m_orgSaved) { self->m_orgSaved = true; // save original image code if (self->m_useMatTexture) self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex); else { // Swapping will work only if the GPU has already loaded the image. // If not, it will delete and overwrite our texture on next render. // To avoid that, we acquire the image buffer now. // WARNING: GPU has a ImageUser to pass, we don't. Using NULL // works on image file, not necessarily on other type of image. self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL); self->m_orgTex = self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D]; self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D] = self->m_actTex; } } // get texture unsigned int * texture = self->m_source->m_image->getImage(self->m_actTex, ts); // if texture is available if (texture != NULL) { // get texture size short * orgSize = self->m_source->m_image->getSize(); // calc scaled sizes short size[2]; if (GLEW_ARB_texture_non_power_of_two) { size[0] = orgSize[0]; size[1] = orgSize[1]; } else { size[0] = ImageBase::calcSize(orgSize[0]); size[1] = ImageBase::calcSize(orgSize[1]); } // scale texture if needed if (size[0] != orgSize[0] || size[1] != orgSize[1]) { IMB_freeImBuf(self->m_scaledImBuf); self->m_scaledImBuf = IMB_allocFromBuffer(texture, NULL, orgSize[0], orgSize[1]); IMB_scaleImBuf(self->m_scaledImBuf, size[0], size[1]); // use scaled image instead original texture = self->m_scaledImBuf->rect; } // load texture for rendering loadTexture(self->m_actTex, texture, size, self->m_mipmap); } // refresh texture source, if required if (refreshSource) { self->m_source->m_image->refresh(); } } } CATCH_EXCP; }