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
00021
00022
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
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
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
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
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
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
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
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);
00277
00278 static void TexmapSolutionMatrix( )
00279 {
00280
00281 if( fTMMatrix[0] < 0.001f )
00282 if( fTMMatrix[iRowWidth] > fTMMatrix[iRowWidth2] )
00283 TexmapAddRows( &fTMMatrix[0], &fTMMatrix[iRowWidth], 1 );
00284 else
00285 TexmapAddRows( &fTMMatrix[0], &fTMMatrix[iRowWidth2], 1 );
00286
00287 if( fTMMatrix[iRowWidth + 1] < 0.001f )
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 )
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
00300 TexmapScaleRow( &fTMMatrix[0], 1/fTMMatrix[0] );
00301 TexmapAddRows( &fTMMatrix[iRowWidth], &fTMMatrix[0], -fTMMatrix[iRowWidth]/fTMMatrix[0] );
00302 TexmapAddRows( &fTMMatrix[iRowWidth2], &fTMMatrix[0], -fTMMatrix[iRowWidth2]/fTMMatrix[0] );
00303
00304
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
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
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
00330 float fLineXSlopes[4];
00331 float iLineRanges[4][2];
00332
00333
00334
00335 for( i = 0; i < verts; i++ )
00336 {
00337 iCurrentX[i] = points[i].x;
00338 iCurrentY[i] = points[i].y;
00339 }
00340
00341
00342
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
00393 for( i = 0; i < 3; i++ )
00394 {
00395
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;
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
00413 fTMMatrix[i*iRowWidth+6] = fThisU/points[i].w;
00414 fTMMatrix[i*iRowWidth+7] = fThisV/points[i].w;
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
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
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
00485
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 ||
00492 z<0 ||
00493 w<0 )
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
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
00584
00585 modelView = m_view * m;
00586
00587 projection.Transpose();
00588 modelView.Transpose();
00589
00590 mFinal = modelView * projection;
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620