31#include <system_threads.h>
35#include <libFreeWRL.h>
40#include "../vrml_parser/Structs.h"
41#include "../main/headers.h"
43#include "../scenegraph/readpng.h"
44#include "../input/InputFunctions.h"
45#include "../opengl/Material.h"
46#include "../opengl/OpenGL_Utils.h"
48#include "../world_script/fieldSet.h"
49#include "../scenegraph/Component_Shape.h"
50#include "../scenegraph/Component_CubeMapTexturing.h"
51#include "../scenegraph/RenderFuncs.h"
52#include "LoadTextures.h"
72int multitex_source[2];
77#ifndef GL_EXT_texture_cube_map
80# define GL_TEXTURE_CUBE_MAP_EXT 0x8513
82# define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
94textureTableIndexStruct_s *getTableIndex(
int i);
97 struct Vector *activeTextureTable;
98 textureTableIndexStruct_s* loadThisTexture;
101 int currentlyWorkingOn;
102 int textureInProcess;
108void *Textures_constructor(){
109 void *v = MALLOCV(
sizeof(
struct pTextures));
113void Textures_init(
struct tTextures *t){
117 t->prv = Textures_constructor();
119 ppTextures p = (ppTextures)t->prv;
120 p->activeTextureTable = NULL;
123 p->currentlyWorkingOn = -1;
125 p->textureInProcess = -1;
128void Textures_clear(
struct tTextures *t){
130 glDeleteBuffers (1,&t->defaultBlankTexture);
134 ppTextures p = (ppTextures)t->prv;
140 deleteVector(textureTableIndexStruct_s *, p->activeTextureTable);
148#if defined(_MSC_VER) || defined(AQUA)
152#if !defined(_ANDROID) && !defined(ANDROIDNDK) && !defined(GLES2)
153GLXContext textureContext = NULL;
159int findTextureFile(textureTableIndexStruct_s *entry);
162void move_texture_to_opengl(textureTableIndexStruct_s*);
163struct Uni_String *newASCIIString(
const char *str);
165int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight);
166void readpng_cleanup(
int free_image_data);
169static void myTexImage2D (
int generateMipMaps, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLubyte *pixels);
179# define uint32 uint32_t
184static void myScaleImage(
int srcX,
int srcY,
int destX,
int destY,
unsigned char *src,
unsigned char *dest) {
188 uint32 *src32 = (uint32 *)src;
189 uint32 *dest32 = (uint32 *)dest;
191 if ((srcY<=0) || (destY<=0) || (srcX<=0) || (destX<=0))
return;
192 if (src == NULL)
return;
193 if (dest == NULL)
return;
195 if ((srcY==destY) && (srcX==destX)) {
197 memcpy (dest,src,srcY*srcX*4);
201 YscaleFactor = ((float)srcY) / ((
float)destY);
202 XscaleFactor = ((float)srcX) / ((
float)destX);
204 for (wye=0; wye<destY; wye++) {
205 for (yex=0; yex<destX; yex++) {
208 size_t oldIndex, newIndex;
210 fx = YscaleFactor * ((float) wye);
211 fy = XscaleFactor * ((float) yex);
214 oldIndex = (size_t)row * (
size_t)srcX + (size_t)column;
215 newIndex = (size_t)wye * (
size_t)destX + (size_t)yex;
216 dest32[newIndex] = src32[oldIndex];
221static void myScaleImage3D(
int srcX,
int srcY,
int srcZ,
int destX,
int destY,
int destZ,
unsigned char *src,
unsigned char *dest) {
227 uint32 *src32 = (uint32 *)src;
228 uint32 *dest32 = (uint32 *)dest;
230 if ((srcY<=0) || (destY<=0) || (srcX<=0) || (destX<=0) || (srcZ<=0) || (destZ<=0))
return;
231 if (src == NULL)
return;
232 if (dest == NULL)
return;
234 if ((srcY==destY) && (srcX==destX) && (srcZ==destZ)) {
236 memcpy (dest,src,srcY*srcX*srcZ*4);
240 YscaleFactor = ((float)srcY) / ((
float)destY);
241 XscaleFactor = ((float)srcX) / ((
float)destX);
242 ZscaleFactor = ((float)srcZ) / ((
float)destZ);
244 for (iz=0; iz<destZ; iz++) {
246 fz = ZscaleFactor * ((float) iz);
248 for (iy=0; iy<destY; iy++) {
250 fy = YscaleFactor * ((float) iy);
252 for (ix=0; ix<destX; ix++) {
256 fx = XscaleFactor * ((float) ix);
258 oldIndex = (page * srcY + row) * srcX + column;
259 dest32[(iz*destY + iy)*destX+ix] = src32[oldIndex];
264int iclamp(
int ival,
int istart,
int iend) {
266 iret = ival > iend? iend : ival;
267 iret = iret < istart ? istart : iret;
270void compute_3D_alpha_gradient_store_rgb(
char *dest,
int x,
int y,
int z){
275 int iz,iy,ix, jz,jy,jx,jzz,jyy,jxx, k;
277 int gradient[3], maxgradient[3], mingradient[3];
278 unsigned char *urgba;
279 uint32 *pixels = (uint32 *)dest;
291 for(k=0;k<3;k++) gradient[k] = 0;
292 rgba0 = (
char *) &pixels[(iz*y +iy)*x + ix];
293 urgba = (
unsigned char *)rgba0;
298 if(iz == z-1) jzz = -1;
299 if(iy == y-1) jyy = -1;
300 if(ix == x-1) jxx = -1;
301 jx = jxx; jy = jyy; jz = jzz;
303 rgba1 = (
char *) &pixels[((iz+jz)*y +(iy+jy))*x + (ix+jx)];
304 gradient[0] = (int)rgba1[3] - (
int)rgba0[3];
307 rgba1 = (
char *) &pixels[((iz+jz)*y +(iy+jy))*x + (ix+jx)];
308 gradient[1] = (int)rgba1[3] - (
int)rgba0[3];
311 rgba1 = (
char *) &pixels[((iz+jz)*y +(iy+jy))*x + (ix+jx)];
312 gradient[2] = (int)rgba1[3] - (
int)rgba0[3];
316 int cube[3][3][3], i,j,ii,jj,kk;
318 ii = iclamp(ix+i,0,x-1);
320 jj= iclamp(iy+j,0,y-1);
322 kk = iclamp(iz+k,0,z-1);
323 cube[i+1][j+1][k+1] = ((
unsigned char *)&pixels[(kk*y +jj)*x + ii])[3];
334 gradient[0] += cube[0][0][1] + 2*cube[0][1][1] + cube[0][2][1];
335 gradient[0] -= cube[2][0][1] + 2*cube[2][1][1] + cube[2][2][1];
336 gradient[0] += cube[0][1][0] + 2*cube[0][1][1] + cube[0][1][2];
337 gradient[0] -= cube[2][1][0] + 2*cube[2][1][1] + cube[2][1][2];
340 gradient[1] += cube[1][0][0] + 2*cube[1][0][1] + cube[1][0][2];
341 gradient[1] -= cube[1][2][0] + 2*cube[1][2][1] + cube[1][2][2];
342 gradient[1] += cube[0][0][1] + 2*cube[1][0][1] + cube[2][0][1];
343 gradient[1] -= cube[9][2][1] + 2*cube[1][2][1] + cube[2][2][1];
346 gradient[2] += cube[0][1][0] + 2*cube[1][1][0] + cube[2][1][0];
347 gradient[2] -= cube[0][1][2] + 2*cube[1][1][2] + cube[2][1][2];
348 gradient[2] += cube[1][0][0] + 2*cube[1][1][0] + cube[1][2][0];
349 gradient[2] -= cube[1][9][2] + 2*cube[1][1][2] + cube[1][2][2];
359 for(k=0;k<3;k++) gradient[k] /= 2;
361 maxgradient[k] = max(maxgradient[k],gradient[k]);
362 mingradient[k] = min(mingradient[k],gradient[k]);
368 for(k=0;k<3;k++) gradient[k] += 127;
371 for(k=0;k<3;k++) urgba[k] = (
unsigned char)gradient[k];
380 printf(
"mingradient %d %d %d\n",mingradient[0],mingradient[1],mingradient[2]);
381 printf(
"maxgradient %d %d %d\n",maxgradient[0],maxgradient[1],maxgradient[2]);
385 textureTableIndexStruct_s *tti2, tt;
390 tti2->texdata = (
unsigned char *)dest;
392 saveImage_web3dit(tti2,
"gradientRGB.web3dit");
394 saveImage_web3dit(tti2,
"gradientRGBA.web3dit");
399static void GenMipMap2D( GLubyte *src, GLubyte **dst,
int srcWidth,
int srcHeight,
int *dstWidth,
int *dstHeight )
408 *dstWidth = srcWidth / 2;
409 if ( *dstWidth <= 0 )
412 *dstHeight = srcHeight / 2;
413 if ( *dstHeight <= 0 )
416 total_size =
sizeof(GLubyte) * (
size_t)texelSize * (size_t)(*dstWidth) * (size_t)(*dstHeight);
417 *dst = MALLOC(
void *, total_size );
422 for ( y = 0; y < *dstHeight; y++ )
424 for( x = 0; x < *dstWidth; x++ )
426 size_t srcIndex[4], x2, y2, swidth, texsize, kd;
449 srcIndex[0] = (y2*swidth + x2) * texsize;
450 srcIndex[1] = (y2*swidth + x2 + (size_t)1L) * texsize;
451 srcIndex[2] = ((y2 + 1L)*swidth + x2) * texsize;
452 srcIndex[3] = ((y2 + 1L)*swidth + x2 + (size_t)1L) * texsize;
455 for ( sample = 0; sample < 4; sample++ )
457 r += src[srcIndex[sample] + (size_t)0L];
458 g += src[srcIndex[sample] + (size_t)1L];
459 b += src[srcIndex[sample] + (size_t)2L];
460 a += src[srcIndex[sample] + (size_t)3L];
470 kd = ((size_t)y * (size_t)(*dstWidth) + (size_t)x ) * (
size_t)texelSize;
472 pix[0] = (GLubyte)( r );
473 pix[1] = (GLubyte)( g );
474 pix[2] = (GLubyte)( b );
475 pix[3] = (GLubyte)( a );
485static void myTexImage2D (
int generateMipMaps, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLubyte *pixels) {
486 GLubyte *prevImage = NULL;
487 GLubyte *newImage = NULL;
492 FW_GL_TEXIMAGE2D(target,level,internalformat,width,height,border,format,type,pixels);
493 if (!generateMipMaps)
return;
494 if ((width <=1) && (height <=1))
return;
498 total_size = (size_t)4L * width * height;
499 prevImage = MALLOC(GLubyte *, total_size);
500 memcpy (prevImage, pixels, total_size);
505 while ((width > 1) && (height > 1)) {
506 GLint newWidth, newHeight;
508 GenMipMap2D(prevImage,&newImage, width, height, &newWidth, &newHeight);
510 FW_GL_TEXIMAGE2D(target,level,internalformat,newWidth,newHeight,0,format,GL_UNSIGNED_BYTE,newImage);
512 FREE_IF_NZ(prevImage);
513 prevImage = newImage;
519 FREE_IF_NZ(newImage);
527const char *texst(
int num)
529 if (num == TEX_NOTLOADED)
return "TEX_NOTLOADED";
530 if (num == TEX_LOADING)
return "TEX_LOADING";
531 if (num == TEX_NEEDSBINDING)
return "TEX_NEEDSBINDING";
532 if (num == TEX_LOADED)
return "TEX_LOADED";
533 if (num == TEX_UNSQUASHED)
return "UNSQUASHED";
539int isTextureAlpha(
int texno) {
540 textureTableIndexStruct_s *ti;
545 ti = getTableIndex(texno);
546 if (ti==NULL)
return FALSE;
548 if (ti->status==TEX_LOADED) {
556int fwl_isTextureinitialized() {
557 return gglobal()->threads.TextureThreadRunning;
561int fwl_isTextureLoaded(
int texno) {
562 textureTableIndexStruct_s *ti;
567 ti = getTableIndex(texno);
568 return (ti->status==TEX_LOADED);
572int fwl_isTextureParsing() {
573 ppTextures p = (ppTextures)gglobal()->Textures.prv;
577 if (p->textureInProcess > 0) {
578 printf(
"call to fwl_isTextureParsing %d, returning %d\n",
579 p->textureInProcess,p->textureInProcess > 0);
582 return p->textureInProcess >0;
586void releaseTexture(
struct X3D_Node *node) {
589 textureTableIndexStruct_s *ti;
591 if (node->_nodeType == NODE_ImageTexture) {
593 }
else if (node->_nodeType == NODE_PixelTexture) {
595 }
else if (node->_nodeType == NODE_BufferTexture) {
597 }
else if (node->_nodeType == NODE_MovieTexture) {
599 }
else if (node->_nodeType == NODE_PixelTexture3D) {
601 }
else if (node->_nodeType == NODE_ImageTexture3D) {
603 }
else if (node->_nodeType == NODE_ComposedTexture3D) {
609 printf (
"releaseTexture, calling getTableIndex\n");
610 ti = getTableIndex(tableIndex);
611 printf (
"releaseTexture, ti %p, ti->status %d\n",ti,ti->status);
612 ti->status = TEX_NOTLOADED;
614 if (ti->OpenGLTexture != TEXTURE_INVALID) {
615 printf (
"deleting %d textures, starting at %u\n",ti->frames, ti->OpenGLTexture);
616 ti->OpenGLTexture = TEXTURE_INVALID;
621 ti = getTableIndex(tableIndex);
623 ti->status = TEX_NOTLOADED;
624 if (ti->OpenGLTexture != TEXTURE_INVALID) {
625 FW_GL_DELETETEXTURES(1, &ti->OpenGLTexture);
626 ti->OpenGLTexture = TEXTURE_INVALID;
634textureTableIndexStruct_s *getTableIndex(
int indx) {
635 ppTextures p = (ppTextures)gglobal()->Textures.prv;
639sprintf (line,
"getTableIndex, looking for %d",indx);
640ConsoleMessage (line);}
643 ConsoleMessage (
"getTableIndex, texture <0 requested");
647 if (p->activeTextureTable ==NULL ) {
648 ConsoleMessage (
"NULL sizing errror in getTableIndex");
653 if (indx >= vectorSize(p->activeTextureTable)) {
654 ConsoleMessage (
"sizing errror in getTableIndex");
661printf (
"getTableIndex - valid request\n");
662sprintf (line,
"getTableIndex, for %d, size %d",indx, vectorSize(p->activeTextureTable));
663ConsoleMessage (line);}
666 return vector_get(textureTableIndexStruct_s *, p->activeTextureTable, indx);
668int getTextureTableIndexFromFromTextureNode(
struct X3D_Node *node){
669 int thisTexture = -1;
670 int thisTextureType = node->_nodeType;
671 if (thisTextureType==NODE_ImageTexture){
673 thisTexture = it->__textureTableIndex;
674 }
else if (thisTextureType==NODE_PixelTexture){
676 thisTexture = pt->__textureTableIndex;
677 }
else if (thisTextureType == NODE_BufferTexture) {
679 thisTexture = pt->__textureTableIndex;
680 }
else if (thisTextureType == NODE_GeneratedTexture) {
682 thisTexture = gt->__textureTableIndex;
683 }
else if (thisTextureType==NODE_MovieTexture){
685 thisTexture = mt->__textureTableIndex;
686 }
else if (thisTextureType == NODE_ComposedCubeMapTexture) {
688 thisTexture = ict->__textureTableIndex;
689 }
else if (thisTextureType==NODE_ImageCubeMapTexture){
691 thisTexture = ict->__textureTableIndex;
692 }
else if (thisTextureType==NODE_GeneratedCubeMapTexture){
694 thisTexture = ict->__textureTableIndex;
695 }
else if (thisTextureType==NODE_PixelTexture3D){
697 thisTexture = pt->__textureTableIndex;
698 }
else if (thisTextureType==NODE_ImageTexture3D){
700 thisTexture = pt->__textureTableIndex;
701 }
else if (thisTextureType==NODE_ComposedTexture3D){
703 thisTexture = pt->__textureTableIndex;
704 }
else if (thisTextureType==NODE_MultiTexture){
706 thisTexture = getTextureTableIndexFromFromTextureNode(X3D_NODE(pt->texture.p[0]));
708 ConsoleMessage (
"Invalid type for texture, %s\n",stringNodeType(thisTextureType));
712textureTableIndexStruct_s *getTableTableFromTextureNode(
struct X3D_Node *textureNode){
713 textureTableIndexStruct_s *ret = NULL;
714 int index = getTextureTableIndexFromFromTextureNode(textureNode);
716 ret = getTableIndex(index);
719int getGlTextureNumberFromTextureNode(
struct X3D_Node *textureNode){
720 textureTableIndexStruct_s *tts = getTableTableFromTextureNode(textureNode);
721 if(tts == NULL)
return 0;
722 return tts->OpenGLTexture;
725int getTextureSizeFromTextureNode(
struct X3D_Node *textureNode,
int *ixyz){
727 textureTableIndexStruct_s *tts = getTableTableFromTextureNode(textureNode);
728 ixyz[0] = ixyz[1] = ixyz[2] = 0;
742void registerTexture0(
int iaction,
struct X3D_Node *tmp) {
750 if ((it->_nodeType == NODE_ImageTexture) ||
751 (it->_nodeType == NODE_PixelTexture) ||
752 (it->_nodeType == NODE_BufferTexture) ||
753 (it->_nodeType == NODE_GeneratedTexture) ||
754 (it->_nodeType == NODE_ComposedCubeMapTexture) ||
755 (it->_nodeType == NODE_ImageCubeMapTexture) ||
756 (it->_nodeType == NODE_GeneratedCubeMapTexture) ||
757 (it->_nodeType == NODE_PixelTexture3D) ||
758 (it->_nodeType == NODE_ImageTexture3D) ||
759 (it->_nodeType == NODE_ComposedTexture3D) ||
760 (it->_nodeType == NODE_MovieTexture)
762 ppTextures p = (ppTextures)gglobal()->Textures.prv;
768 textureTableIndexStruct_s * newTexture = MALLOC (textureTableIndexStruct_s *,
sizeof (textureTableIndexStruct_s));
769 memset(newTexture,0,
sizeof(textureTableIndexStruct_s));
773 if (p->activeTextureTable == NULL) {
774 p->activeTextureTable =newVector(textureTableIndexStruct_s *, 16);
775 vector_pushBack(textureTableIndexStruct_s *, p->activeTextureTable, newTexture);
779 textureNumber = vectorSize(p->activeTextureTable);
783 DEBUG_TEX(
"CREATING TEXTURE NODE: type %d\n", it->_nodeType);
786 switch (it->_nodeType) {
788 case NODE_ImageTexture:
789 it->__textureTableIndex = textureNumber;
791 case NODE_PixelTexture: {
794 pt->__textureTableIndex = textureNumber;
796 case NODE_BufferTexture: {
799 pt->__textureTableIndex = textureNumber;
801 case NODE_GeneratedTexture: {
804 pt->__textureTableIndex = textureNumber;
806 case NODE_PixelTexture3D: {
809 pt->__textureTableIndex = textureNumber;
811 case NODE_ImageTexture3D: {
814 pt->__textureTableIndex = textureNumber;
816 case NODE_ComposedTexture3D: {
819 pt->__textureTableIndex = textureNumber;
821 case NODE_MovieTexture: {
824 mt->__textureTableIndex = textureNumber;
827 case NODE_ComposedCubeMapTexture: {
830 v1t->__textureTableIndex = textureNumber;
834 case NODE_ImageCubeMapTexture: {
837 v1t->__textureTableIndex = textureNumber;
841 case NODE_GeneratedCubeMapTexture: {
844 v1t->__textureTableIndex = textureNumber;
851 newTexture->nodeType = it->_nodeType;
852 newTexture->scenegraphNode = X3D_NODE(tmp);
853 newTexture->textureNumber = textureNumber;
855 vector_pushBack(textureTableIndexStruct_s *, p->activeTextureTable, newTexture);
862 textureTableIndexStruct_s * tti = NULL;
863 int *textureNumber = NULL;
868 switch (it->_nodeType) {
870 case NODE_ImageTexture:
871 textureNumber = &it->__textureTableIndex;
873 case NODE_PixelTexture: {
876 textureNumber = &pt->__textureTableIndex;
878 case NODE_BufferTexture: {
881 textureNumber = &pt->__textureTableIndex;
883 case NODE_GeneratedTexture: {
886 textureNumber = &pt->__textureTableIndex;
888 case NODE_PixelTexture3D: {
891 textureNumber = &pt->__textureTableIndex;
893 case NODE_ImageTexture3D: {
896 textureNumber = &pt->__textureTableIndex;
898 case NODE_ComposedTexture3D: {
901 textureNumber = &pt->__textureTableIndex;
903 case NODE_MovieTexture: {
906 textureNumber = &mt->__textureTableIndex;
909 case NODE_ComposedCubeMapTexture: {
912 textureNumber = &v1t->__textureTableIndex;
915 case NODE_ImageCubeMapTexture: {
918 textureNumber = &v1t->__textureTableIndex;
921 case NODE_GeneratedCubeMapTexture: {
924 textureNumber = &v1t->__textureTableIndex;
928 tti = getTableIndex(*textureNumber);
931 vector_set(textureTableIndexStruct_s *,p->activeTextureTable,*textureNumber,NULL);
943 FREE_IF_NZ(tti->texdata);
953void registerTexture(
struct X3D_Node *tmp) {
954 registerTexture0(1,tmp);
956void unRegisterTexture(
struct X3D_Node *tmp) {
957 registerTexture0(0,tmp);
961void add_node_to_broto_context(
struct X3D_Proto *currentContext,
struct X3D_Node *node);
964void push_render_geom(
int igeom);
965void pop_render_geom();
974 thisurl.n = 0; thisurl.p = NULL;
976 s_shader_capabilities_t* me;
978 me = mat->currentShaderProperties;
979 mat->fw_FrontMaterial.type = MAT_UNLIT;
980 for (count=0; count<6; count++) {
983 case 0: {thistex = X3D_IMAGETEXTURE(node->__frontTexture); thisurl = node->frontUrl;
break;}
984 case 1: {thistex = X3D_IMAGETEXTURE(node->__backTexture); thisurl = node->backUrl;
break;}
985 case 2: {thistex = X3D_IMAGETEXTURE(node->__topTexture); thisurl = node->topUrl;
break;}
986 case 3: {thistex = X3D_IMAGETEXTURE(node->__bottomTexture); thisurl = node->bottomUrl;
break;}
987 case 4: {thistex = X3D_IMAGETEXTURE(node->__rightTexture); thisurl = node->rightUrl;
break;}
988 case 5: {thistex = X3D_IMAGETEXTURE(node->__leftTexture); thisurl = node->leftUrl;
break;}
990 if (thisurl.n != 0 ) {
992 if (thistex == NULL) {
994 thistex = createNewX3DNode(NODE_ImageTexture);
995 thistp = createNewX3DNode (NODE_TextureProperties);
996 if(node->_executionContext){
997 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(thistex));
998 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(thistp));
1004 thistp->generateMipMaps = GL_FALSE;
1006 thistp->textureCompression = newASCIIString(
"FASTEST");
1007 thistp->borderWidth = 0;
1008 thistex->textureProperties = X3D_NODE(thistp);
1009 ADD_PARENT(X3D_NODE(thistp), X3D_NODE(thistex));
1012 printf (
"bg, creating shadow texture node url.n = %d\n",thisurl.n);
1017 for (i=0; i<thisurl.n; i++) {
1018 thistex->url.p[i] = newASCIIString (thisurl.p[i]->strptr);
1020 thistex->url.n = thisurl.n;
1023 case 0: {node->__frontTexture = X3D_NODE(thistex);
break;}
1024 case 1: {node->__backTexture = X3D_NODE(thistex);
break;}
1025 case 2: {node->__topTexture = X3D_NODE(thistex);
break;}
1026 case 3: {node->__bottomTexture = X3D_NODE(thistex);
break;}
1027 case 4: {node->__rightTexture = X3D_NODE(thistex);
break;}
1028 case 5: {node->__leftTexture = X3D_NODE(thistex);
break;}
1033 clear_textureUnit_used();
1034 clear_material_samplers();
1035 clear_materialparameters_per_draw_counts();
1037 gglobal()->RenderFuncs.textureStackTop = 0;
1039 push_render_geom(1);
1042 gglobal()->RenderFuncs.texturenode = (
void*)thistex;
1043 render_node(X3D_NODE(thistex));
1046 textureTransform_start();
1050 textureCoord_send(&mtf);
1051 FW_GL_VERTEX_POINTER(3,GL_FLOAT,0,BackgroundVert);
1052 FW_GL_NORMAL_POINTER(GL_FLOAT,0,Backnorms);
1054 sendArraysToGPU (GL_TRIANGLES, count*6, 6);
1056 textureTransform_end();
1068 mat->fw_FrontMaterial.type = MAT_UNLIT;
1070 for (count=0; count<6; count++) {
1073 case 0: {POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->frontTexture,thistex);
break;}
1074 case 1: {POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->backTexture,thistex);
break;}
1075 case 2: {POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->topTexture,thistex);
break;}
1076 case 3: {POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->bottomTexture,thistex);
break;}
1077 case 4: {POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->rightTexture,thistex);
break;}
1078 case 5: {POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->leftTexture,thistex);
break;}
1083 if ((thistex->_nodeType == NODE_ImageTexture) ||
1084 (thistex->_nodeType == NODE_PixelTexture) ||
1085 (thistex->_nodeType == NODE_BufferTexture) ||
1086 (thistex->_nodeType == NODE_MovieTexture) ||
1087 (thistex->_nodeType == NODE_MultiTexture)) {
1090 switch (thistex->_nodeType) {
1091 case NODE_ImageTexture: {
1092 if (X3D_IMAGETEXTURE(thistex)->textureProperties == NULL) {
1093 thistp = createNewX3DNode (NODE_TextureProperties);
1094 if(node->_executionContext){
1095 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(thistp));
1097 X3D_IMAGETEXTURE(thistex)->textureProperties = X3D_NODE(thistp);
1098 ADD_PARENT(X3D_NODE(thistp),thistex);
1102 case NODE_PixelTexture: {
1103 if (X3D_PIXELTEXTURE(thistex)->textureProperties == NULL) {
1104 thistp = createNewX3DNode (NODE_TextureProperties);
1105 if(node->_executionContext){
1106 add_node_to_broto_context(X3D_PROTO(node->_executionContext),X3D_NODE(thistp));
1109 X3D_PIXELTEXTURE(thistex)->textureProperties = X3D_NODE(thistp);
1110 ADD_PARENT(X3D_NODE(thistp),thistex);
1114 case NODE_BufferTexture: {
1115 if (X3D_BUFFERTEXTURE(thistex)->textureProperties == NULL) {
1116 thistp = createNewX3DNode(NODE_TextureProperties);
1117 if (node->_executionContext) {
1118 add_node_to_broto_context(X3D_PROTO(node->_executionContext), X3D_NODE(thistp));
1121 X3D_BUFFERTEXTURE(thistex)->textureProperties = X3D_NODE(thistp);
1122 ADD_PARENT(X3D_NODE(thistp), thistex);
1127 case NODE_MovieTexture:
1128 case NODE_MultiTexture:
1133 clear_textureUnit_used();
1134 clear_material_samplers();
1135 clear_materialparameters_per_draw_counts();
1137 gglobal()->RenderFuncs.textureStackTop = 0;
1139 push_render_geom(1);
1142 gglobal()->RenderFuncs.texturenode = (
void*)thistex;
1143 render_node(X3D_NODE(thistex));
1146 textureTransform_start();
1150 textureCoord_send(&mtf);
1151 FW_GL_VERTEX_POINTER(3, GL_FLOAT, 0, BackgroundVert);
1152 FW_GL_NORMAL_POINTER(GL_FLOAT, 0, Backnorms);
1154 sendArraysToGPU(GL_TRIANGLES, count * 6, 6);
1156 textureTransform_end();
1165void loadTextureNode (
struct X3D_Node *node,
void *vparam)
1167 PRINT_GL_ERROR_IF_ANY(
"loadTextureNode")
1170 if (NODE_NEEDS_COMPILING) {
1172 DEBUG_TEX (
"FORCE NODE RELOAD: %p %s\n", node, stringNodeType(node->_nodeType));
1184 switch (node->_nodeType) {
1186 case NODE_MovieTexture: {
1191 case NODE_PixelTexture:
1192 releaseTexture(node);
1194 case NODE_BufferTexture:
1195 releaseTexture(node);
1198 case NODE_ImageTexture:
1199 releaseTexture(node);
1201 case NODE_GeneratedTexture:
1202 releaseTexture(node);
1205 case NODE_ImageCubeMapTexture:
1206 releaseTexture(node);
1209 case NODE_GeneratedCubeMapTexture:
1213 case NODE_PixelTexture3D:
1214 releaseTexture(node);
1216 case NODE_ImageTexture3D:
1217 releaseTexture(node);
1219 case NODE_ComposedTexture3D:
1220 releaseTexture(node);
1224 printf (
"loadTextureNode, unknown node type %s\n",stringNodeType(node->_nodeType));
1230 new_bind_image (X3D_NODE(node), (
struct multiTexParams *)vparam);
1240 ttglobal tg = gglobal();
1241 rdr_caps = tg->display.rdr_caps;
1247 if (node->__xparams == 0) {
1249 node->__xparams = MALLOC (
void *,
sizeof (
struct multiTexParams) * rdr_caps->texture_units);
1258 for (count = 0; count < rdr_caps->texture_units; count++) {
1259 paramPtr->multitex_mode[0]= MTMODE_MODULATE;
1260 paramPtr->multitex_mode[1]= 0;
1261 paramPtr->multitex_source[0]=INT_ID_UNDEFINED;
1262 paramPtr->multitex_source[1]=0;
1263 paramPtr->multitex_function=INT_ID_UNDEFINED;
1270 max = node->texture.n;
1271 if (max > rdr_caps->texture_units) max = rdr_caps->texture_units;
1279 for (count = 0; count < max; count++) {
1280 char *smode, *ssource, *sfunc;
1281 smode = ssource = sfunc = NULL;
1282 if(node->mode.n>count){
1284 smode = node->mode.p[count]->strptr;
1286 mode = findFieldInMULTITEXTUREMODE(smode);
1287 if(mode > -1) mode += 1;
1290 if(strchr(smode,
'/') || strchr(smode,
',')){
1292 char *srgb, *salpha, *b1,*b2, *splittable;
1293 int modergb, modealpha;
1294 splittable = strdup(smode);
1295 b1 = strchr(splittable,
' ');
1296 b2 = strrchr(splittable,
' ');
1298 splittable[b1 - splittable] =
'\0';
1300 modergb = findFieldInMULTITEXTUREMODE(srgb);
1302 modergb = MTMODE_MODULATE;
1305 modealpha = findFieldInMULTITEXTUREMODE(salpha);
1307 modealpha = MTMODE_MODULATE;
1316 paramPtr->multitex_mode[0] = mode;
1317 paramPtr->multitex_mode[1] = modea;
1321 if(node->source.n > count) {
1322 int source, sourcea;
1323 ssource = node->source.p[count]->strptr;
1324 source = findFieldInMULTITEXTURESOURCE(ssource);
1325 if(source > -1) source += 1;
1329 if(strchr(ssource,
'/') || strchr(ssource,
',')){
1331 char *srgb, *salpha, *b1,*b2, *splittable;
1332 int sourcergb, sourcealpha;
1333 splittable = strdup(ssource);
1334 b1 = strchr(splittable,
' ');
1335 b2 = strrchr(splittable,
' ');
1337 splittable[b1 - splittable] =
'\0';
1339 sourcergb = findFieldInMULTITEXTURESOURCE(srgb);
1341 sourcergb = INT_ID_UNDEFINED;
1344 sourcealpha = findFieldInMULTITEXTURESOURCE(salpha);
1347 sourcea = sourcealpha;
1351 paramPtr->multitex_source[0] = source;
1352 paramPtr->multitex_source[1] = sourcea;
1357 if (node->function.n>count) {
1359 sfunc = node->function.p[count]->strptr;
1361 ifunc = findFieldInMULTITEXTUREFUNCTION(sfunc);
1364 paramPtr->multitex_function = ifunc;
1369printf (
"compile_MultiTexture, %d of %d, mode %d %d source %d %d function %d m %s s %s f %s\n",
1370count,max,paramPtr->multitex_mode[0],paramPtr->multitex_mode[1],paramPtr->multitex_source[0],paramPtr->multitex_source[1],paramPtr->multitex_function,smode,ssource,sfunc);
1384 ttglobal tg = gglobal();
1385 rdr_caps = tg->display.rdr_caps;
1388 printf (
"loadMultiTexture, this %s has %d textures %x %x\n",stringNodeType(node->_nodeType),
1390 (
int) node->texture.p[0], (
int) node->texture.p[1]);
1391 printf (
" change %d ichange %d\n",node->_change, node->_ichange);
1395 if (NODE_NEEDS_COMPILING) {
1396 compileMultiTexture(node);
1406 max = node->texture.n;
1409 if (max > rdr_caps->texture_units) max = rdr_caps->texture_units;
1410 if (max > MAX_MULTITEXTURE) max = MAX_MULTITEXTURE;
1417 printf (
"loadMultiTExture, param stack:\n");
1418 for (count=0; count<max; count++) {
1419 printf (
" tex %d source %d mode %d\n",count,paramPtr[count].multitex_source,paramPtr[count].multitex_mode);
1423 for (count=0; count < max; count++) {
1425 printf (
"loadMultiTexture, working on texture %d\n",count);
1429 nt = X3D_IMAGETEXTURE(node->texture.p[count]);
1431 switch (nt->_nodeType) {
1432 case NODE_PixelTexture:
1433 case NODE_ImageTexture :
1434 case NODE_GeneratedTexture:
1437 render_node(X3D_NODE(nt));
1439 case NODE_ImageCubeMapTexture:
1440 case NODE_ComposedCubeMapTexture:
1441 case NODE_GeneratedCubeMapTexture:
1443 render_node(X3D_NODE(nt));
1446 case NODE_MultiTexture:
1447 printf (
"MultiTexture texture %d is a MULTITEXTURE!!\n",count);
1450 printf (
"MultiTexture - unknown sub texture type %d\n",
1458 tg->RenderFuncs.textureStackTop++;
1465 printf (
"loadMultiTexture, textureStackTop %d\n",gglobal()->RenderFuncs.textureStackTop);
1466 printf (
"loadMultiTexture, finished with texture %d\n",count);
1469 tg->RenderFuncs.texturenode = (
void*)node;
1473int getTextureDescriptors(
struct X3D_Node *textureNode,
int *textures,
int *modes,
int *sources,
int *funcs,
int *width,
int *height,
int *samplr){
1475 if( textureNode == NULL)
return 0;
1476 if(textureNode->_nodeType == NODE_MultiTexture){
1480 if (!xparam)
return 0;
1481 ntexture = pt->texture.n;
1482 for(
int i=0;i<ntexture;i++){
1485 textures[i] = getGlTextureNumberFromTextureNode(pt->texture.p[i]);
1486 iret = getTextureSizeFromTextureNode(pt->texture.p[i],ixyz);
1488 modes[i] = xparam[i].multitex_mode[0] + 100*xparam[i].multitex_mode[1];
1489 sources[i] = xparam[i].multitex_source[0] + 100*xparam[i].multitex_source[1];
1490 funcs[i] = xparam[i].multitex_function;
1491 samplr[i] = is_cubeMap(pt->texture.p[i]);
1493 }
else if (textureNode->_nodeType == NODE_ComposedTexture3D) {
1497 for (
int i = 0; i < ntexture; i++) {
1500 textures[i] = getGlTextureNumberFromTextureNode(tex->p[i]);
1501 iret = getTextureSizeFromTextureNode(tex->p[i], ixyz);
1503 modes[i] = MTMODE_REPLACE;
1504 sources[i] = INT_ID_UNDEFINED;
1505 funcs[i] = INT_ID_UNDEFINED;
1512 textures[0] = getGlTextureNumberFromTextureNode(textureNode);
1514 modes[0] = MTMODE_REPLACE;
1515 sources[0] = INT_ID_UNDEFINED;
1516 funcs[0] = INT_ID_UNDEFINED;
1517 iret = getTextureSizeFromTextureNode(textureNode,ixyz);
1519 height[0] = ixyz[1];
1520 samplr[0] = is_cubeMap(textureNode);
1526#define BOUNDARY_TO_GL(direct) \
1527 switch (findFieldInTEXTUREBOUNDARYKEYWORDS(tpNode->boundaryMode##direct->strptr)) { \
1528 case TB_CLAMP: direct##rc=GL_CLAMP; break; \
1529 case TB_CLAMP_TO_EDGE: direct##rc=GL_CLAMP_TO_EDGE; break; \
1530 case TB_CLAMP_TO_BOUNDARY: direct##rc=GL_CLAMP_TO_BORDER; break; \
1531 case TB_MIRRORED_REPEAT: direct##rc=GL_MIRRORED_REPEAT; break; \
1532 case TB_REPEAT: direct##rc=GL_REPEAT; break; \
1533 default: direct##rc = GL_REPEAT; \
1538#define DEF_FINDFIELD(arr) \
1539 static int findFieldIn##arr(const char* field) \
1541 return findFieldInARR(field, arr, arr##_COUNT); \
1544DEF_FINDFIELD(TEXTUREMINIFICATIONKEYWORDS)
1545DEF_FINDFIELD(TEXTUREMAGNIFICATIONKEYWORDS)
1546DEF_FINDFIELD(TEXTUREBOUNDARYKEYWORDS)
1547DEF_FINDFIELD(TEXTURECOMPRESSIONKEYWORDS)
1549void unpackImageCubeMap6 (textureTableIndexStruct_s* me);
1550void move_texture_to_opengl(textureTableIndexStruct_s* me) {
1551 int rx, ry, rz, sx, sy, sz;
1557 float anisotropicDegree = 1.0f;
1560 GLint Trc, Src, Rrc;
1561 GLint minFilter, magFilter;
1563 int generateMipMaps;
1565 unsigned char* mytexdata;
1571 pthread_mutex_t gl_mutex1 = PTHREAD_MUTEX_INITIALIZER;
1582 int haveValidTexturePropertiesNode;
1588 pthread_mutex_lock(&gl_mutex1);
1591 ttglobal tg = gglobal();
1592 rdr_caps = tg->display.rdr_caps;
1596 Src = FALSE; Trc = FALSE; Rrc = FALSE;
1598 haveValidTexturePropertiesNode = FALSE;
1600 borderColour.c[0] = 0.0f; borderColour.c[1] = 0.0f; borderColour.c[2] = 0.0f; borderColour.c[3] = 0.0f;
1601 compression = GL_FALSE;
1606 if (!checkNode(me->scenegraphNode, __FILE__, __LINE__)) {
1607 ConsoleMessage(
"main node disappeared, ignoring texture\n");
1608 me->status = TEXTURE_INVALID;
1611 pthread_mutex_unlock(&gl_mutex1);
1620 if (me->texdata == NULL) {
1621 char buff[] = { 0x70, 0x70, 0x70, 0xff };
1625 me->hasAlpha = FALSE;
1626 me->texdata = MALLOC(
unsigned char*, 4);
1627 memcpy(me->texdata, buff, 4);
1635 if (me->OpenGLTexture == TEXTURE_INVALID) {
1637 if ((getAppearanceProperties()->cubeFace == 0) || (getAppearanceProperties()->cubeFace == GL_TEXTURE_CUBE_MAP_POSITIVE_X)) {
1638 FW_GL_GENTEXTURES(1, &me->OpenGLTexture);
1642 printf(
"just glGend texture for block %p is %u, type %s\n",
1643 me, me->OpenGLTexture, stringNodeType(me->nodeType));
1649 if (me->nodeType == NODE_ImageTexture) {
1651 Src = it->repeatS; Trc = it->repeatT;
1652 tpNode = X3D_TEXTUREPROPERTIES(it->textureProperties);
1654 else if (me->nodeType == NODE_PixelTexture) {
1656 Src = pt->repeatS; Trc = pt->repeatT;
1657 tpNode = X3D_TEXTUREPROPERTIES(pt->textureProperties);
1659 else if (me->nodeType == NODE_BufferTexture) {
1661 Src = bt->repeatS; Trc = bt->repeatT;
1662 tpNode = X3D_TEXTUREPROPERTIES(bt->textureProperties);
1664 else if (me->nodeType == NODE_GeneratedTexture) {
1666 Src = gt->repeatS; Trc = gt->repeatT;
1667 tpNode = X3D_TEXTUREPROPERTIES(gt->textureProperties);
1669 else if (me->nodeType == NODE_MovieTexture) {
1671 Src = mt->repeatS; Trc = mt->repeatT;
1672 tpNode = X3D_TEXTUREPROPERTIES(mt->textureProperties);
1674 else if (me->nodeType == NODE_PixelTexture3D) {
1676 Src = pt3d->repeatS; Trc = pt3d->repeatT; Rrc = pt3d->repeatR;
1677 tpNode = X3D_TEXTUREPROPERTIES(pt3d->textureProperties);
1679 else if (me->nodeType == NODE_ImageTexture3D) {
1682 Src = it3d->repeatS; Trc = it3d->repeatT; Rrc = it3d->repeatR;
1683 tpNode = X3D_TEXTUREPROPERTIES(it3d->textureProperties);
1685 else if (me->nodeType == NODE_ComposedTexture3D) {
1688 Src = ct3d->repeatS; Trc = ct3d->repeatT; Rrc = ct3d->repeatR;
1689 tpNode = X3D_TEXTUREPROPERTIES(ct3d->textureProperties);
1691 else if (me->nodeType == NODE_ImageCubeMapTexture) {
1693 tpNode = X3D_TEXTUREPROPERTIES(mi->textureProperties);
1695 else if (me->nodeType == NODE_GeneratedCubeMapTexture) {
1697 tpNode = X3D_TEXTUREPROPERTIES(mi->textureProperties);
1702 me->repeatSTR[0] = Src;
1703 me->repeatSTR[1] = Trc;
1704 me->repeatSTR[2] = Rrc;
1709 if (tpNode->_nodeType != NODE_TextureProperties) {
1710 ConsoleMessage(
"have a %s as a textureProperties node", stringNodeType(tpNode->_nodeType));
1713 haveValidTexturePropertiesNode = TRUE;
1714 generateMipMaps = tpNode->generateMipMaps ? GL_TRUE : GL_FALSE;
1715 texPri = tpNode->texturePriority;
1716 if ((texPri < 0.0) || (texPri > 1.0)) {
1718 ConsoleMessage(
"invalid texturePriority of %f", tpNode->texturePriority);
1720 memcpy(&borderColour, &(tpNode->borderColor),
sizeof(
struct SFColorRGBA));
1722 anisotropicDegree = tpNode->anisotropicDegree;
1723 if ((anisotropicDegree < 1.0) || (anisotropicDegree > rdr_caps->anisotropicDegree)) {
1727 anisotropicDegree = rdr_caps->anisotropicDegree;
1730 borderWidth = tpNode->borderWidth;
1731 if (borderWidth < 0) borderWidth = 0;
1732 if (borderWidth > 1) borderWidth = 1;
1736 switch (findFieldInTEXTUREMAGNIFICATIONKEYWORDS(tpNode->magnificationFilter->strptr)) {
1737 case TMAG_AVG_PIXEL:
1738 magFilter = GL_LINEAR;
break;
1739 case TMAG_DEFAULT: magFilter = GL_LINEAR;
break;
1740 case TMAG_FASTEST: magFilter = GL_LINEAR;
break;
1741 case TMAG_NEAREST_PIXEL: magFilter = GL_NEAREST;
break;
1742 case TMAG_NICEST: magFilter = GL_NEAREST;
break;
1743 default: magFilter = GL_NEAREST; ConsoleMessage(
"unknown magnification filter %s",
1744 tpNode->magnificationFilter->strptr);
1748 if (generateMipMaps)
switch (findFieldInTEXTUREMINIFICATIONKEYWORDS(tpNode->minificationFilter->strptr)) {
1749 case TMIN_AVG_PIXEL: minFilter = GL_NEAREST;
break;
1750 case TMIN_AVG_PIXEL_AVG_MIPMAP: minFilter = GL_NEAREST_MIPMAP_NEAREST;
break;
1751 case TMIN_AVG_PIXEL_NEAREST_MIPMAP: minFilter = GL_NEAREST_MIPMAP_NEAREST;
break;
1752 case TMIN_DEFAULT: minFilter = GL_NEAREST_MIPMAP_LINEAR;
break;
1753 case TMIN_FASTEST: minFilter = GL_NEAREST_MIPMAP_LINEAR;
break;
1754 case TMIN_NICEST: minFilter = GL_NEAREST_MIPMAP_NEAREST;
break;
1755 case TMIN_NEAREST_PIXEL: minFilter = GL_NEAREST;
break;
1756 case TMIN_NEAREST_PIXEL_NEAREST_MIPMAP: minFilter = GL_NEAREST_MIPMAP_LINEAR;
break;
1757 default: minFilter = GL_NEAREST_MIPMAP_NEAREST;
1758 ConsoleMessage(
"unknown minificationFilter of %s",
1759 tpNode->minificationFilter->strptr);
1761 else switch (findFieldInTEXTUREMINIFICATIONKEYWORDS(tpNode->minificationFilter->strptr)) {
1762 case TMIN_AVG_PIXEL:
1763 case TMIN_AVG_PIXEL_AVG_MIPMAP:
1764 case TMIN_AVG_PIXEL_NEAREST_MIPMAP:
1768 case TMIN_NEAREST_PIXEL: minFilter = GL_NEAREST;
break;
1769 case TMIN_NEAREST_PIXEL_NEAREST_MIPMAP: minFilter = GL_LINEAR;
break;
1770 default: minFilter = GL_NEAREST;
1771 ConsoleMessage(
"unknown minificationFilter of %s",
1772 tpNode->minificationFilter->strptr);
1775 switch (findFieldInTEXTURECOMPRESSIONKEYWORDS(tpNode->textureCompression->strptr)) {
1776 case TC_DEFAULT: compression = GL_NONE;
break;
1777 case TC_FASTEST: compression = GL_FASTEST;
break;
1778 case TC_HIGH: compression = GL_FASTEST;
break;
1779 case TC_LOW: compression = GL_NONE;
break;
1780 case TC_MEDIUM: compression = GL_NICEST;
break;
1781 case TC_NICEST: compression = GL_NICEST;
break;
1783 default: compression = GL_NEAREST_MIPMAP_NEAREST;
1784 ConsoleMessage(
"unknown textureCompression of %s",
1785 tpNode->textureCompression->strptr);
1796 if (!haveValidTexturePropertiesNode) {
1799 Src = Src ? GL_REPEAT : GL_CLAMP_TO_EDGE;
1800 Trc = Trc ? GL_REPEAT : GL_CLAMP_TO_EDGE;
1801 Rrc = Rrc ? GL_REPEAT : GL_CLAMP_TO_EDGE;
1803 generateMipMaps = GL_TRUE;
1805 if (me->x > 0 && me->y > 0)
1819 if (me->x < me->y * me->z) ratio = (float)(me->y * me->z) / (float)me->x;
1820 else ratio = (float)me->x / (
float)(me->y * me->z);
1821 if (ratio > 2.0f) generateMipMaps = GL_FALSE;
1825 if ((me->x <= 256) || ((me->y * me->z) <= 256)) {
1826 minFilter = GL_NEAREST_MIPMAP_NEAREST;
1827 if (!generateMipMaps) minFilter = GL_NEAREST;
1828 magFilter = GL_NEAREST;
1831 minFilter = GL_LINEAR_MIPMAP_NEAREST;
1832 if (!generateMipMaps) minFilter = GL_LINEAR;
1833 magFilter = GL_LINEAR;
1845 if (getAppearanceProperties()->cubeFace != 0) {
1847 unsigned char* dest = me->texdata;
1856 iformat = GL_RGBA; format = GL_RGBA; itype = GL_UNSIGNED_BYTE;
1857 if (me->idepthbuffer) {
1858 iformat = GL_DEPTH_COMPONENT;
1859 format = GL_DEPTH_COMPONENT;
1866 if (getAppearanceProperties()->cubeFace == GL_TEXTURE_CUBE_MAP_POSITIVE_X) {
1867 FW_GL_TEXPARAMETERI(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1868 FW_GL_TEXPARAMETERI(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1869 FW_GL_TEXPARAMETERI(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1870 FW_GL_TEXPARAMETERI(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1871 FW_GL_TEXPARAMETERI(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1882 int cy, cyy, icsize;
1883 sp = (uint32*)me->texdata;
1884 for (cy = 0; cy < ry / 2; cy++) {
1886 for (cx = 0; cx < rx; cx += 512) {
1887 icsize = min(512, rx - cx - 1) * 4;
1888 memcpy(tp, &sp[cy * rx + cx], icsize);
1889 memcpy(&sp[cy * rx + cx], &sp[cyy * rx + cx], icsize);
1890 memcpy(&sp[cyy * rx + cx], tp, icsize);
1895 generateMipMaps = 0;
1896 myTexImage2D(generateMipMaps, getAppearanceProperties()->cubeFace, 0, iformat, rx, ry, 0, format, itype, dest);
1908 if (me->nodeType == NODE_ImageCubeMapTexture || me->nodeType == NODE_ComposedCubeMapTexture) {
1909 render_node(me->scenegraphNode);
1912 if (me->nodeType == NODE_GeneratedCubeMapTexture) {
1913 me->status = TEX_LOADED;
1948 mytexdata = me->texdata;
1949 if (mytexdata == NULL) {
1950 printf (
"mytexdata is null, texture failed, put something here\n");
1953 glBindTexture (GL_TEXTURE_2D, me->OpenGLTexture);
1974 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, Src);
1975 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, Trc);
1976#if !defined(GL_ES_VERSION_2_0)
1977 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, Rrc);
1978 FW_GL_TEXPARAMETERF(GL_TEXTURE_2D,GL_TEXTURE_PRIORITY, texPri);
1979 FW_GL_TEXPARAMETERFV(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,(GLfloat *)&borderColour);
1982#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1983 FW_GL_TEXPARAMETERF(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,anisotropicDegree);
1986 if (compression != GL_NONE) {
1987 iformat = GL_COMPRESSED_RGBA;
1991 npot = rdr_caps->av_npot_texture;
1996 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
1997 FW_GL_TEXPARAMETERI( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
1998 me->magFilter = magFilter == GL_LINEAR ? 1 : 0;
2009 unsigned char *dest = mytexdata;
2013 rx = x; ry = y; rz = z;
2016 static int round_down = 1;
2017 static int trunc_down = 0;
2020 while(sx) {sx /= 2; rx *= 2;}
2021 if(rx/2 == x) {rx /= 2;}
2024 if(x < rx && (
float)(x - rx/2)/(
float)(rx - rx/2) < .25) rx = rx/2;
2027 if(x < rx) rx = rx/2;
2030 while(sy) {sy /= 2; ry *= 2;}
2031 if(ry/2 == y) {ry /= 2;}
2033 if(y < ry && (
float)(y - ry/2)/(
float)(ry - ry/2) < .25) ry = ry/2;
2035 if(y < ry) ry = ry/2;
2039 while(sz) {sz /= 2; rz *= 2;}
2040 if(rz/2 == z) {rz /= 2;}
2042 if(z < rz && (
float)(z - rz/2)/(
float)(rz - rz/2) < .25) rz = rz/2;
2044 if(z < rz) rz = rz/2;
2047 if (gglobal()->internalc.global_print_opengl_errors) {
2048 DEBUG_MSG(
"initial texture scale to %d %d\n",rx,ry);
2054 int emulating3D_TILED;
2055 emulating3D_TILED = TRUE;
2056 generateMipMaps = FALSE;
2057 if(emulating3D_TILED){
2078 int rc,sc,c,cube_root, max_size;
2079 unsigned char *texdataTiles = NULL;
2081 int nx, ny, ix, iy, nxx, nyy;
2084 max_size = rdr_caps->runtime_max_texture_size;
2087 if(x * y * z > 256 * 256 * 256)
2088 max_size = min(max_size,4096);
2090 cube_root = (int)pow( max_size * max_size + 3, 1.0/3.0);
2095 while(sc) {sc /= 2; rc *= 2;}
2096 if(rc > c) {rc /= 2;}
2099 if(rx != x || ry != y || rz != z || rx > cube_root || ry > cube_root || rz > cube_root) {
2106 if (rx > cube_root) rx = cube_root;
2107 if (ry > cube_root) ry = cube_root;
2108 if (rz > cube_root) rz = cube_root;
2111 if (gglobal()->internalc.global_print_opengl_errors) {
2112 DEBUG_MSG(
"texture size after maxTextureSize taken into account: %d %d, from %d %d\n",rx,ry,x,y);
2120 if(x > rx || y > ry || z > rz){
2125 dest = MALLOC(
unsigned char *, 4 * rx * ry * rz);
2126 myScaleImage3D(x,y,z,mx,my,mz,mytexdata,dest);
2130 FREE_IF_NZ(me->texdata);
2135 if(me->channels == 1){
2137 compute_3D_alpha_gradient_store_rgb((
char *)dest,x,y,z);
2140 ny = (int) sqrt(z+1);
2142 nx = z - nx*ny > 0 ? nx+1 : nx;
2152 texdataTiles = MALLOC(
unsigned char *,nxx * nyy * 4);
2153 p2 = (uint32 *)texdataTiles;
2154 p1 = (uint32 *)dest;
2155 for(iz=0;iz<z;iz++){
2162 ifrom = (iz*y + j)*x + k;
2163 ito = (iy*y + j)*nxx + (ix*x) + k;
2171 textureTableIndexStruct_s tti2, *tti3;
2177 tti3->texdata = texdataTiles;
2178 saveImage_web3dit(tti3,
"test_tiled_texture.web3dit");
2181 myTexImage2D(generateMipMaps, GL_TEXTURE_2D, 0, iformat, nxx, nyy, 0, format, GL_UNSIGNED_BYTE, texdataTiles);
2182 ConsoleMessage(
"final texture2D size %d %d\n",nxx,nyy);
2183 FREE_IF_NZ(texdataTiles);
2184 if(dest != me->texdata) FREE_IF_NZ(dest);
2190 if(rx != x || ry != y || rx > rdr_caps->runtime_max_texture_size || ry > rdr_caps->runtime_max_texture_size) {
2197 rx = min(rx,rdr_caps->runtime_max_texture_size);
2198 ry = min(ry,rdr_caps->runtime_max_texture_size);
2201 if (gglobal()->internalc.global_print_opengl_errors) {
2202 DEBUG_MSG(
"texture size after maxTextureSize taken into account: %d %d, from %d %d\n",rx,ry,x,y);
2214 if(generateMipMaps){
2220 if ((x==rx) && (y==ry)) {
2226 size_t total_size = (size_t)4L * rx * ry;
2227 dest = MALLOC(
unsigned char *, total_size);
2229 myScaleImage(x,y,rx,ry,mytexdata,dest);
2231 if(rx > 8192 || ry > 8192) ConsoleMessage(
"texture size rx %d ry %d\n",rx,ry);
2232 myTexImage2D(generateMipMaps, GL_TEXTURE_2D, 0, iformat, rx, ry, 0, format, GL_UNSIGNED_BYTE, dest);
2234 if(mytexdata != dest) {
2240 FREE_IF_NZ (me->texdata);
2249 me->status = TEX_LOADED;
2252 pthread_mutex_unlock( &gl_mutex1 );
2277 int thisTextureType;
2286 textureTableIndexStruct_s *myTableIndex;
2290 ttglobal tg = gglobal();
2291 p = (ppTextures)tg->Textures.prv;
2296 thisTextureType = node->_nodeType;
2297 if (thisTextureType==NODE_ImageTexture){
2300 thisTexture = it->__textureTableIndex;
2301 }
else if (thisTextureType==NODE_PixelTexture){
2303 thisTexture = pt->__textureTableIndex;
2304 }
else if (thisTextureType == NODE_BufferTexture) {
2306 thisTexture = bt->__textureTableIndex;
2307 }
else if (thisTextureType == NODE_GeneratedTexture) {
2309 thisTexture = gt->__textureTableIndex;
2310 }
else if (thisTextureType==NODE_MovieTexture){
2312 thisTexture = mt->__textureTableIndex;
2314 }
else if (thisTextureType == NODE_ComposedCubeMapTexture) {
2316 thisTexture = ict->__textureTableIndex;
2318 }
else if (thisTextureType==NODE_ImageCubeMapTexture){
2320 thisTexture = ict->__textureTableIndex;
2322 }
else if (thisTextureType==NODE_GeneratedCubeMapTexture){
2324 thisTexture = gct->__textureTableIndex;
2325 }
else if (thisTextureType==NODE_PixelTexture3D){
2328 thisTexture = pt3d->__textureTableIndex;
2329 }
else if (thisTextureType==NODE_ImageTexture3D){
2332 thisTexture = pt3d->__textureTableIndex;
2334 }
else if (thisTextureType==NODE_ComposedTexture3D){
2337 thisTexture = pt3d->__textureTableIndex;
2339 ConsoleMessage (
"Invalid type for texture, %s\n",stringNodeType(thisTextureType));
2343 myTableIndex = getTableIndex(thisTexture);
2344 if (myTableIndex->status != TEX_LOADED) {
2345 DEBUG_TEX(
"new_bind_image, I am %p, textureStackTop %d, thisTexture is %d myTableIndex %p status %s\n",
2346 node,tg->RenderFuncs.textureStackTop,thisTexture,myTableIndex, texst(myTableIndex->status));
2352 tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop] = tg->Textures.defaultBlankTexture;
2353 switch (myTableIndex->status) {
2355 DEBUG_TEX(
"feeding texture %p to texture thread...\n", myTableIndex);
2356 if(mfurl && mfurl->n == 0) {
2358 myTableIndex->status = TEX_NEEDSBINDING;
2360 myTableIndex->status = TEX_LOADING;
2361 send_texture_to_loader(myTableIndex);
2367 DEBUG_TEX(
"I've to wait for %p...\n", myTableIndex);
2370 case TEX_NEEDSBINDING:
2371 DEBUG_TEX(
"texture loaded into memory... now lets load it into OpenGL...\n");
2372 if (myTableIndex->no_gl == 0) {
2373 move_texture_to_opengl(myTableIndex);
2378 if (myTableIndex->status != TEX_LOADED) {
2379 printf(
"issue going from TEX_NEEDSBINDING to TEX_LOADED, is %s\n",
2380 texst(myTableIndex->status));
2392 if (myTableIndex->hasAlpha) tg->RenderFuncs.last_texture_type = TEXTURE_ALPHA;
2393 else tg->RenderFuncs.last_texture_type = TEXTURE_NO_ALPHA;
2397 if (myTableIndex->OpenGLTexture == TEXTURE_INVALID) {
2399 DEBUG_TEX(
"no openGLtexture here status %s\n", texst(myTableIndex->status));
2403 tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop] = myTableIndex->OpenGLTexture;
2410 if (param != NULL) {
2412 memcpy(&(textureParameterStack[tg->RenderFuncs.textureStackTop]), param,sizeof (
struct multiTexParams));
2415 p->textureInProcess = -1;
2418 case TEX_UNSQUASHED:
2420 printf (
"unknown texture status %d\n",myTableIndex->status);
2426int get_bound_image(
struct X3D_Node *node) {
2428 int thisTextureType;
2437 textureTableIndexStruct_s *myTableIndex;
2441 ttglobal tg = gglobal();
2442 p = (ppTextures)tg->Textures.prv;
2447 thisTextureType = node->_nodeType;
2448 if (thisTextureType==NODE_ImageTexture){
2451 thisTexture = it->__textureTableIndex;
2452 }
else if (thisTextureType==NODE_PixelTexture){
2454 thisTexture = pt->__textureTableIndex;
2455 }
else if (thisTextureType == NODE_BufferTexture) {
2457 thisTexture = bt->__textureTableIndex;
2458 }
else if (thisTextureType == NODE_GeneratedTexture) {
2460 thisTexture = gt->__textureTableIndex;
2461 }
else if (thisTextureType==NODE_MovieTexture){
2463 thisTexture = mt->__textureTableIndex;
2465 }
else if (thisTextureType == NODE_ComposedCubeMapTexture) {
2467 thisTexture = ict->__textureTableIndex;
2469 }
else if (thisTextureType==NODE_ImageCubeMapTexture){
2471 thisTexture = ict->__textureTableIndex;
2473 }
else if (thisTextureType==NODE_GeneratedCubeMapTexture){
2475 thisTexture = gct->__textureTableIndex;
2476 }
else if (thisTextureType==NODE_PixelTexture3D){
2479 thisTexture = pt3d->__textureTableIndex;
2480 }
else if (thisTextureType==NODE_ImageTexture3D){
2483 thisTexture = pt3d->__textureTableIndex;
2485 }
else if (thisTextureType==NODE_ComposedTexture3D){
2488 thisTexture = pt3d->__textureTableIndex;
2490 ConsoleMessage (
"Invalid type for texture, %s\n",stringNodeType(thisTextureType));
2494 myTableIndex = getTableIndex(thisTexture);
2495 return myTableIndex->OpenGLTexture;