00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
00063
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
00074 int byteSize = sizeof(OverlayVertex) * MAX_POINT;
00075 AS.pDevice->CreateVertexBuffer( byteSize, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &AS.overlay_pVB );
00076
00077
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
00085 AS.res_fonts.push_back( util_loadFont("Arial","",18) );
00086
00087
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)
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
00186
00187 device_setPixelShader( AS.pshader_overlay );
00188
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
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