TumblerSource/Tumbler_offscreen.c

//
//      Offscreen.c
//
// To Do:
//
// This thing calls updateGWorld each time through, this is slow, fix
//
 
#include "QD3D.h"
#include "QD3DDrawContext.h"
#include "QD3DShader.h"
#include "QD3DGeometry.h"
#include "QD3DStyle.h"
#include "QD3DTransform.h"
#include "QD3DMath.h"
 
 
#include "Tumbler_globals.h"
#include "Tumbler_prototypes.h"
#include "Tumbler_offscreen.h"
#include "Tumbler_windows.h"
 
 
 
TQ3Status DrawOffscreen(DocumentPtr theDocument)
 
{
 
    if( theDocument->documentGroup ) {
 
        RgnHandle   windowRgn, growRgn, clipRgn;
        Rect        growRect;
        TQ3Vector3D globalScale;
        TQ3Vector3D globalTranslate;
        
        globalScale.x = globalScale.y = globalScale.z = theDocument->documentGroupScale;
        globalTranslate = *(TQ3Vector3D *)&theDocument->documentGroupCenter;
        Q3Vector3D_Scale(&globalTranslate, -1, &globalTranslate);
    
        SetPort(theDocument->theWindow);
    
        growRect = theDocument->theWindow->portRect;
        growRect.top = growRect.bottom -15;
        growRect.left = growRect.right -15;
 
        growRgn = NewRgn();
        RectRgn(growRgn, &growRect);
        
        windowRgn = NewRgn();
        RectRgn(windowRgn, &theDocument->theWindow->portRect);
        
        clipRgn = NewRgn();
        DiffRgn(windowRgn, growRgn, clipRgn);
        
        SetClip(clipRgn);
        
        Q3View_StartRendering(theDocument->theView);
        
        do {                
            TQ3SubdivisionStyleData     subData = {kQ3SubdivisionMethodConstant, 20, 20};
        
            Q3Shader_Submit(theDocument->illuminationShader, theDocument->theView);
 
            if( theDocument->light == kQ3True ) {
                Q3Object_Submit(theDocument->light1, theDocument->theView);
                Q3Object_Submit(theDocument->light2, theDocument->theView);
                Q3Object_Submit(theDocument->light3, theDocument->theView);
            }
        
            if( theDocument->shaded == kQ3True )
                Q3Style_Submit(theDocument->backfacingStyle, theDocument->theView) ;
                                
            Q3InterpolationStyle_Submit(theDocument->currentInterpolation,theDocument->theView);
            
            Q3SubdivisionStyle_Submit( &subData,theDocument->theView);
            
            Q3MatrixTransform_Submit( &theDocument->modelRotation, theDocument->theView);
            Q3ScaleTransform_Submit(&globalScale, theDocument->theView);
            Q3TranslateTransform_Submit(&globalTranslate, theDocument->theView);
                        
            Q3DisplayGroup_Submit(theDocument->documentGroup, theDocument->theView);
            
        } while (Q3View_EndRendering(theDocument->theView) == kQ3ViewStatusRetraverse);
 
        ClipRect(&theDocument->theWindow->portRect);
        DisposeRgn(clipRgn);
        DisposeRgn(windowRgn);
        DisposeRgn(growRgn);
    } else {
    
        Rect    theRect = theDocument->theWindow->portRect;
 
#ifndef PODIUM_APP
        // only want to color the bg for Tumbler
        RGBColor color = { 0xFFFF, 0xFFFF, 0xFFFF};
        
        color.red *= theDocument->clearColor.r;
        color.green *= theDocument->clearColor.g;
        color.blue *= theDocument->clearColor.b;
        
        RGBBackColor(&color);
#endif
 
        EraseRect( &theRect );
        
#ifndef PODIUM_APP
        color.blue = color.green = color.red  =  0xFFFF;
        RGBBackColor(&color);
#endif
 
    }
 
    
    return(kQ3Success);
}
 
 
 
void DrawOnscreen(DocumentPtr theDocument)
{
#if 0
    Rect    srcRect, dstRect;
    CGrafPtr    savedPort ;
    GDHandle    savedDevice ;
 
    if(theDocument->theOffscreen == nil || theDocument->theOffscreen->offscreenWorld == nil) {
        // Draw Offscreen will allocate them
        if( DrawOffscreen(theDocument) == nil)
            return;
    }
    
    srcRect = theDocument->theOffscreen->offscreenWorld->portRect;
    dstRect = theDocument->theWindow->portRect;
    
    if(!EqualRect(&theDocument->theOffscreen->offscreenWorld->portRect, &dstRect) ) {
        /* Size of the window changed */
        if( DrawOffscreen(theDocument) == nil)
            return;
    }
 
    srcRect.right  -= 15;
    srcRect.bottom -= 15;
 
    dstRect.right  -= ;
    dstRect.bottom -= ;
    
    GetGWorld(&savedPort,&savedDevice);
    SetGWorld(theDocument->theOffscreen->windowPort, theDocument->theOffscreen->windowDevice);
    
    CopyBits(&((GrafPtr) theDocument->theOffscreen->offscreenWorld)->portBits,
             (BitMap *) &(theDocument->theOffscreen->windowPort)->portPixMap,
             &srcRect, &dstRect, srcCopy, 0L);
        
    SetGWorld( savedPort, savedDevice);
#else
    TQ3DrawContextObject        drawCtx;
    RgnHandle               oldClip;
    Rect                    contentRect;
    GrafPtr                 savedPort ;
    
    GetPort( &savedPort ) ;
    SetPort(theDocument->theWindow);
    
    oldClip = NewRgn();
    GetClip(oldClip);
 
    contentRect = theDocument->theWindow->portRect;
//  contentRect.bottom -= 15;
//  contentRect.right -= 15;
    ClipRect(&contentRect);
 
#ifndef PODIUM_APP
    DoDrawGrowIcon(theDocument->theWindow);
#else
    
    // copy the background picture to the offscreen buffer and 
    // composite the geometry image
    {
        CGrafPtr        savedPort ;
        GDHandle        savedGDH ;
        OSErr           theErr ;
        
        GetGWorld( &savedPort, &savedGDH ) ;
        SetGWorld( theDocument->screenBuffer, nil ) ;
    
        // this is the background picture
        CopyBits(&((GrafPtr) theDocument->bgOffscreen)->portBits,
                 &((GrafPtr) theDocument->screenBuffer)->portBits,
                 &theDocument->bgOffscreen->portRect, 
                 &theDocument->bgOffscreen->portRect, 
                 srcCopy, 
                 0L);
    
        // only copy from the offscreen if there is 
        // a valid group in the document
        
        if( theDocument->documentGroup != NULL ) {
            
                         
            CopyBits(&((GrafPtr) theDocument->geometriesOffscreen)->portBits,
                     &((GrafPtr) theDocument->screenBuffer)->portBits,
                     &theDocument->geometriesOffscreen->portRect, 
                     &theDocument->dropArea, 
                     srcCopy | transparent, 
                     0L);
        }
        SetGWorld( (CGrafPtr)theDocument->theWindow, nil ) ;
        
        CopyBits(&((GrafPtr) theDocument->screenBuffer)->portBits,
                 &theDocument->theWindow->portBits,
                 &theDocument->screenBuffer->portRect, 
                 &theDocument->screenBuffer->portRect, 
                 srcCopy, 
                 0L);
        
        
        SetGWorld( savedPort, savedGDH ) ;
    }
 
#endif
    
 
    SetClip(oldClip);
    DisposeRgn(oldClip);
    SetPort( savedPort ) ;
#endif
}