MercuryDisplaySoftwareC.cpp

Go to the documentation of this file.
00001 #include "MercuryDisplaySoftwareC.h"
00002 #include "MercuryLog.h"
00003 
00004 int MercuryDisplaySoftwareC::m_bypp;
00005 int MercuryDisplaySoftwareC::m_height;
00006 int MercuryDisplaySoftwareC::m_width;
00007 bool MercuryDisplaySoftwareC::m_zBufferWrite;
00008 unsigned char * MercuryDisplaySoftwareC::m_cBuffer;
00009 unsigned int * MercuryDisplaySoftwareC::m_zBuffer;
00010 
00011 MercuryDisplaySoftwareC::MercuryDisplaySoftwareC()
00012 {
00013     bDepthTest = false;
00014     m_InternalTextures.resize(1);
00015     m_pCurTexture = &m_InternalTextures[0];
00016     m_pCurTexture->m_isMaterial = false;
00017     m_pCurTexture->m_isInUse = false;
00018 }
00019 /*
00020 void MercuryDisplaySoftwareC::Init()
00021 {
00022     MercuryDisplay::Init();
00023 }
00024 */
00025 bool MercuryDisplaySoftwareC::EndFrame()
00026 {
00027     m_window->SwapBuffers();
00028     memset( m_cBuffer, 0, m_width * m_height * m_bypp );
00029     ClearZBuffer();
00030     m_cBuffer = m_window->GetBackDirectBuffer();
00031     ToggleZBufferWrite( true );
00032     ++m_framesDrawn;
00033 
00034     return true;
00035 }
00036 
00037 bool MercuryDisplaySoftwareC::MakeWindow(const char* title, int width, int height, int bits, bool fullscreenflag)
00038 {
00039     m_width = width;
00040     m_height = height;
00041     m_bypp = bits/8;
00042 
00043     m_VPx = 0;
00044     m_VPy = 0;
00045     m_VPwidth = width;
00046     m_VPheight = height;
00047 
00048     if (m_window == NULL)
00049         return false;
00050 
00051     if (!m_window->MakeRender(title,width,height,bits,fullscreenflag,RT_SW))
00052     {
00053         m_window->DestroyWindowAndRender();
00054         return false;
00055     }
00056 
00057     MercuryDisplay::MakeWindow(title, width, height, bits, fullscreenflag);
00058 
00059     m_cBuffer = m_window->GetBackDirectBuffer();
00060     m_zBuffer = new unsigned int[width*height];
00061 
00062     return true;
00063 }
00064 
00065 void MercuryDisplaySoftwareC::DeleteTextures( int n, unsigned int *textureNames )
00066 {
00067     m_InternalTextures[*textureNames].m_isInUse = false;
00068     SAFE_DELETE( m_InternalTextures[*textureNames].m_data );
00069 }
00070 
00071 void MercuryDisplaySoftwareC::DrawMesh(const MercuryMesh& mesh)
00072 {
00073     static int iPointsPerPoly;
00074     static InternalPoint Points[4];
00075     static MercuryVertex* V;
00076     static InternalPoint NewPoints[20000];
00077     static const unsigned int* I;
00078 
00079     switch(mesh.GetDrawType())
00080     {
00081     case MGL_TRIANGLE:  iPointsPerPoly = 3; break;
00082     case MGL_QUAD:      iPointsPerPoly = 4; break;
00083     case MGL_POINT:     iPointsPerPoly = 1; break;
00084     default: return;
00085     };
00086 
00087     V = (MercuryVertex*)mesh.GetVerticePtr();
00088 
00089     m_verticesDrawn += mesh.NumIndices();
00090     I = mesh.GetIndicesPtr();
00091 
00092     for( unsigned i = 0; i < mesh.NumVertices(); i++ )
00093     {
00094         InternalPipelinePoint( V[i].GetPointHandle(), NewPoints[i] );
00095         V[i].GetUV( &NewPoints[i].u );
00096     }
00097 
00098     for( unsigned j = 0; j < mesh.NumIndices(); j+=iPointsPerPoly )
00099     {
00100         Points[0] = NewPoints[I[j]];
00101         Points[1] = NewPoints[I[j+1]];
00102         Points[2] = NewPoints[I[j+2]];
00103         InternalDrawPoly( &Points[0], iPointsPerPoly );
00104     }
00105 }
00106 
00107 void MercuryDisplaySoftwareC::SetMaterial(const MercuryMaterial* material)
00108 {
00109     m_pCurMaterial.m_alpha = material->m_alpha;
00110     m_pCurMaterial.m_ambient = material->m_ambient;
00111     m_pCurMaterial.m_diffuse = material->m_diffuse;
00112     m_pCurMaterial.m_emissive = material->m_emissive;
00113 }
00114 
00115 void MercuryDisplaySoftwareC::ClearZBuffer() 
00116 {
00117     memset( m_zBuffer, 0x00, m_width * m_height * 4 );
00118 }
00119 
00120 void MercuryDisplaySoftwareC::UpdateTextureData(MercuryTexture* texture, unsigned int& ID)
00121 {
00122 //  memcpy( m_InternalTextures[ID].m_data, texture->GetRaw(), texture->GetWidth() * texture->GetHeight() * ColorBytesToSize( texture->GetColorByteType() ) );
00123 }
00124 
00125 void MercuryDisplaySoftwareC::CreateCache(MercuryTexture* texture, unsigned int& ID)
00126 {
00127     for( ID = 1; ID < m_InternalTextures.size(); ID++ )
00128         if( !m_InternalTextures[ID].m_isInUse )
00129             break;
00130     
00131     if( ID >= m_InternalTextures.size() )
00132     {
00133         m_InternalTextures.resize( ID+1 );
00134         m_InternalTextures[ID].m_isInUse = false;
00135     }
00136     if( m_InternalTextures[ID].m_isInUse )
00137         SAFE_DELETE( m_InternalTextures[ID].m_data );
00138     int bypp = ColorBytesToSize( texture->GetColorByteType() );
00139     m_InternalTextures[ID].m_data = new unsigned char[texture->GetWidth() * texture->GetHeight() * bypp];
00140 //  memcpy( m_InternalTextures[ID].m_data, texture->GetRaw(), texture->GetWidth() * texture->GetHeight() * bypp );
00141     m_InternalTextures[ID].m_height = texture->GetHeight();
00142     m_InternalTextures[ID].m_width = texture->GetWidth();
00143     m_InternalTextures[ID].m_isInUse = true;
00144     m_InternalTextures[ID].m_isMaterial = true;
00145     m_InternalTextures[ID].m_type = texture->GetColorByteType();
00146 //  m_InternalTextures[ID].m_TexMat = texture->GetFinalMatrix();
00147 }
00148 
00149 void MercuryDisplaySoftwareC::CreateCache(RawImageData* data, unsigned int& ID)
00150 {
00151     for( ID = 0; ID+1 < m_InternalTextures.size(); ID++ )
00152         if( !m_InternalTextures[ID+1].m_isInUse )
00153             break;
00154     
00155     if( ID+1 >= m_InternalTextures.size() )
00156     {
00157         m_InternalTextures.resize( ID+2 );
00158         m_InternalTextures[ID+1].m_isInUse = false;
00159     }
00160     if( m_InternalTextures[ID+1].m_isInUse )
00161         SAFE_DELETE( m_InternalTextures[ID+1].m_data );
00162     int bypp = ColorBytesToSize( data->attrs.m_ColorByteType );
00163     m_InternalTextures[ID+1].m_data = new unsigned char[data->attrs.m_height * data->attrs.m_width * bypp];
00164     memcpy( m_InternalTextures[ID+1].m_data, data->data, data->attrs.m_height * data->attrs.m_width * bypp );
00165     m_InternalTextures[ID+1].m_height = data->attrs.m_height;
00166     m_InternalTextures[ID+1].m_width = data->attrs.m_width;
00167     m_InternalTextures[ID+1].m_isInUse = true;
00168     m_InternalTextures[ID+1].m_isMaterial = true;
00169     m_InternalTextures[ID+1].m_type = data->attrs.m_ColorByteType;
00170     ID++;
00171 }
00172 
00173 void MercuryDisplaySoftwareC::EnableTextures(MercuryMaterial* material)
00174 {
00175     int iTextureID = 0;
00176     if( material->NumTextures() != 0 )
00177     {
00178         m_pCurMercuryTexture = material->GetTexture(0);
00179         iTextureID = m_pCurMercuryTexture->GetID();
00180     }
00181 
00182     m_pCurTexture = &m_InternalTextures[ iTextureID ];
00183 
00184     if( material->NumTextures() != 0 )
00185     {
00186         material->EditTexture(0)->Prerender();
00187         m_pCurTexture->m_TexMat = material->EditTexture(0)->GetFinalMatrix();
00188     }
00189 }
00190 
00191 void MercuryDisplaySoftwareC::ReadFrameBuffer(RawImageData& image)
00192 {
00193     image.attrs.m_ColorByteType = RGB;
00194     image.attrs.m_dpi_x = 72;
00195     image.attrs.m_dpi_y = 72;
00196     image.attrs.m_height = m_window->GetHeight();
00197     image.attrs.m_width = m_window->GetWidth();
00198     image.data = new unsigned char[m_window->GetHeight() * m_window->GetWidth() * 3];
00199     for( int x = 0; x < m_window->GetWidth(); x++ )
00200         for( int y = 0; y < m_window->GetHeight(); y++ )
00201         {
00202             image.data[(x + (m_window->GetHeight()-1-y) * m_window->GetWidth())*3 + 2] = m_cBuffer[(x + y * m_window->GetWidth())*m_bypp + 0];
00203             image.data[(x + (m_window->GetHeight()-1-y) * m_window->GetWidth())*3 + 1] = m_cBuffer[(x + y * m_window->GetWidth())*m_bypp + 1];
00204             image.data[(x + (m_window->GetHeight()-1-y) * m_window->GetWidth())*3 + 0] = m_cBuffer[(x + y * m_window->GetWidth())*m_bypp + 2];
00205         }
00206 }
00207 
00208 void SWCVectorMultiply( MercuryMatrix &m, float *p, float *out )
00209 {
00210     out[0] = p[0] * m[0][0] + p[1] * m[1][0] + p[2] * m[2][0] + p[3] * m[3][0];
00211     out[1] = p[0] * m[0][1] + p[1] * m[1][1] + p[2] * m[2][1] + p[3] * m[3][1];
00212     out[2] = p[0] * m[0][2] + p[1] * m[1][2] + p[2] * m[2][2] + p[3] * m[3][2];
00213     out[3] = p[0] * m[0][3] + p[1] * m[1][3] + p[2] * m[2][3] + p[3] * m[3][3];
00214 }
00215 
00216 void MercuryDisplaySoftwareC::InternalPipelinePoint( const MercuryPoint &pIn, InternalPoint &pOut )
00217 {
00218     //PRE-VERTEX-SHADER
00219     static float fi[4];
00220     static float fj[4];
00221     fi[0] = pIn.x;
00222     fi[1] = pIn.y;
00223     fi[2] = pIn.z;
00224     fi[3] = 1;
00225     SWCVectorMultiply( mFinal, fi, fj );
00226 
00227     //Divide-by-perspective step
00228     pOut.w = fj[3];
00229     pOut.x = fj[0]/pOut.w;
00230     pOut.y = fj[1]/pOut.w;
00231     pOut.z = fj[2]/pOut.w;
00232 
00233     //viewport transform.
00234     pOut.x *= (m_VPwidth - m_VPx)/(2);
00235     pOut.x += (m_VPwidth)/2;
00236     pOut.y *= (m_VPy - m_VPheight)/(2);
00237     pOut.y += (m_VPheight)/2;
00238 }
00239 
00240 
00241 #define PLOT( p , c )\
00242         if ( p.w < 0 )\
00243             continue;\
00244         if( p.x < m_width && p.y <= m_height && p.x >= 0 && p.y >= 0)\
00245             m_cBuffer[ (int( p.x ) + int( p.y )* m_width ) * m_bypp + c] = char(255);
00246 
00247 #define FASTCROSSCHECK( x,y, p1x, p1y, p2x, p2y )  ( ( (p1x-x)*(p2y-y) - (p2x-x)*(p1y-y) ) > 0 )
00248 
00249 //These two functions operate on a matrix of the form x,y,1,(NC),z,w,u,v  (we're trying to keep alignment)
00250 static void TexmapAddRows( float * fRowWork, float * fRowMultiply, float fQuantity )
00251 {
00252     fRowWork[0] += fRowMultiply[0] * fQuantity;
00253     fRowWork[1] += fRowMultiply[1] * fQuantity;
00254     fRowWork[2] += fRowMultiply[2] * fQuantity;
00255     fRowWork[3] += fRowMultiply[3] * fQuantity;
00256     fRowWork[4] += fRowMultiply[4] * fQuantity;
00257     fRowWork[5] += fRowMultiply[5] * fQuantity;
00258     fRowWork[6] += fRowMultiply[6] * fQuantity;
00259     fRowWork[7] += fRowMultiply[7] * fQuantity;
00260 }
00261 
00262 static void TexmapScaleRow( float * fRowWork, float fQuantity )
00263 {
00264     fRowWork[0] *= fQuantity;
00265     fRowWork[1] *= fQuantity;
00266     fRowWork[2] *= fQuantity;
00267     fRowWork[3] *= fQuantity;
00268     fRowWork[4] *= fQuantity;
00269     fRowWork[5] *= fQuantity;
00270     fRowWork[6] *= fQuantity;
00271     fRowWork[7] *= fQuantity;
00272 }
00273 
00274 const static int iRowWidth = 8;
00275 const static int iRowWidth2 = 16;
00276 static float fTMMatrix[24] M_ALIGN(128);    //For SSE2 or SSE
00277 
00278 static void TexmapSolutionMatrix( )
00279 {
00280     //Step0: Prevent inaccuracies
00281     if( fTMMatrix[0] < 0.001f ) //We'll lose accuracy.
00282         if( fTMMatrix[iRowWidth] > fTMMatrix[iRowWidth2] )  //So fix it.
00283             TexmapAddRows( &fTMMatrix[0], &fTMMatrix[iRowWidth], 1 );
00284         else
00285             TexmapAddRows( &fTMMatrix[0], &fTMMatrix[iRowWidth2], 1 );
00286 
00287     if( fTMMatrix[iRowWidth + 1] < 0.001f ) //We'll lose accuracy @ (2,2)
00288         if( fTMMatrix[1] > fTMMatrix[iRowWidth2+1] )    
00289             TexmapAddRows( &fTMMatrix[iRowWidth], &fTMMatrix[0], 1 );
00290         else
00291             TexmapAddRows( &fTMMatrix[iRowWidth], &fTMMatrix[iRowWidth2], 1 );
00292     
00293     if( fTMMatrix[iRowWidth2 + 2] < 0.001f )    //We'll lose accuracy @ (3,3)
00294         if( fTMMatrix[2] > fTMMatrix[iRowWidth+2] ) 
00295             TexmapAddRows( &fTMMatrix[iRowWidth2], &fTMMatrix[0], 1 );
00296         else
00297             TexmapAddRows( &fTMMatrix[iRowWidth2], &fTMMatrix[iRowWidth], 1 );
00298 
00299     //Step1, the first column.
00300     TexmapScaleRow( &fTMMatrix[0], 1/fTMMatrix[0] );    //(1,1) is now 1.
00301     TexmapAddRows( &fTMMatrix[iRowWidth], &fTMMatrix[0], -fTMMatrix[iRowWidth]/fTMMatrix[0] );
00302     TexmapAddRows( &fTMMatrix[iRowWidth2], &fTMMatrix[0], -fTMMatrix[iRowWidth2]/fTMMatrix[0] );
00303 
00304     //Step2, the second column.
00305     TexmapScaleRow( &fTMMatrix[iRowWidth], 1/fTMMatrix[iRowWidth+1] );
00306     TexmapAddRows( &fTMMatrix[0], &fTMMatrix[iRowWidth], -fTMMatrix[1]/fTMMatrix[iRowWidth+1] );
00307     TexmapAddRows( &fTMMatrix[iRowWidth2], &fTMMatrix[iRowWidth], -fTMMatrix[iRowWidth2+1]/fTMMatrix[iRowWidth+1] );
00308 
00309     //Step3, the third column.  
00310     TexmapScaleRow( &fTMMatrix[iRowWidth2], 1/fTMMatrix[iRowWidth2+2] );
00311     TexmapAddRows( &fTMMatrix[0], &fTMMatrix[iRowWidth2], -fTMMatrix[2]/fTMMatrix[iRowWidth2+2] );
00312     TexmapAddRows( &fTMMatrix[iRowWidth], &fTMMatrix[iRowWidth2], -fTMMatrix[iRowWidth+2]/fTMMatrix[iRowWidth2+2] );
00313 
00314     //OK, we should be solved!  Here would be a good place to check to make sure
00315 }
00316 
00317 void MercuryDisplaySoftwareC::InternalDrawPoly( const InternalPoint * points, int verts, int mode )
00318 {
00319     int minX = (int)points[0].x, maxX = (int)points[0].x;
00320     int minY = (int)points[0].y, maxY = (int)points[0].y;
00321     int x = (int)points[0].x;
00322     int y = (int)points[0].y;
00323     static int i, loc;
00324     static int j;
00325 
00326     static float iCurrentX[5];
00327     static float iCurrentY[5];
00328 
00329     //Lines!
00330     float fLineXSlopes[4];
00331     float iLineRanges[4][2];        //[ymin] -> [ymax]
00332 
00333     //GEOMETRY SHADER
00334 
00335     for( i = 0; i < verts; i++ )
00336     {
00337         iCurrentX[i] = points[i].x;
00338         iCurrentY[i] = points[i].y;
00339     }
00340 
00341     //Tricky!  When deciding if we want to render a point, we have to use the pre-existing function
00342     //however, when deciding if we are going to render a polygon -- we have to be more than strict!
00343     if( (iCurrentX[1]-iCurrentX[0])*(iCurrentY[2]-iCurrentY[0]) - 
00344         (iCurrentX[2]-iCurrentX[0])*(iCurrentY[1]-iCurrentY[0]) > -1 )
00345         return;
00346 
00347     int wfails = 0;
00348     if( points[0].w < 0 )
00349         wfails++;
00350 
00351 
00352     for( i = 1; i < verts; i++ )
00353     {
00354         if( points[i].w < 0 )
00355             wfails++;
00356         x = int(points[i].x); y = int(points[i].y);
00357         if( x < minX ) minX = x;
00358         else if( x > maxX ) maxX = x;
00359         if( y < minY ) minY = y;
00360         else if( y > maxY ) maxY = y;
00361     }
00362 
00363     if( wfails >= 1 )
00364         return;
00365 
00366     if( minX >= m_width ) return;
00367     if( minY >= m_height ) return;
00368     if( maxX < 0 ) return;
00369     if( maxY < 0 ) return;
00370     if( minX < 0 ) minX = 0;
00371     if( minY < 0 ) minY = 0;
00372     if( maxX >= m_width ) maxX = m_width-1;
00373     if( maxY >= m_height ) maxY = m_height-1;
00374 
00375     for( i = 0; i < verts; i++ )
00376     {
00377         static float aX,aY,bX,bY; 
00378         aX = points[i].x;
00379         aY = points[i].y;
00380         bX = points[(i+1)%verts].x;
00381         bY = points[(i+1)%verts].y;
00382 
00383         iLineRanges[i][0] = (aY<bY)?aY:bY;
00384         iLineRanges[i][1] = (aY>bY)?aY:bY;
00385 
00386         fLineXSlopes[i] = (aX-bX)/(aY-bY);
00387     }
00388 
00389     bool bHasATexture = m_pCurTexture->m_isMaterial;
00390     static float iFinalSolutionMatrix[12];
00391 
00392     //Construct the TMMatrix
00393     for( i = 0; i < 3; i++ )
00394     {
00395         //VERTEX SHADER, Part II
00396         loc = i%verts;
00397         fTMMatrix[i*iRowWidth+0] = points[i].x;
00398         fTMMatrix[i*iRowWidth+1] = points[i].y;
00399         fTMMatrix[i*iRowWidth+2] = 1;
00400         fTMMatrix[i*iRowWidth+3] = 1; //NOT USED
00401         fTMMatrix[i*iRowWidth+4] = points[i].z/points[i].w;
00402         fTMMatrix[i*iRowWidth+5] = 1/points[i].w;
00403         if( bHasATexture)
00404         {
00405             static float fThisU;
00406             fThisU = points[i].u;
00407             static float fThisV;
00408             fThisV = points[i].v;
00409 
00410             fThisU = m_pCurTexture->m_TexMat[0][0] * fThisU + m_pCurTexture->m_TexMat[0][1] * fThisV + m_pCurTexture->m_TexMat[0][3];
00411             fThisV = m_pCurTexture->m_TexMat[1][0] * fThisU + m_pCurTexture->m_TexMat[1][1] * fThisV + m_pCurTexture->m_TexMat[1][3];
00412             //Perfrom texture matrix calculations here.
00413             fTMMatrix[i*iRowWidth+6] = fThisU/points[i].w;// * m_pCurTexture->m_width;
00414             fTMMatrix[i*iRowWidth+7] = fThisV/points[i].w;// * m_pCurTexture->m_height;
00415         }
00416         else
00417         {
00418             fTMMatrix[i*iRowWidth+6] = 0;
00419             fTMMatrix[i*iRowWidth+7] = 0;
00420         }
00421     }
00422 
00423     TexmapSolutionMatrix();
00424 
00425     for( i = 0; i < 3; i++ )
00426     {
00427         iFinalSolutionMatrix[i*4+0] = (fTMMatrix[i*iRowWidth+4]);
00428         iFinalSolutionMatrix[i*4+1] = (fTMMatrix[i*iRowWidth+5]);
00429         iFinalSolutionMatrix[i*4+2] = (fTMMatrix[i*iRowWidth+6]);
00430         iFinalSolutionMatrix[i*4+3] = (fTMMatrix[i*iRowWidth+7]);
00431     }
00432 
00433     static unsigned int TAlpha;
00434     static unsigned int TR;
00435     static unsigned int TG;
00436     static unsigned int TB;
00437     static unsigned int TNAlpha;
00438     static unsigned int ALPHA;
00439     static unsigned int NEGALPHA;
00440     static unsigned int LUMINENCE;
00441     static unsigned int fBuf;
00442 
00443     static float tf;
00444 
00445     TAlpha = (unsigned int)(m_pCurMaterial.m_diffuse.GetA() * 255.0f);
00446     TR = (unsigned int)(m_pCurMaterial.m_diffuse.GetR()*TAlpha);
00447     TG = (unsigned int)(m_pCurMaterial.m_diffuse.GetG()*TAlpha);
00448     TB = (unsigned int)(m_pCurMaterial.m_diffuse.GetB()*TAlpha);
00449     TNAlpha = 255-TAlpha;
00450 
00451     bool bNotFullAlpha = ( TAlpha != 255 || TR != 255 || TG != 255 || TB != 255 );
00452 
00453     if( TAlpha == 0 )
00454         return;
00455 
00456     for( y = minY; y <= maxY; ++y )
00457     {
00458         maxX = -1;
00459         minX = m_width + 1;
00460         for( i = 0; i < verts; i++ )
00461             if( iLineRanges[i][0] <= y && iLineRanges[i][1] >= y )
00462             {
00463                 tf = points[i].x + (y-points[i].y) * fLineXSlopes[i];
00464 
00465                 //These first two cases can happen when fLineXSlopes[i] is an incredibly large number.
00466                 if( tf < points[i].x && tf < points[(i+1)%verts].x )
00467                     tf = (points[i].x<points[(i+1)%verts].x)?points[i].x:points[(i+1)%verts].x;
00468                 if( tf > points[i].x && j > points[(i+1)%verts].x )
00469                     tf = (points[i].x>points[(i+1)%verts].x)?points[i].x:points[(i+1)%verts].x;
00470 
00471                 //These can happen if the line extends off of the screen
00472                 if( j < 0 ) 
00473                     j = 0;
00474                 else if( j >= m_width )
00475                     j = m_width-1;
00476 
00477                 if( maxX < j ) maxX = j;
00478                 if( minX > j ) minX = j;
00479             }
00480 
00481 
00482         for( x = minX; x<= maxX; ++x )
00483         {
00484             //This code runs for EVERY PIXEL, so keep it tight!
00485             //FRAGMENT SHADER
00486             static float w;
00487             w = (iFinalSolutionMatrix[1] * x + iFinalSolutionMatrix[5] * y + iFinalSolutionMatrix[9]);
00488             static float z;
00489             z = (iFinalSolutionMatrix[0] * x + iFinalSolutionMatrix[4] * y + iFinalSolutionMatrix[8])*20000;
00490             
00491             if( z >= 1500000 || //Too far away to see
00492                 z<0 ||          //Behind camera
00493                 w<0 )           //Culled
00494                 continue;
00495 
00496             loc = x + y*m_width;
00497 
00498             if( bDepthTest )
00499                 if( m_zBuffer[loc] > z )
00500                     continue;
00501                 else if (m_zBufferWrite)
00502                     m_zBuffer[loc] = (unsigned int)z;
00503 
00504             static int lBuf;
00505             lBuf = loc * m_bypp;
00506             if( bHasATexture )
00507             {           
00508                 int u,v;
00509 
00510                 u = (unsigned int)((iFinalSolutionMatrix[2] * x + iFinalSolutionMatrix[6] * y + iFinalSolutionMatrix[10])*float(m_pCurTexture->m_width)/w);
00511                 v = (unsigned int)((iFinalSolutionMatrix[3] * x + iFinalSolutionMatrix[7] * y + iFinalSolutionMatrix[11])*float(m_pCurTexture->m_height)/w);
00512 
00513                 if (m_pCurMercuryTexture->GetMapping() == SPHERE)
00514                 {
00515                     u += y;
00516                     v += x;
00517                 }
00518 
00519                 u = u%m_pCurTexture->m_width;
00520                 v = v%m_pCurTexture->m_height;
00521                 if( u < 0 ) u+= m_pCurTexture->m_width;
00522                 if( v < 0 ) v+= m_pCurTexture->m_height;
00523 
00524                 fBuf = u+v*m_pCurTexture->m_width;
00525 
00526                 if( m_pCurTexture->m_type == LUMINANCE_ALPHA )
00527                 {
00528                     //No adverse effects of just assuming we're always not full alpha
00529                     ALPHA = m_pCurTexture->m_data[fBuf*2+1] * TAlpha;
00530                     NEGALPHA = 65536-ALPHA;
00531                     LUMINENCE = m_pCurTexture->m_data[fBuf*2+0];
00532                     m_cBuffer[ lBuf + 0] = ( m_cBuffer[ lBuf + 0] * NEGALPHA + LUMINENCE * ALPHA )>>16; 
00533                     m_cBuffer[ lBuf + 1] = ( m_cBuffer[ lBuf + 1] * NEGALPHA + LUMINENCE * ALPHA )>>16; 
00534                     m_cBuffer[ lBuf + 2] = ( m_cBuffer[ lBuf + 2] * NEGALPHA + LUMINENCE * ALPHA )>>16; 
00535                 }
00536                 if( !bNotFullAlpha )
00537                 {
00538                     if ( m_pCurTexture->m_type == RGBA )
00539                     {
00540                         ALPHA = m_pCurTexture->m_data[fBuf*4+3];
00541                         NEGALPHA = 255-ALPHA;
00542 
00543                         m_cBuffer[ lBuf + 2] = ((ALPHA) * m_pCurTexture->m_data[fBuf*4+0] + NEGALPHA * m_cBuffer[ lBuf + 2])>>8;
00544                         m_cBuffer[ lBuf + 1] = ((ALPHA) * m_pCurTexture->m_data[fBuf*4+1] + NEGALPHA * m_cBuffer[ lBuf + 1])>>8;
00545                         m_cBuffer[ lBuf + 0] = ((ALPHA) * m_pCurTexture->m_data[fBuf*4+2] + NEGALPHA * m_cBuffer[ lBuf + 0])>>8;
00546                     } else if ( m_pCurTexture->m_type == RGB )
00547                     {
00548                         m_cBuffer[lBuf + 2] = m_pCurTexture->m_data[fBuf*3+0];
00549                         m_cBuffer[lBuf + 1] = m_pCurTexture->m_data[fBuf*3+1];
00550                         m_cBuffer[lBuf + 0] = m_pCurTexture->m_data[fBuf*3+2];
00551                     } 
00552                 } else {
00553                     if ( m_pCurTexture->m_type == RGBA )
00554                     {
00555                         ALPHA = m_pCurTexture->m_data[fBuf*4+3];
00556                         NEGALPHA = 65536-(TAlpha*ALPHA);
00557 
00558                         m_cBuffer[ lBuf + 2] = (ALPHA * m_pCurTexture->m_data[fBuf*4+0] * TR + NEGALPHA * m_cBuffer[ lBuf + 2] )>>16;
00559                         m_cBuffer[ lBuf + 1] = (ALPHA * m_pCurTexture->m_data[fBuf*4+1] * TG + NEGALPHA * m_cBuffer[ lBuf + 1] )>>16;
00560                         m_cBuffer[ lBuf + 0] = (ALPHA * m_pCurTexture->m_data[fBuf*4+2] * TB + NEGALPHA * m_cBuffer[ lBuf + 0] )>>16;
00561                     } else if ( m_pCurTexture->m_type == RGB )
00562                     {
00563                         m_cBuffer[lBuf + 2] = ( m_cBuffer[lBuf + 2] * TNAlpha + m_pCurTexture->m_data[fBuf*3+0] * TR )>>8;
00564                         m_cBuffer[lBuf + 1] = ( m_cBuffer[lBuf + 1] * TNAlpha + m_pCurTexture->m_data[fBuf*3+1] * TG )>>8;
00565                         m_cBuffer[lBuf + 0] = ( m_cBuffer[lBuf + 0] * TNAlpha + m_pCurTexture->m_data[fBuf*3+2] * TB )>>8;
00566                     } 
00567                 }
00568             } else {
00569                 m_cBuffer[lBuf + 0] = (( m_cBuffer[lBuf + 0] * TNAlpha )>>8) + TB;
00570                 m_cBuffer[lBuf + 1] = (( m_cBuffer[lBuf + 1] * TNAlpha )>>8) + TG;
00571                 m_cBuffer[lBuf + 2] = (( m_cBuffer[lBuf + 2] * TNAlpha )>>8) + TR;
00572             }
00573         }
00574         }
00575 }
00576 
00577 void MercuryDisplaySoftwareC::SendMatrixData(const MercuryMatrix& m)
00578 {
00579     static MercuryMatrix projection;
00580     static MercuryMatrix modelView;
00581 
00582     projection = GetProjection();
00583 //  modelView = ViewStack.GetTop() * WorldStack.GetTop();
00584 //  modelView = ViewStack.GetTop() * m;
00585     modelView = m_view * m;
00586 
00587     projection.Transpose();
00588     modelView.Transpose();
00589 
00590     mFinal = modelView * projection;
00591 }
00592 
00593 
00594 /* 
00595  * Copyright (c) 2006 Charles Lohr
00596  * All rights reserved.
00597  *
00598  * Redistribution and use in source and binary forms, with or
00599  * without modification, are permitted provided that the following
00600  * conditions are met:
00601  *  -   Redistributions of source code must retain the above
00602  *      copyright notice, this list of conditions and the following disclaimer.
00603  *  -   Redistributions in binary form must reproduce the above copyright
00604  *      notice, this list of conditions and the following disclaimer in
00605  *      the documentation and/or other materials provided with the distribution.
00606  *  -   Neither the name of the Mercury Engine nor the names of its
00607  *      contributors may be used to endorse or promote products derived from
00608  *      this software without specific prior written permission.
00609  *
00610  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00611  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00612  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00613  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00614  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00615  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00616  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00617  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00618  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00619  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00620  */

Hosted by SourceForge.net Logo