Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

AOverlay.cpp

Go to the documentation of this file.
00001 /*
00002 CS Senior Project 2003
00003 Team : Leftfield
00004 Project : ModernWarfare
00005 Members :
00006 - Russ Christensen              <rchriste@cs.utah.edu>
00007 - Todd Smith                    <tcsmith@cs.utah.edu>
00008 - Usit Duongsaa                 <duongsaa@cs.utah.edu>
00009 Copyright 2003 Russ Christensen, Usit Duongsaa, and Todd Smith. All rights reserved.
00010 
00011 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00012 
00013 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
00014 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
00015 THIS SOFTWARE IS PROVIDED BY RUSS CHRISTENSEN, USIT DUONGSAA, AND TODD SMITH ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RUSS, USIT, TODD OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00016 */
00017 
00023 #include "AEngine.h"
00024 #include "AState.h"
00025 #include "ADevice.h"
00026 #include "AConstants.h"
00027 #include "AVertexTypes.h"
00028 
00029 
00030 //------------------------------------------------------------------------------------
00031 //------------------------------------------------------------------------------------
00034 const int MAX_POINT = 96/3;             
00035 
00037 namespace OpType
00038 {
00039         const int OP_INVALID            =  -1;
00040         const int OP_IMAGE                      =       0;
00041         const int OP_FILLED_RECT        =       1;
00042         const int OP_EMPTY_RECT         =       2;
00043         const int OP_LINE                       =       3;
00044         const int OP_POINT                      =       4;
00045         const int OP_TEXT                       =       5;
00046 }
00047 //------------------------------------------------------------------------------------
00049 class OverlayEntryComparer      
00050 {
00051 public:
00054         bool operator()(const OverlayEntry &L, const OverlayEntry &R )
00055         {
00056                 return (L.op*100+L.blendMode)+L.priority*1000 < (R.op*100+R.blendMode)+R.priority*1000;
00057         }
00058 };
00059 //------------------------------------------------------------------------------------
00060 //------------------------------------------------------------------------------------
00061 //------------------------------------------------------------------------------------
00062 // convert a point in (0..1)^2 to (-1..+1)^2
00063 // note that the y-axis is flipped
00064 void convertToScreenCoord( Vec2D &pt )
00065 {
00066         pt[0] = pt[0]*2.0f - 1.0f;
00067         pt[1] = (1.0f-pt[1])*2.0f - 1.0f;
00068 }
00069 //------------------------------------------------------------------------------------
00070 //------------------------------------------------------------------------------------
00071 void overlay_init()
00072 {
00073         // create vertex buffer
00074         int byteSize = sizeof(OverlayVertex) * MAX_POINT;
00075         AS.pDevice->CreateVertexBuffer( byteSize, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &AS.overlay_pVB );
00076         
00077         // put in index to constant registers
00078         OverlayVertex *access;
00079         if( FAILED( AS.overlay_pVB->Lock(0,0, (BYTE**)&access, 0) )) throw Error("Can't Lock Overlay VB");
00080         for( int i=0; i<MAX_POINT; i++ )        
00081                 access[i].cIndex = i*3.0f;
00082         AS.overlay_pVB->Unlock();
00083 
00084         // load default font
00085         AS.res_fonts.push_back( util_loadFont("Arial","",18) );
00086 
00087         // load V&P Shader
00088         AS.vshader_overlay = util_loadVertexShader( "shaders\\overlay.vso", dwOverlayVertexDecl );
00089         AS.pshader_overlay = util_loadPixelShader(  "shaders\\overlay.pso" );
00090         AS.pshader_textureConstAlpha = util_loadPixelShader(  "shaders\\textureConstAlpha.pso" );
00091         AS.pshader_texturePixelAlpha = util_loadPixelShader(  "shaders\\texturePixelAlpha.pso" );
00092 
00093         AS.overlay_pTextStream = new ostringstream();
00094 }
00095 //------------------------------------------------------------------------------------
00096 void overlay_flush()
00097 {
00098         AS.overlay_entries.resize(0);
00099         delete AS.overlay_pTextStream;
00100         AS.overlay_pTextStream = new ostringstream();   
00101 }
00102 //------------------------------------------------------------------------------------
00103 inline void useOverlayShaders()
00104 {
00105         device_setTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
00106         device_setTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
00107         device_setTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_POINT );
00108         device_setVertexShader( AS.vshader_overlay );   
00109         device_setStreamSource( 0, AS.overlay_pVB, sizeof(OverlayVertex) );
00110         device_setRenderState( D3DRS_ZENABLE, FALSE );
00111         device_setRenderState( D3DRS_SPECULARENABLE, FALSE );
00112         device_setRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
00113 }
00114 //------------------------------------------------------------------------------------
00115 void overlay_render()
00116 {
00117         sort(AS.overlay_entries.begin(), AS.overlay_entries.end(), OverlayEntryComparer());
00118         useOverlayShaders();
00119 
00120         D3DLINEPATTERN linePattern;
00121 
00122         int last = (int)AS.overlay_entries.size();
00123         for( int i=0; i<last; i++ )
00124         {
00125                 OverlayEntry &e = AS.overlay_entries[i];
00126                 device_setRenderStateBlendMode(e.blendMode);
00127                 convertToScreenCoord(e.pt1);            
00128                 FLOAT x1, x2, y1, y2;
00129 
00130                 if(e.op==OpType::OP_IMAGE)              // for image, pt2 is used for size
00131                 {                       
00132                         e.pt1 = e.pt1 - e.pt2;
00133                         e.pt2 = 2.0f*e.pt2 + e.pt1;
00134                 }
00135                 else
00136                 {
00137                         convertToScreenCoord(e.pt2);
00138                 }
00139                 x1 =  min( e.pt1[0], e.pt2[0] );
00140                 x2 =  max( e.pt1[0], e.pt2[0] );
00141                 y1 =  min( e.pt1[1], e.pt2[1] );
00142                 y2 =  max( e.pt1[1], e.pt2[1] );
00143                 FLOAT dataA[12] = { x1,y1,0.0f, 10.0f, e.color[0], e.color[1], e.color[2], e.alpha, 0.0f, 1.0f };
00144                 FLOAT dataB[12] = { x2,y1,0.0f, 10.0f, e.color[0], e.color[1], e.color[2], e.alpha, 1.0f, 1.0f };
00145                 FLOAT dataC[12] = { x2,y2,0.0f, 10.0f, e.color[0], e.color[1], e.color[2], e.alpha, 1.0f, 0.0f };
00146                 FLOAT dataD[12] = { x1,y2,0.0f, 10.0f, e.color[0], e.color[1], e.color[2], e.alpha, 0.0f, 0.0f };
00147 
00148                 switch(e.op)
00149                 {
00150                         case OpType::OP_IMAGE:
00151                                 {
00152                                         useOverlayShaders();
00153                                         if(e.blendMode==BlendModes::KEY)
00154                                                 device_setPixelShader(  AS.pshader_texturePixelAlpha );
00155                                         else
00156                                                 device_setPixelShader(  AS.pshader_textureConstAlpha );
00157                                         device_setTexture(0, AS.res_textures.at(e.resource) );
00158                                         AS.pDevice->SetVertexShaderConstant( 0, dataD, 3 );
00159                                         AS.pDevice->SetVertexShaderConstant( 3, dataC, 3 );
00160                                         AS.pDevice->SetVertexShaderConstant( 6, dataB, 3 );
00161                                         AS.pDevice->SetVertexShaderConstant( 9, dataA, 3 );
00162                                         AS.pDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
00163                                         break;
00164                                 }
00165 
00166                         case OpType::OP_POINT:
00167                                 {
00168                                         useOverlayShaders();
00169                                         device_setPixelShader(  AS.pshader_overlay );
00170                                         dataA[0]=e.pt1[0];              dataA[1]=e.pt1[1];              dataA[2]=0.0f;                  dataA[3]=e.size*4.0f;
00171                                         dataA[4]=e.color[0];    dataA[5]=e.color[1];    dataA[6]=e.color[2];    dataA[7]=e.alpha;
00172                                         AS.pDevice->SetVertexShaderConstant( 0, dataA, 2 );
00173                                         AS.pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 1 );
00174                                         break;
00175                                 }
00176                                 
00177                         case OpType::OP_LINE:
00178                                 {
00179                                         useOverlayShaders();
00180                                         int intPattern = *(int*)(&e.size);
00181                                         WORD patterns[3] = { 0xffff, 0x3333, 0x5555 };
00182                                         linePattern.wRepeatFactor = 1;
00183                                         linePattern.wLinePattern = patterns[ intPattern ];
00184                                         DWORD dwPattern = *(DWORD*)(&linePattern);
00185                                         //device_setRenderState( D3DRS_LINEPATTERN, dwPattern );
00186 
00187                                         device_setPixelShader(  AS.pshader_overlay );
00188                                         // send first point to GPU
00189                                         dataA[0]=e.pt1[0];              dataA[1]=e.pt1[1];              dataA[2]=0.0f;                  dataA[3]=10.0f;
00190                                         dataA[4]=e.color[0];    dataA[5]=e.color[1];    dataA[6]=e.color[2];    dataA[7]=e.alpha;
00191                                         AS.pDevice->SetVertexShaderConstant( 0, dataA, 2 );
00192                                 
00193                                         // second point
00194                                         dataA[0]=e.pt2[0];                      dataA[1]=e.pt2[1];
00195                                         AS.pDevice->SetVertexShaderConstant( 3, dataA, 2 );
00196         
00197                                         AS.pDevice->DrawPrimitive( D3DPT_LINELIST, 0, 1 );
00198                                         break;
00199                                 }
00200                                 
00201 
00202                         case OpType::OP_EMPTY_RECT:
00203                                 {
00204                                         useOverlayShaders();
00205                                         device_setPixelShader(  AS.pshader_overlay );
00206                                         AS.pDevice->SetVertexShaderConstant( 0, dataA, 2 );
00207                                         AS.pDevice->SetVertexShaderConstant( 3, dataB, 2 );
00208                                         AS.pDevice->SetVertexShaderConstant( 6, dataC, 2 );
00209                                         AS.pDevice->SetVertexShaderConstant( 9, dataD, 2 );
00210                                         AS.pDevice->SetVertexShaderConstant(12, dataA, 2 );
00211                                         AS.pDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, 4 );
00212                                         break;
00213                                 }                       
00214 
00215                         case OpType::OP_FILLED_RECT:
00216                                 {
00217                                         useOverlayShaders();
00218                                         device_setPixelShader(  AS.pshader_overlay );
00219                                         AS.pDevice->SetVertexShaderConstant( 0, dataD, 2 );
00220                                         AS.pDevice->SetVertexShaderConstant( 3, dataC, 2 );
00221                                         AS.pDevice->SetVertexShaderConstant( 6, dataB, 2 );
00222                                         AS.pDevice->SetVertexShaderConstant( 9, dataA, 2 );
00223                                         AS.pDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
00224                                         break;
00225                                 }
00226                                 
00227                         case OpType::OP_TEXT:
00228                                 {                                       
00229                                         DWORD color = D3DXCOLOR( e.color[0], e.color[1], e.color[2], e.alpha );
00230                                         FLOAT scale = e.size * 0.025f;
00231                                         TCHAR *tStr = util_stringToTChar(e.s);
00232                                         AS.res_fonts.at(e.resource)->DrawTextScaled( e.pt1[0], -e.pt1[1], 0.0f,
00233                                                                                                                      scale, scale, color, tStr, 0 );
00234                                         device_flushSettings();
00235                                         break;
00236                                 }
00237 
00238                         default:
00239                                 assert(false && "Invalid OpCode in Overlay pipeline");
00240                 }
00241         }
00242 
00243         AS.overlay_entries.resize(0);
00244 }
00245 //------------------------------------------------------------------------------------
00246 void overlay_point( const Vec2D pt, const FLOAT size, const Vec3D rgb, const int blendMode,
00247                                     const FLOAT alpha, const int priority )
00248 {
00249         AS.overlay_entries.push_back( OverlayEntry(OpType::OP_POINT, blendMode,
00250                                                                   pt, pt, rgb, alpha, size, "", NULL,priority)  );
00251 }
00252 //------------------------------------------------------------------------------------
00253 void overlay_line(  const Vec2D pt1, const Vec2D pt2, const Vec3D rgb, const int blendMode,
00254                                         const FLOAT alpha, const int priority, const int pattern )
00255 {
00256         FLOAT floatPattern = *(FLOAT*)(&pattern);
00257         AS.overlay_entries.push_back( OverlayEntry(OpType::OP_LINE, blendMode,
00258                                                                   pt1, pt2, rgb, alpha, floatPattern, "", NULL,priority)  );
00259 }
00260 //------------------------------------------------------------------------------------
00261 void overlay_rect(  const Vec2D pt1, const Vec2D pt2, const bool fill, const Vec3D rgb,
00262                                     const int blendMode, const FLOAT alpha, const int priority )
00263 {
00264         if(fill)
00265                 AS.overlay_entries.push_back( OverlayEntry(OpType::OP_FILLED_RECT, 
00266                                                                           blendMode, pt1, pt2, rgb, alpha, 1.0f, "", NULL,priority)  );
00267         else
00268                 AS.overlay_entries.push_back( OverlayEntry(OpType::OP_EMPTY_RECT, 
00269                                                                           blendMode, pt1, pt2, rgb, alpha, 1.0f, "", NULL,priority)  );
00270 }
00271 //------------------------------------------------------------------------------------
00272 ostream& overlay_text()
00273 {
00274         return *(AS.overlay_pTextStream);
00275 }
00276 //------------------------------------------------------------------------------------
00277 void overlay_textOut( const Vec2D pos, const FLOAT scale, const Vec3D rgb, const AFont font, int priority )
00278 {
00279         AS.overlay_entries.push_back( OverlayEntry(OpType::OP_TEXT,     BlendModes::NONE,
00280                                                                   pos, pos, rgb, 1.0f, scale, AS.overlay_pTextStream->str(), font,priority)  );
00281         overlay_clearText();
00282 }
00283 //------------------------------------------------------------------------------------
00284 void overlay_clearText()
00285 {
00286         delete AS.overlay_pTextStream;
00287         AS.overlay_pTextStream = new ostringstream();
00288 }
00289 //------------------------------------------------------------------------------------
00290 void overlay_image( const ATexture image, const Vec2D center, const Vec2D size,
00291                                     const int blendMode, const FLOAT alpha, const int priority )
00292 {
00293         AS.overlay_entries.push_back( OverlayEntry(OpType::OP_IMAGE, blendMode, center, size,
00294                                                                                            Colors::white, alpha, 0.0f, "", image,priority) );
00295 }
00296 //------------------------------------------------------------------------------------

Generated on Wed Apr 23 05:50:13 2003 for Modern Warfare by doxygen1.3-rc2