| | /*
Copyright (c)The 3Delight Team.
All Rights Reserved.
*/
//
// = LIBRARY
// 3delight
// = AUTHOR(S)
// Aghiles Kheffache
// = VERSION
// $Revision: 1.4 $
// = DATE RELEASED
// $Date: 2003/06/30 19:30:17 $
// = RCSID
// $Id: zfile.cpp,v 1.4 2003/06/30 19:30:17 aghiles Exp $
//
#include <ndspy.h>
#include <uparam.h>
#include <assert.h>
#include <stdio.h>
#include <float.h>
#include <string.h>
#include <limits.h>
/* ZFile Display Driver Implementation */
const unsigned kDefaultZFileSize = 512;
/*
zfile format:
zFile format is (matrices and image are row-major):
magic # (0x2f0867ab) (4 bytes)
width (short) (2 bytes)
height (short) (2 bytes)
shadow matrices (32 floats, 16 for NP and 16 for Nl) (128 bytes)
image data (floats) (width*height*4 bytes)
NOTE
Matrices are stored in row major format.
*/
class zFile
{
public:
zFile(
const char* fileName,
const float* np, const float* nl,
unsigned short width, unsigned short height )
: m_file(0x0), m_width(width), m_height(height),
m_currentLine(0), m_pixelsLeftOnLine(width)
{
m_file = fopen( fileName, "wb" );
if( m_file )
{
unsigned long magic = 0x2f0867ab;
assert( sizeof(long) == 4 );
fwrite( &magic, 4, 1, m_file );
fwrite( &m_width, sizeof(m_width), 1, m_file );
fwrite( &m_height, sizeof(m_height), 1, m_file );
fwrite( np, sizeof(float), 16, m_file );
fwrite( nl, sizeof(float), 16, m_file );
}
}
~zFile()
{
if( m_file )
{
fclose(m_file);
}
}
bool Valid() const { return m_file != 0x0; }
unsigned GetWidth() const {return m_width;}
unsigned GetHeight() const {return m_height;}
bool WriteScanline(
unsigned short y, unsigned short size, const float* data )
{
if( y != m_currentLine || size > m_pixelsLeftOnLine )
{
return false;
}
m_pixelsLeftOnLine -= size;
if( m_pixelsLeftOnLine == 0 )
{
++m_currentLine;
m_pixelsLeftOnLine = m_width;
}
return fwrite( data, sizeof(float), size, m_file ) == size;
}
private:
FILE* m_file;
unsigned short m_width;
unsigned short m_height;
unsigned short m_currentLine;
unsigned short m_pixelsLeftOnLine;
};
/*
A utility function to get user parameters ...
*/
const void* GetParameter(
const char *name,
unsigned n,
const UserParameter parms[] )
{
for( unsigned i=0; i<n; i++ )
{
if(0 == strcmp(name, parms[i].name))
{
return parms[i].value;
}
}
return 0x0;
}
/*
Open
*/
PtDspyError DspyImageOpen(
PtDspyImageHandle *i_phImage,
const char *i_drivername,
const char *i_filename,
int i_width, int i_height,
int i_parametercount,
const UserParameter i_parameters[],
int i_numFormat,
PtDspyDevFormat i_format[],
PtFlagStuff *flagstuff )
{
int i;
bool zfound = false;
const float* nl =
(float*)GetParameter( "Nl", i_parametercount, i_parameters );
const float* np =
(float*)GetParameter( "NP", i_parametercount, i_parameters );
/* Loop through all provided data channels and only ask for the 'z'
channel. */
for( i=0; i<i_numFormat; i++ )
{
if( strcmp(i_format[i].name, "z") != 0 )
{
i_format[i].type = PkDspyNone;
}
else
{
i_format[i].type = PkDspyFloat32;
zfound = true;
}
}
if( !zfound )
{
fprintf( stderr, "dspy_z : need 'z' in order to proceed.\n" );
return PkDspyErrorUnsupported;
}
if( !nl || !np )
{
fprintf(
stderr,
"dspy_z : need Nl & Np matrices in order to proceed. bug.\n" );
return PkDspyErrorBadParams;
}
if (i_width > USHRT_MAX || i_height > USHRT_MAX)
{
fprintf(
stderr,
"dspy_z : image too large for zfile format" \
" (use shadowmap ddriver).\n" );
return PkDspyErrorUndefined;
}
zFile* aZFile = new zFile( i_filename, np, nl, i_width, i_height );
if( !aZFile || !aZFile->Valid() )
{
fprintf(
stderr,
"dspy_z : cannot create file" \
"(permissions ? free disk space ?).\n" );
delete aZFile;
return PkDspyErrorNoResource;
}
*i_phImage = (void*) aZFile;
/* Ask display manager to provide data scanline by scanline
*/
flagstuff->flags |= PkDspyFlagsWantsScanLineOrder;
return PkDspyErrorNone;
}
/*
DspyImageQuery
*/
PtDspyError DspyImageQuery(
PtDspyImageHandle i_hImage,
PtDspyQueryType i_type,
size_t i_datalen,
void *i_data )
{
zFile *aZFile = (zFile*) i_hImage;
if( !i_data )
{
return PkDspyErrorBadParams;
}
switch( i_type )
{
case PkSizeQuery:
{
PtDspySizeInfo sizeQ;
if( aZFile )
{
sizeQ.width = aZFile->GetWidth();
sizeQ.height = aZFile->GetHeight();
sizeQ.aspectRatio = 1;
}
else
{
sizeQ.width = kDefaultZFileSize;
sizeQ.height = kDefaultZFileSize;
sizeQ.aspectRatio = 1;
}
memcpy(
i_data, &sizeQ,
i_datalen>sizeof(sizeQ) ? sizeof(sizeQ) : i_datalen );
break;
}
case PkOverwriteQuery:
{
PtDspyOverwriteInfo overwQ;
overwQ.overwrite = 1;
memcpy(
i_data, &overwQ,
i_datalen>sizeof(overwQ) ? sizeof(overwQ) : i_datalen );
break;
}
default:
return PkDspyErrorUnsupported;
}
return PkDspyErrorNone;
}
/*
DspyImageData
Data is expected in scanline order (as asked in DspyImageOpen()).
*/
PtDspyError DspyImageData(
PtDspyImageHandle i_hImage,
int i_xmin, int i_xmax_plusone,
int i_ymin, int i_ymax_plusone,
int i_entrySize,
const unsigned char* i_data )
{
zFile* aZFile = (zFile*) i_hImage;
const float* fdata = (const float*) i_data;
if( !aZFile || !fdata )
{
return PkDspyErrorBadParams;
}
/* Perform some sanity checks but everything should be fine really ...
:> */
if( i_ymax_plusone - i_ymin > 1 ||
i_xmin != 0 ||
i_xmax_plusone != aZFile->GetWidth() ||
i_entrySize != sizeof(float) )
{
return PkDspyErrorBadParams;
}
if( !aZFile->WriteScanline(i_ymin, i_xmax_plusone - i_xmin, fdata) )
{
return PkDspyErrorNoResource;
}
return PkDspyErrorNone;
}
/*
DspyImageDelayClose
Not used by 3Delight yet.
*/
PtDspyError DspyImageDelayClose( PtDspyImageHandle i_hImage )
{
return DspyImageClose( i_hImage );
}
/*
DspyImageClose
delete our object.
*/
PtDspyError DspyImageClose( PtDspyImageHandle i_hImage )
{
zFile* aZFile = (zFile*) i_hImage;
if( !aZFile )
{
return PkDspyErrorUndefined;
}
delete aZFile;
return PkDspyErrorNone;
}
This document was generated
by Aghiles Kheffache on July, 31 2003
using texi2html
3Delight 1.0.0. Copyright 2000-2003 The 3Delight Team.
All Rights Reserved.
|
|