Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Coumans <blender@erwincoumans.com>2006-01-08 12:37:15 +0300
committerErwin Coumans <blender@erwincoumans.com>2006-01-08 12:37:15 +0300
commitc94455c14d28221f6e05f33ba42e23a5d3245a28 (patch)
tree733dfaccbbcd71cf66e2d33b1868f64f78189eeb /source/gameengine/Ketsji/BL_Texture.cpp
parent88a8508b347dda050557e72dfad105023e5095aa (diff)
more linux game engine work. hopefully works now!
Diffstat (limited to 'source/gameengine/Ketsji/BL_Texture.cpp')
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
new file mode 100644
index 00000000000..f03bfffc8ec
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -0,0 +1,389 @@
+// ------------------------------------
+#ifdef WIN32
+#include <windows.h>
+#endif // WIN32
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+
+#include <iostream>
+
+#include "BL_Material.h"
+#include "BL_Texture.h"
+#include "MT_assert.h"
+
+#include "DNA_texture_types.h"
+#include "DNA_image_types.h"
+#include "IMB_imbuf_types.h"
+#include "BKE_image.h"
+//#include "IMB_imbuf.h"
+#include "BLI_blenlib.h"
+
+#include "RAS_GLExtensionManager.h"
+using namespace bgl;
+
+#define spit(x) std::cout << x << std::endl;
+
+#include "MEM_guardedalloc.h"
+
+
+
+extern "C" {
+ // envmaps
+ #include "IMB_imbuf.h"
+ void my_envmap_split_ima(EnvMap *env);
+ void my_free_envmapdata(EnvMap *env);
+}
+
+// (n&(n-1)) zeros the least significant bit of n
+static int is_pow2(int num) {
+ return ((num)&(num-1))==0;
+}
+static int smaller_pow2(int num) {
+ while (!is_pow2(num))
+ num= num&(num-1);
+ return num;
+}
+
+
+
+BL_Texture::BL_Texture()
+: mTexture(0),
+ mError(0),
+ mOk(0),
+ mNeedsDeleted(0),
+ mType(0),
+ mName("")
+{
+ // --
+}
+
+BL_Texture::~BL_Texture()
+{
+ // --
+}
+
+void BL_Texture::DeleteTex()
+{
+ if( mNeedsDeleted ) {
+ glDeleteTextures(1, (GLuint*)&(*mTexture));
+ mNeedsDeleted = 0;
+ mOk = 0;
+ }
+}
+
+
+bool BL_Texture::InitFromImage( Image *img, bool mipmap)
+{
+ if(!img || img->ok==0 ) {
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ if( img->ibuf==0 ) {
+ load_image(img, IB_rect, "", 0);
+ if(img->ibuf==0) {
+ img->ok = 0;
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ }
+ mTexture = &img->bindcode;
+ mName = img->id.name;
+ mType = BL_TEX2D;
+
+ // smoke em if we got em
+ if (*mTexture != 0) {
+ glBindTexture(GL_TEXTURE_2D, *mTexture );
+ Validate();
+ return mOk;
+ }
+ glGenTextures(1, (GLuint*)mTexture);
+ InitGLTex(img->ibuf->rect, img->ibuf->x, img->ibuf->y, mipmap);
+ Validate();
+ return mOk;
+}
+
+void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
+{
+ if (!is_pow2(x) || !is_pow2(y) ) {
+ InitNonPow2Tex(pix, x,y,mipmap);
+ return;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, *mTexture );
+ if( mipmap ) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, x, y, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+ }
+ 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, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+ }
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+
+void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
+{
+ int nx= smaller_pow2(x);
+ int ny= smaller_pow2(y);
+
+ unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int));
+
+ gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels);
+ glBindTexture(GL_TEXTURE_2D, *mTexture );
+
+ if( mipmap ) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+ }
+ 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, newPixels );
+ }
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ free(newPixels);
+}
+
+
+bool BL_Texture::InitCubeMap( EnvMap *cubemap )
+{
+#ifdef GL_ARB_texture_cube_map
+ if(!RAS_EXT_support._ARB_texture_cube_map) {
+ spit("cubemaps not supported");
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+
+ else if(!cubemap || cubemap->ima->ok==0 ) {
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+
+ if( cubemap->ima->ibuf==0 ) {
+ load_image(cubemap->ima, IB_rect, "", 0);
+ if(cubemap->ima->ibuf==0) {
+ cubemap->ima->ok = 0;
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ }
+
+ EnvMap *CubeMap = cubemap;
+ mNeedsDeleted = 1;
+ mBlankTexture = 0;
+ mType = BL_TEXCUBE;
+ mTexture = &mBlankTexture;
+ mName = CubeMap->ima->id.name;
+
+ glGenTextures(1, (GLuint*)(mTexture));
+ glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, *mTexture );
+ bool needs_split = false;
+
+ if(!CubeMap->cube[0]) needs_split = true;
+
+ if(needs_split){
+ // split it
+ my_envmap_split_ima(CubeMap);
+ }
+
+ int x = cubemap->ima->ibuf->x;
+ int y = cubemap->ima->ibuf->y;
+ unsigned int *data= (unsigned int *)malloc(x*y*sizeof(unsigned int));
+
+ // -----------------------------------
+ x = CubeMap->cube[0]->ibuf->x;
+ y = CubeMap->cube[0]->ibuf->y;
+
+ // check the first image, and assume the rest
+ if (!is_pow2(x) || !is_pow2(y))
+ {
+ spit("invalid envmap size please render with CubeRes @ power of two");
+ free(data);
+ data = 0;
+ mError = true;
+ mOk = false;
+ return mOk;
+ }
+ memcpy(data, CubeMap->cube[0]->ibuf->rect, (x*y*sizeof(unsigned int)));
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ // -----------------------------------
+ x = CubeMap->cube[1]->ibuf->x;
+ y = CubeMap->cube[1]->ibuf->y;
+ memcpy(data, CubeMap->cube[1]->ibuf->rect, (x*y*sizeof(unsigned int)));
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ // -----------------------------------
+ x = CubeMap->cube[2]->ibuf->x;
+ y = CubeMap->cube[2]->ibuf->y;
+ memcpy(data, CubeMap->cube[2]->ibuf->rect, (x*y*sizeof(unsigned int)));
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ // -----------------------------------
+ x = CubeMap->cube[3]->ibuf->x;
+ y = CubeMap->cube[3]->ibuf->y;
+ memcpy(data, CubeMap->cube[3]->ibuf->rect, (x*y*sizeof(unsigned int)));
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ // -----------------------------------
+ x = CubeMap->cube[4]->ibuf->x;
+ y = CubeMap->cube[4]->ibuf->y;
+ memcpy(data, CubeMap->cube[4]->ibuf->rect, (x*y*sizeof(unsigned int)));
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ // -----------------------------------
+ x = CubeMap->cube[5]->ibuf->x;
+ y = CubeMap->cube[5]->ibuf->y;
+ memcpy(data, CubeMap->cube[5]->ibuf->rect, (x*y*sizeof(unsigned int)));
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT );
+
+ if(data) {
+ free(data);
+ data = 0;
+ }
+
+ if(needs_split) {
+ // okay we allocated, swap back to orig and free used
+ cubemap->ima = CubeMap->ima;
+ my_free_envmapdata(CubeMap);
+ }
+ mOk = IsValid();
+ return mOk;
+
+#else
+
+ mError = true;
+ mOk = false;
+ return mOk;
+
+#endif//GL_ARB_texture_cube_map
+}
+
+
+STR_String BL_Texture::GetName() const
+{
+ return mName;
+}
+
+
+bool BL_Texture::IsValid()
+{
+ return (mTexture && *mTexture!= 0)?glIsTexture(*mTexture)!=0:false;
+}
+
+
+void BL_Texture::Validate()
+{
+ mOk = IsValid();
+}
+
+
+bool BL_Texture::Ok()
+{
+ return ( mTexture?((!mError || mOk ) && *mTexture!= 0):0 );
+}
+
+
+unsigned int BL_Texture::GetTextureType() const
+{
+ return mType;
+}
+
+
+BL_Texture::operator const unsigned int () const
+{
+ return mTexture? *mTexture:0;
+}
+
+bool BL_Texture::SetGLTex(unsigned int tex)
+{
+ return false;
+}
+
+extern "C" {
+
+void my_envmap_split_ima(EnvMap *env)
+{
+ ImBuf *ibuf;
+ Image *ima;
+ int dx, part;
+
+ my_free_envmapdata(env);
+
+ dx= env->ima->ibuf->y;
+ dx/= 2;
+ if(3*dx != env->ima->ibuf->x) {
+ printf("Incorrect envmap size\n");
+ env->ok= 0;
+ env->ima->ok= 0;
+ }
+ else {
+ for(part=0; part<6; part++) {
+ ibuf= IMB_allocImBuf(dx, dx, 24, IB_rect, 0);
+ ima= (Image*)MEM_callocN(sizeof(Image), "image");
+ ima->ibuf= ibuf;
+ ima->ok= 1;
+ env->cube[part]= ima;
+ }
+ IMB_rectop(env->cube[0]->ibuf, env->ima->ibuf,
+ 0, 0, 0, 0, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[1]->ibuf, env->ima->ibuf,
+ 0, 0, dx, 0, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[2]->ibuf, env->ima->ibuf,
+ 0, 0, 2*dx, 0, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[3]->ibuf, env->ima->ibuf,
+ 0, 0, 0, dx, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[4]->ibuf, env->ima->ibuf,
+ 0, 0, dx, dx, dx, dx, IMB_rectcpy, 0);
+ IMB_rectop(env->cube[5]->ibuf, env->ima->ibuf,
+ 0, 0, 2*dx, dx, dx, dx, IMB_rectcpy, 0);
+ env->ok= 2;
+ }
+}
+
+
+void my_free_envmapdata(EnvMap *env)
+{
+ Image *ima;
+ unsigned int a, part;
+
+ for(part=0; part<6; part++) {
+ ima= env->cube[part];
+ if(ima) {
+ if(ima->ibuf) IMB_freeImBuf(ima->ibuf);
+
+ for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
+ if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
+ }
+ MEM_freeN(ima);
+ env->cube[part]= 0;
+ }
+ }
+ env->ok= 0;
+}
+
+
+}
+
+unsigned int BL_Texture::mBlankTexture = 0;
+