TumblerSource/Tumbler_PICTImport.c

#include "Tumbler_globals.h"
#include "Tumbler_prototypes.h"
#include "QD3DShader.h"
#include "QD3DStorage.h"
 
#include "Tumbler_PICTImport.h"
 
 
TQ3Boolean TextureFromPICT(
    PicHandle           pict,
    TQ3StoragePixmap    *bmap)
{
    unsigned long           *texture_map;
    unsigned char           *texture_map_addr;
    unsigned long           *pict_map;
    unsigned long           pict_map_addr;
    register unsigned long  row;
    register unsigned long  col;
    Rect                    rectGW;
    GWorldPtr               pGWorld;
    PixMapHandle            hPixMap;
    unsigned long           pict_rowbytes;
    
    GDHandle                oldGD;
    GWorldPtr               oldGW;
    
    unsigned long           textureSize;
    
    /* save current port */
    GetGWorld(&oldGW, &oldGD);
 
    rectGW = (*pict)->picFrame;
    
    /* create the GWorld */
    if(NewGWorld(&pGWorld, 32, &rectGW, 0, 0, 0) != noErr) {
        Alert(130, 0L);
        return(kQ3False);
    }
    
    
    if(pGWorld == nil) {
        Alert(130, 0L);
        return(kQ3False);
    }
 
    hPixMap = GetGWorldPixMap(pGWorld);
    pict_map_addr = (unsigned long) GetPixBaseAddr (hPixMap);
    pict_rowbytes = (unsigned long)(**hPixMap).rowBytes & 0x3fff;
    
    /* put the PICT into the window */
    SetGWorld(pGWorld, nil);
    
    LockPixels(hPixMap);
    EraseRect(&rectGW);
    DrawPicture(pict, &rectGW);
        
    /* allocate an area of memory for the texture */
 
    textureSize = (rectGW.right - rectGW.left) * (rectGW.bottom - rectGW.top) * sizeof(unsigned long);
 
    texture_map = (unsigned long *)NewPtr(textureSize);
    if (texture_map == nil) {
        Alert(130, 0L);
        return(kQ3False);
    }
    
    bmap->width = rectGW.right - rectGW.left;
    bmap->height = rectGW.bottom - rectGW.top;
    bmap->rowBytes = bmap->width * 4;
    bmap->pixelSize = 32;
    bmap->pixelType = kQ3PixelTypeRGB32;
    bmap->bitOrder = kQ3EndianBig ;
    bmap->byteOrder = kQ3EndianBig ;
 
    /* copy the PICT into the texture */
    texture_map_addr = (unsigned char *) texture_map;
    for (row = 0L; row < bmap->height; row++) {
        pict_map = (unsigned long *)(pict_map_addr + (pict_rowbytes * row));
        for (col = 0L; col < bmap->width; col++) {
            *texture_map++ = (*pict_map++|0xff000000L);
        }
    }
    
    bmap->image = Q3MemoryStorage_New(texture_map_addr, textureSize);
 
    UnlockPixels(hPixMap);
    
    /* restore port */
    SetGWorld(oldGW, oldGD);
    
    /* free GWorld */
    DisposeGWorld(pGWorld);
    
    DisposePtr((Ptr)texture_map_addr);
    
    return(kQ3True);
}
 
TQ3Status AddTextureToDocument(DocumentPtr theDocument, TQ3StoragePixmap *textureImage)
{
    TQ3TextureObject    textureObject;
    TQ3GroupPosition position;
    TQ3Object       firstObject;
    
    textureObject = Q3PixmapTexture_New(textureImage);
    
    if( textureObject ) {
        if( Q3Object_IsType(theDocument->documentGroup, kQ3GroupTypeDisplay) == kQ3True) {
            Q3Group_GetFirstPosition(theDocument->documentGroup, &position);
    
            Q3Group_GetPositionObject(theDocument->documentGroup, position, &firstObject);
    
            if( Q3Object_IsType(firstObject, kQ3SurfaceShaderTypeTexture) == kQ3True) {
                TQ3TextureObject    oldTextureObject;
                TQ3StoragePixmap oldTextureImage;
                        
                Q3TextureShader_GetTexture(firstObject, &oldTextureObject);
                Q3PixmapTexture_GetPixmap(oldTextureObject, &oldTextureImage);
                
                Q3Object_Dispose(oldTextureObject);
                Q3TextureShader_SetTexture(firstObject, textureObject);
                Q3Object_Dispose(textureObject);
            } else {
                TQ3ShaderObject textureShader;
                
                textureShader = Q3TextureShader_New(textureObject);
                Q3Object_Dispose(textureObject);
                //Q3Group_SetPositionObject(theDocument->documentGroup, position, theDocument->textureShader);
                Q3Group_AddObjectBefore(theDocument->documentGroup, position, textureShader);
                Q3Object_Dispose(textureShader);
            }
            
            Q3Object_Dispose(firstObject);
        } else if( Q3Object_IsType(theDocument->documentGroup, kQ3DisplayGroupTypeOrdered) == kQ3True) {
            TQ3ShaderObject textureShader;
            
            Q3Group_GetFirstPositionOfType(
                theDocument->documentGroup,
                kQ3ShapeTypeShader, &position); 
            
            if( position ) {
                Q3Group_GetPositionObject(theDocument->documentGroup, position, &firstObject);
    
                if( Q3Object_IsType(firstObject, kQ3SurfaceShaderTypeTexture) == kQ3True) {
                    TQ3TextureObject    oldTextureObject;
                    TQ3StoragePixmap oldTextureImage;
                    
                    Q3TextureShader_GetTexture(firstObject, &oldTextureObject);
                    Q3PixmapTexture_GetPixmap(oldTextureObject, &oldTextureImage);
                    
                    Q3Object_Dispose(oldTextureObject);
                    Q3TextureShader_SetTexture(firstObject, textureObject);
                    Q3Object_Dispose(textureObject);
                } else {
                    textureShader = Q3TextureShader_New(textureObject);
                    if( textureShader ) {
                        Q3Object_Dispose(textureObject);
                        Q3Group_SetPositionObject(theDocument->documentGroup, position, textureShader);
                        Q3Object_Dispose(textureShader);
                    } else {
                        return(kQ3Failure);
                    }
                }
            } else {
                textureShader = Q3TextureShader_New(textureObject);
                if( textureShader ) {
                    Q3Object_Dispose(textureObject);
                    Q3Group_AddObject(theDocument->documentGroup, textureShader);
                    Q3Object_Dispose(textureShader);
                } else {
                    return(kQ3Failure);
                }
            }
            
        }
    return(kQ3Success);
    } else {
        return(kQ3Failure);
    }
}