Renderer.cpp 29.9 KB
Newer Older
Gargaj's avatar
Gargaj committed
1
#include <windows.h>
Gargaj's avatar
Gargaj committed
2
#include <windowsx.h>
Gargaj's avatar
Gargaj committed
3
#include <tchar.h>
Gargaj's avatar
Gargaj committed
4
#include <d3d9.h>
Gargaj's avatar
Gargaj committed
5
#include <d3dx9.h>
Gargaj's avatar
Gargaj committed
6
7
#include "../Renderer.h"

8
9
10
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include "Scintilla.h"
Gargaj's avatar
Gargaj committed
11

Gargaj's avatar
Gargaj committed
12
13
#define DEVTYPE D3DDEVTYPE_HAL

14
const char * shaderKeyword =
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  " register packoffset static const"
  " break continue discard do for if else switch while case default return true false"
  " BINORMAL BINORMAL0 BINORMAL1 BINORMAL2 BINORMAL3 BINORMAL4 BINORMAL5 BINORMAL6 BINORMAL7"
  " BLENDINDICES BLENDINDICES0 BLENDINDICES1 BLENDINDICES2 BLENDINDICES3 BLENDINDICES4 BLENDINDICES5 BLENDINDICES6 BLENDINDICES7"
  " BLENDWEIGHT BLENDWEIGHT0 BLENDWEIGHT1 BLENDWEIGHT2 BLENDWEIGHT3 BLENDWEIGHT4 BLENDWEIGHT5 BLENDWEIGHT6 BLENDWEIGHT7"
  " COLOR COLOR0 COLOR1 COLOR2 COLOR3 COLOR4 COLOR5 COLOR6 COLOR7"
  " NORMAL NORMAL0 NORMAL1 NORMAL2 NORMAL3 NORMAL4 NORMAL5 NORMAL6 NORMAL7"
  " POSITION POSITION0 POSITION1 POSITION2 POSITION3 POSITION4 POSITION5 POSITION6 POSITION7"
  " POSITIONT"
  " PSIZE PSIZE0 PSIZE1 PSIZE2 PSIZE3 PSIZE4 PSIZE5 PSIZE6 PSIZE7"
  " TANGENT TANGENT0 TANGENT1 TANGENT2 TANGENT3 TANGENT4 TANGENT5 TANGENT6 TANGENT7"
  " TEXCOORD TEXCOORD0 TEXCOORD1 TEXCOORD2 TEXCOORD3 TEXCOORD4 TEXCOORD5 TEXCOORD6 TEXCOORD7 TEXCOORD8 TEXCOORD9"
  " TEXCOORD0 TEXCOORD1 TEXCOORD2 TEXCOORD3 TEXCOORD4 TEXCOORD5 TEXCOORD6 TEXCOORD7 TEXCOORD8 TEXCOORD9"
  " SV_Coverage SV_Depth SV_DispatchThreadID SV_DomainLocation SV_GroupID SV_GroupIndex SV_GroupThreadID SV_GSInstanceID SV_InsideTessFactor SV_IsFrontFace SV_OutputControlPointID SV_POSITION SV_Position SV_RenderTargetArrayIndex SV_SampleIndex SV_TessFactor SV_ViewportArrayIndex SV_InstanceID SV_PrimitiveID SV_VertexID SV_TargetID"
  " SV_TARGET SV_Target SV_Target0 SV_Target1 SV_Target2 SV_Target3 SV_Target4 SV_Target5 SV_Target6 SV_Target7"
  " SV_ClipDistance0 SV_ClipDistance1 SV_ClipDistance2 SV_ClipDistance3 SV_ClipDistance4 SV_ClipDistance5 SV_ClipDistance6 SV_ClipDistance7"
  " SV_CullDistance0 SV_CullDistance1 SV_CullDistance2 SV_CullDistance3 SV_CullDistance4 SV_CullDistance5 SV_CullDistance6 SV_CullDistance7";
32
33

const char * shaderType = 
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  "bool bool1 bool2 bool3 bool4"
  " bool1x1 bool1x2 bool1x3 bool1x4"
  " bool2x1 bool2x2 bool2x3 bool2x4"
  " bool3x1 bool3x2 bool3x3 bool3x4"
  " bool4x1 bool4x2 bool4x3 bool4x4"
  " int int1 int2 int3 int4"
  " int1x1 int1x2 int1x3 int1x4"
  " int2x1 int2x2 int2x3 int2x4"
  " int3x1 int3x2 int3x3 int3x4"
  " int4x1 int4x2 int4x3 int4x4"
  " uint uint1 uint2 uint3 uint4"
  " uint1x1 uint1x2 uint1x3 uint1x4"
  " uint2x1 uint2x2 uint2x3 uint2x4"
  " uint3x1 uint3x2 uint3x3 uint3x4"
  " uint4x1 uint4x2 uint4x3 uint4x4"
  " UINT UINT2 UINT3 UINT4"
  " dword dword1 dword2 dword3 dword4"
  " dword1x1 dword1x2 dword1x3 dword1x4"
  " dword2x1 dword2x2 dword2x3 dword2x4"
  " dword3x1 dword3x2 dword3x3 dword3x4"
  " dword4x1 dword4x2 dword4x3 dword4x4"
  " half half1 half2 half3 half4"
  " half1x1 half1x2 half1x3 half1x4"
  " half2x1 half2x2 half2x3 half2x4"
  " half3x1 half3x2 half3x3 half3x4"
  " half4x1 half4x2 half4x3 half4x4"
  " float float1 float2 float3 float4"
  " float1x1 float1x2 float1x3 float1x4"
  " float2x1 float2x2 float2x3 float2x4"
  " float3x1 float3x2 float3x3 float3x4"
  " float4x1 float4x2 float4x3 float4x4"
  " double double1 double2 double3 double4"
  " double1x1 double1x2 double1x3 double1x4"
  " double2x1 double2x2 double2x3 double2x4"
  " double3x1 double3x2 double3x3 double3x4"
  " double4x1 double4x2 double4x3 double4x4"
  " snorm unorm string void cbuffer struct"
  " Buffer AppendStructuredBfufer ByteAddressBuffer ConsumeStructuredBuffer StructuredBuffer"
  " RWBuffer RWByteAddressBuffer RWStructuredBuffer RWTexture1D RWTexture1DArray RWTexture2D RWTexture2DArray RWTexture3D"
  " InputPatch OutputPatch"
  " linear centroid nointerpolation noperspective sample"
  " sampler sampler1D sampler2D sampler3D samplerCUBE SamplerComparisonState SamplerState sampler_state"
  " AddressU AddressV AddressW BorderColor Filter MaxAnisotropy MaxLOD MinLOD MipLODBias ComparisonFunc ComparisonFilter"
  " texture Texture1D Texture1DArray Texture2D Texture2DArray Texture2DMS Texture2DMSArray Texture3D TextureCube";
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

const char * shaderBuiltin =
  "abs acos all AllMemoryBarrier AllMemoryBarrierWithGroupSync any asdouble"
  " asfloat asin asint asuint atan atan2 ceil clamp clip cos cosh countbits"
  " cross D3DCOLORtoUBYTE4 ddx ddx_coarse ddx_fine ddy ddy_coarse ddy_fine"
  " degrees determinant DeviceMemoryBarrier DeviceMemoryBarrierWithGroupSync"
  " distance dot dst EvaluateAttributeAtCentroid EvaluateAttributeAtSample"
  " EvaluateAttributeSnapped exp exp2 f16tof32 f32tof16 faceforward firstbithigh"
  " firstbitlow floor fmod frac frexp fwidth GetRenderTargetSampleCount"
  " GetRenderTargetSamplePosition GroupMemoryBarrier GroupMemoryBarrierWithGroupSync"
  " InterlockedAdd InterlockedAnd InterlockedCompareExchange InterlockedCompareStore"
  " InterlockedExchange InterlockedMax InterlockedMin InterlockedOr InterlockedXor"
  " isfinite isinf isnan ldexp length lerp lit log log10 log2 mad max min modf mul"
  " noise normalize pow Process2DQuadTessFactorsAvg Process2DQuadTessFactorsMax"
  " Process2DQuadTessFactorsMin ProcessIsolineTessFactors ProcessQuadTessFactorsAvg"
  " ProcessQuadTessFactorsMax ProcessQuadTessFactorsMin ProcessTriTessFactorsAvg"
  " ProcessTriTessFactorsMax ProcessTriTessFactorsMin radians rcp reflect refract"
  " reversebits round rsqrt saturate sign sin sincos sinh smoothstep sqrt step"
  " tan tanh tex1D tex1Dbias tex1Dgrad tex1Dlod tex1Dproj tex2D tex2Dbias"
  " tex2Dgrad tex2Dlod tex2Dproj tex3D tex3Dbias tex3Dgrad tex3Dlod tex3Dproj"
  " texCUBE texCUBEbias texCUBEgrad texCUBElod texCUBEproj transpose trunc";

Gargaj's avatar
Gargaj committed
100
101
namespace Renderer
{
102
  char * defaultShaderFilename = "shader.dx9.hlsl";
Gargaj's avatar
Gargaj committed
103
  char defaultShader[65536] = 
Gargaj's avatar
Gargaj committed
104
    "texture texTFFT; sampler1D texFFT = sampler_state { Texture = <texTFFT>; }; \n"
105
    "// towards 0.0 is bass / lower freq, towards 1.0 is higher / treble freq\n"
Gargaj's avatar
Gargaj committed
106
107
    "texture texFFTSmoothedT; sampler1D texFFTSmoothed = sampler_state { Texture = <texFFTSmoothedT>; }; \n"
    "// this one has longer falloff and less harsh transients\n"
108
109
    "texture texFFTIntegratedT; sampler1D texFFTIntegrated = sampler_state { Texture = <texFFTIntegratedT>; }; \n"
    "// this is continually increasing\n"
Gargaj's avatar
Gargaj committed
110
    "\n"
111
112
113
114
115
116
117
118
119
    "{%textures:begin%}" // leave off \n here
    "texture raw{%textures:name%}; sampler2D {%textures:name%} = sampler_state { Texture = <raw{%textures:name%}>; };\n"
    "{%textures:end%}"
    "\n"
    "{%midi:begin%}" // leave off \n here
    "float {%midi:name%};\n"
    "{%midi:end%}"
    "float fGlobalTime; // in seconds\n"
    "float2 v2Resolution; // viewport resolution (in pixels)\n"
Gargaj's avatar
Gargaj committed
120
    "\n"
121
122
123
124
125
    "float4 plas( float2 v, float time )\n"
    "{\n"
    "  float c = 0.5 + sin( v.x * 10.0 ) + cos( sin( time + v.y ) * 20.0 );\n"
    "  return float4( sin(c * 0.2 + cos(time)), c * 0.15, cos( c * 0.1 + time / .4 ) * .25, 1.0 );\n"
    "}\n"
Gargaj's avatar
Gargaj committed
126
    "float4 main( float2 TexCoord : TEXCOORD0 ) : COLOR0\n"
Gargaj's avatar
Gargaj committed
127
128
129
    "{\n"
    "  float2 uv = TexCoord;\n"
    "  uv -= 0.5;\n"
Gargaj's avatar
Gargaj committed
130
    "  uv /= float2(v2Resolution.y / v2Resolution.x, 1);"
Gargaj's avatar
Gargaj committed
131
132
133
134
135
136
    "\n"
    "  float2 m;\n"
    "  m.x = atan(uv.x / uv.y) / 3.14;\n"
    "  m.y = 1 / length(uv) * .2;\n"
    "  float d = m.y;\n"
    "\n"
Gargaj's avatar
Gargaj committed
137
    "  float f = tex1D( texFFT, d ).r * 100;\n"
Gargaj's avatar
Gargaj committed
138
139
140
    "  m.x += sin( fGlobalTime ) * 0.1;\n"
    "  m.y += fGlobalTime * 0.25;\n"
    "\n"
141
142
143
    "  float4 t = plas( m * 3.14, fGlobalTime ) / d;\n"
    "  t = saturate( t );\n"
    "  return f + t;\n"
Gargaj's avatar
Gargaj committed
144
    "}";
145
146
147
148
149
150
151
152
153
154
155
  char defaultVertexShader[65536] = 
    "struct VS_INPUT_PP { float3 Pos : POSITION0; float2 TexCoord : TEXCOORD0; };\n"
    "struct VS_OUTPUT_PP { float4 Pos : POSITION0; float2 TexCoord : TEXCOORD0; };\n"
    "\n"
    "VS_OUTPUT_PP main( VS_INPUT_PP In )\n"
    "{\n"
    "  VS_OUTPUT_PP Out;\n"
    "  Out.Pos = float4( In.Pos, 1.0 );\n"
    "  Out.TexCoord = In.TexCoord;\n"
    "  return Out;\n"
    "}\n";
Gargaj's avatar
Gargaj committed
156
157
158

  bool run = true;

Gargaj's avatar
Gargaj committed
159
160
  LPDIRECT3D9 pD3D = NULL;
  LPDIRECT3DDEVICE9 pDevice = NULL;
Gargaj's avatar
Gargaj committed
161
  LPD3DXCONSTANTTABLE pConstantTable = NULL;
162
  LPDIRECT3DVERTEXSHADER9 pVertexShader = NULL;
Gargaj's avatar
Gargaj committed
163
  LPDIRECT3DPIXELSHADER9 theShader = NULL;
Gargaj's avatar
Gargaj committed
164
165
  LPDIRECT3DSURFACE9 pBackBuffer = NULL;
  LPDIRECT3DSURFACE9 pFrameGrabTexture = NULL;
Gargaj's avatar
Gargaj committed
166

Gargaj's avatar
Gargaj committed
167
168
  int nWidth = 0;
  int nHeight = 0;
Gargaj's avatar
Gargaj committed
169
170
171
172
173
174
175
176
177
178
179
180
181
  HWND hWnd = NULL;

  KeyEvent keyEventBuffer[512];
  int keyEventBufferCount = 0;
  MouseEvent mouseEventBuffer[512];
  int mouseEventBufferCount = 0;

  LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
  {
    switch (uMsg) 
    {
    case WM_KEYDOWN: 
      {
Gargaj's avatar
Gargaj committed
182
183
        int sciKey = 0;
        switch(wParam)
Gargaj's avatar
Gargaj committed
184
        {
Gargaj's avatar
Gargaj committed
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
        case VK_DOWN:         sciKey = SCK_DOWN;      break;
        case VK_UP:           sciKey = SCK_UP;        break;
        case VK_LEFT:         sciKey = SCK_LEFT;      break;
        case VK_RIGHT:        sciKey = SCK_RIGHT;     break;
        case VK_HOME:         sciKey = SCK_HOME;      break;
        case VK_END:          sciKey = SCK_END;       break;
        case VK_PRIOR:        sciKey = SCK_PRIOR;     break;
        case VK_NEXT:         sciKey = SCK_NEXT;      break;
        case VK_DELETE:       sciKey = SCK_DELETE;    break;
        case VK_INSERT:       sciKey = SCK_INSERT;    break;
        case VK_ESCAPE:       sciKey = SCK_ESCAPE;    break;
        case VK_BACK:         sciKey = SCK_BACK;      break;
        case VK_TAB:          sciKey = SCK_TAB;       break;
        case VK_RETURN:       sciKey = SCK_RETURN;    break;
//         case VK_KP_PLUS:      sciKey = SCK_ADD;       break;
//         case VK_KP_MINUS:     sciKey = SCK_SUBTRACT;  break;
//         case VK_KP_DIVIDE:    sciKey = SCK_DIVIDE;    break;
//         case VK_LSUPER:       sciKey = SCK_WIN;       break;
//         case VK_RSUPER:       sciKey = SCK_RWIN;      break;
        case VK_MENU:         sciKey = SCK_MENU;      break;
//         case VK_SLASH:        sciKey = '/';           break;
//         case VK_ASTERISK:     sciKey = '`';           break;
//         case VK_LEFTBRACKET:  sciKey = '[';           break;
//         case VK_BACKSLASH:    sciKey = '\\';          break;
//         case VK_RIGHTBRACKET: sciKey = ']';           break;
Gargaj's avatar
Gargaj committed
210
        case VK_F2:         sciKey = 283;      break;
Gargaj's avatar
Gargaj committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
        case VK_F5:         sciKey = 286;      break;
        case VK_F11:        sciKey = 292;      break;
        case VK_SHIFT:
        case VK_LSHIFT:
        case VK_RSHIFT:
        case VK_LMENU:
        case VK_RMENU:
        case VK_CONTROL:
        case VK_LCONTROL:
        case VK_RCONTROL:
          sciKey = 0;
          break;
        default:
          sciKey = wParam;
        }
        if (sciKey)
        {
          keyEventBuffer[keyEventBufferCount].ctrl  = GetAsyncKeyState( VK_LCONTROL ) || GetAsyncKeyState( VK_RCONTROL );
          keyEventBuffer[keyEventBufferCount].alt   = GetAsyncKeyState( VK_LMENU ) || GetAsyncKeyState( VK_RMENU );
          keyEventBuffer[keyEventBufferCount].shift = GetAsyncKeyState( VK_LSHIFT ) || GetAsyncKeyState( VK_RSHIFT );
          keyEventBuffer[keyEventBufferCount].scanCode = sciKey;
Gargaj's avatar
Gargaj committed
232
          keyEventBuffer[keyEventBufferCount].character = 0;
Gargaj's avatar
Gargaj committed
233
234
235
236
237
238
          keyEventBufferCount++;
        }
        //pKeys[wParam] = 1;
      } break;
    case WM_CHAR: 
      {
Gargaj's avatar
Gargaj committed
239
        if (wParam >= 32)
Gargaj's avatar
Gargaj committed
240
241
242
243
244
245
246
        {
          keyEventBuffer[keyEventBufferCount].ctrl  = GetAsyncKeyState( VK_LCONTROL ) || GetAsyncKeyState( VK_RCONTROL );
          keyEventBuffer[keyEventBufferCount].alt   = GetAsyncKeyState( VK_LMENU ) || GetAsyncKeyState( VK_RMENU );
          keyEventBuffer[keyEventBufferCount].shift = GetAsyncKeyState( VK_LSHIFT ) || GetAsyncKeyState( VK_RSHIFT );
          keyEventBuffer[keyEventBufferCount].scanCode = 0;
          keyEventBuffer[keyEventBufferCount].character = wParam;
          keyEventBufferCount++;
Gargaj's avatar
Gargaj committed
247
248
249
250
251
252
253
254
255
256
257
        }
        //pKeys[wParam] = 1;
      } break;

    case WM_KEYUP: 
      {
        //pKeys[wParam] = 0;
      } break;

    case WM_LBUTTONDOWN: 
      {
258
        mouseEventBuffer[mouseEventBufferCount].eventType = MOUSEEVENTTYPE_DOWN;
Gargaj's avatar
Gargaj committed
259
260
261
262
        mouseEventBuffer[mouseEventBufferCount].button = MOUSEBUTTON_LEFT;
        mouseEventBuffer[mouseEventBufferCount].x = GET_X_LPARAM(lParam);
        mouseEventBuffer[mouseEventBufferCount].y = GET_Y_LPARAM(lParam);
        mouseEventBufferCount++;
Gargaj's avatar
Gargaj committed
263
264
      } break;

265
266
267
268
269
270
271
272
    case WM_MOUSEMOVE: 
      {
        mouseEventBuffer[mouseEventBufferCount].eventType = MOUSEEVENTTYPE_MOVE;
        mouseEventBuffer[mouseEventBufferCount].x = GET_X_LPARAM(lParam);
        mouseEventBuffer[mouseEventBufferCount].y = GET_Y_LPARAM(lParam);
        mouseEventBufferCount++;
      } break;

Gargaj's avatar
Gargaj committed
273
274
    case WM_LBUTTONUP: 
      {
275
276
277
278
279
        mouseEventBuffer[mouseEventBufferCount].eventType = MOUSEEVENTTYPE_UP;
        mouseEventBuffer[mouseEventBufferCount].button = MOUSEBUTTON_LEFT;
        mouseEventBuffer[mouseEventBufferCount].x = GET_X_LPARAM(lParam);
        mouseEventBuffer[mouseEventBufferCount].y = GET_Y_LPARAM(lParam);
        mouseEventBufferCount++;
Gargaj's avatar
Gargaj committed
280
281
      } break;

mathieu _alkama_ m's avatar
mathieu _alkama_ m committed
282
283
284
285
    case WM_MOUSEWHEEL:
      {
        mouseEventBuffer[mouseEventBufferCount].eventType = MOUSEEVENTTYPE_SCROLL;
        mouseEventBuffer[mouseEventBufferCount].x = 0;
286
        mouseEventBuffer[mouseEventBufferCount].y = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
mathieu _alkama_ m's avatar
mathieu _alkama_ m committed
287
288
289
290
291
292
        mouseEventBufferCount++;
      } break;

    case WM_MOUSEHWHEEL:
      {
        mouseEventBuffer[mouseEventBufferCount].eventType = MOUSEEVENTTYPE_SCROLL;
293
        mouseEventBuffer[mouseEventBufferCount].x = -GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
mathieu _alkama_ m's avatar
mathieu _alkama_ m committed
294
295
296
297
        mouseEventBuffer[mouseEventBufferCount].y = 0;
        mouseEventBufferCount++;
      } break;

Gargaj's avatar
Gargaj committed
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
    case WM_SYSCOMMAND: 
      {
        switch (wParam) 
        {
        case SC_SCREENSAVE:
        case SC_MONITORPOWER: 
          {
            return 0;
          }
        }
      } break;

    case WM_CLOSE: 
      {
        run = false;
      } break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }

  bool InitWindow(RENDERER_SETTINGS * pSetup) 
Gargaj's avatar
Gargaj committed
320
  {
Gargaj's avatar
Gargaj committed
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
    WNDCLASS WC;

    WC.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    WC.lpfnWndProc = &WndProc;
    WC.cbClsExtra = 0;
    WC.cbWndExtra = 0;
    WC.hInstance = GetModuleHandle(NULL);
    //WC.hIcon = LoadIcon(setup->hInstance,MAKEINTRESOURCE(IDI_ICON1));
    WC.hIcon = NULL;
    WC.hCursor = LoadCursor(NULL, IDC_ARROW);
    WC.hbrBackground = NULL;
    WC.lpszMenuName = NULL;
    WC.lpszClassName = _T("fwzwnd");
    if(!RegisterClass(&WC)) return 0;

    DWORD wExStyle = WS_EX_APPWINDOW;
    DWORD wStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    if (pSetup->windowMode == RENDERER_WINDOWMODE_WINDOWED) wStyle |= WS_OVERLAPPED | WS_CAPTION;

    RECT wr={0,0,pSetup->nWidth,pSetup->nHeight};
    AdjustWindowRectEx(&wr, wStyle, FALSE, wExStyle);
Gargaj's avatar
Gargaj committed
342

343
    hWnd = CreateWindowEx(wExStyle,_T("fwzwnd"),_T("BONZOMATIC - Direct3D 9.0c edition"),wStyle,
Gargaj's avatar
Gargaj committed
344
345
346
347
348
349
      (GetSystemMetrics(SM_CXSCREEN) - pSetup->nWidth )/2,
      (GetSystemMetrics(SM_CYSCREEN) - pSetup->nHeight)/2,
      wr.right-wr.left, wr.bottom-wr.top,
      NULL, NULL, WC.hInstance, NULL);

    if (!hWnd) 
Gargaj's avatar
Gargaj committed
350
351
      return false;

Gargaj's avatar
Gargaj committed
352
353
354
355
356
357
358
    ShowWindow(hWnd, SW_SHOW);
    SetForegroundWindow(hWnd);
    SetFocus(hWnd);

    return true;
  }

Gargaj's avatar
Gargaj committed
359
  D3DPRESENT_PARAMETERS d3dpp;
Gargaj's avatar
Gargaj committed
360
361
  bool InitDirect3D(RENDERER_SETTINGS * pSetup) 
  {
Gargaj's avatar
Gargaj committed
362
363
364
365
366
367
    pD3D = Direct3DCreate9(D3D9b_SDK_VERSION);
    if (!pD3D) 
    {
      printf("[Renderer] Direct3DCreate9 failed\n");
      return false;
    }
Gargaj's avatar
Gargaj committed
368
369
370
371
372
373
374
375
376

    nWidth  = pSetup->nWidth;
    nHeight = pSetup->nHeight;

    ZeroMemory(&d3dpp,sizeof(d3dpp));

    d3dpp.SwapEffect     = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow  = hWnd;
    d3dpp.Windowed       = pSetup->windowMode != RENDERER_WINDOWMODE_FULLSCREEN;
Gargaj's avatar
Gargaj committed
377
    d3dpp.PresentationInterval = pSetup->bVsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
Gargaj's avatar
Gargaj committed
378
379
380
381
382
383
384
385

    d3dpp.BackBufferCount  = 1;

    d3dpp.BackBufferWidth  = pSetup->nWidth;
    d3dpp.BackBufferHeight = pSetup->nHeight;

    D3DDISPLAYMODE d3ddm;
    if( FAILED( pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
Gargaj's avatar
Gargaj committed
386
387
    {
      printf("[Renderer] GetAdapterDisplayMode failed\n");
Gargaj's avatar
Gargaj committed
388
      return false;
Gargaj's avatar
Gargaj committed
389
    }
Gargaj's avatar
Gargaj committed
390
391
392
393
394
395
396
397
398
399
400
401

    static D3DFORMAT pBackbufferFormats32[] = {
      D3DFMT_X8R8G8B8,
      D3DFMT_A8R8G8B8,
      D3DFMT_UNKNOWN
    };
    D3DFORMAT * pFormats = pBackbufferFormats32;
    for (int i=0; pFormats[i] != D3DFMT_UNKNOWN; i++)
      if ( SUCCEEDED(pD3D->CheckDeviceType( D3DADAPTER_DEFAULT, DEVTYPE, d3ddm.Format, pFormats[i], d3dpp.Windowed )) )
        d3dpp.BackBufferFormat = pFormats[i];

    if (d3dpp.BackBufferFormat == D3DFMT_UNKNOWN) 
Gargaj's avatar
Gargaj committed
402
403
    {
      printf("[Renderer] No suitable backbuffer format found\n");
Gargaj's avatar
Gargaj committed
404
      return false;
Gargaj's avatar
Gargaj committed
405
    }
Gargaj's avatar
Gargaj committed
406

407
    d3dpp.EnableAutoDepthStencil = FALSE;
Gargaj's avatar
Gargaj committed
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

    static D3DMULTISAMPLE_TYPE pMultisampleTypes[]=
    {
      D3DMULTISAMPLE_2_SAMPLES,
      D3DMULTISAMPLE_4_SAMPLES,
      D3DMULTISAMPLE_6_SAMPLES,
      D3DMULTISAMPLE_8_SAMPLES,
      D3DMULTISAMPLE_NONE
    };

    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;

    HRESULT h;
    h = pD3D->CreateDevice( D3DADAPTER_DEFAULT, DEVTYPE, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
    if (h != D3D_OK) 
    {
      h = pD3D->CreateDevice( D3DADAPTER_DEFAULT, DEVTYPE, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
      if(h != D3D_OK) 
      {
Gargaj's avatar
Gargaj committed
427
        printf("[Renderer] CreateDevice failed: %08X\n",h);
Gargaj's avatar
Gargaj committed
428
429
430
431
        return false;
      }
    }

Gargaj's avatar
Gargaj committed
432
    pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
Gargaj's avatar
Gargaj committed
433
434
435
436
437

    for (int x=0; x<4; x++) 
    {
      pDevice->SetSamplerState( x, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      pDevice->SetSamplerState( x, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
438
      pDevice->SetSamplerState( x, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
Gargaj's avatar
Gargaj committed
439
    }
Gargaj's avatar
Gargaj committed
440
441
442

    pDevice->GetRenderTarget( 0, &pBackBuffer );

Gargaj's avatar
Gargaj committed
443
444
445
    return 1;
  }

Gargaj's avatar
Gargaj committed
446
  LPDIRECT3DVERTEXBUFFER9 pFullscreenQuadVB = NULL;
Gargaj's avatar
Gargaj committed
447
  LPDIRECT3DVERTEXBUFFER9 pGUIQuadVB = NULL;
Gargaj's avatar
Gargaj committed
448
  LPDIRECT3DVERTEXDECLARATION9 pFullscreenQuadVertexDecl = NULL;
Gargaj's avatar
Gargaj committed
449
450

#define GUIQUADVB_SIZE (128*6)
Gargaj's avatar
Gargaj committed
451

Gargaj's avatar
Gargaj committed
452
453
454
  bool Open( RENDERER_SETTINGS * settings )
  {
    if (!InitWindow(settings))
Gargaj's avatar
Gargaj committed
455
456
    {
      printf("[Renderer] InitWindow failed\n");
Gargaj's avatar
Gargaj committed
457
      return false;
Gargaj's avatar
Gargaj committed
458
    }
Gargaj's avatar
Gargaj committed
459
460

    if (!InitDirect3D(settings))
Gargaj's avatar
Gargaj committed
461
462
    {
      printf("[Renderer] InitDirect3D failed\n");
Gargaj's avatar
Gargaj committed
463
      return false;
Gargaj's avatar
Gargaj committed
464
    }
Gargaj's avatar
Gargaj committed
465

Gargaj's avatar
Gargaj committed
466
    static D3DVERTEXELEMENT9 pFullscreenQuadElements[] = 
Gargaj's avatar
Gargaj committed
467
468
469
470
471
472
473
474
475
    {
      { 0, 0*sizeof(float), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
      { 0, 3*sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
      D3DDECL_END()
    };

    static float pQuad[] = {
      -1.0, -1.0,  0.0, 0.0, 0.0,
      -1.0,  1.0,  0.0, 0.0, 1.0,
476
       1.0, -1.0,  0.0, 1.0, 0.0,
Gargaj's avatar
Gargaj committed
477
478
479
480
481
482
483
484
485
       1.0,  1.0,  0.0, 1.0, 1.0,
    };

    pDevice->CreateVertexBuffer( 4 * 5 * sizeof(float), D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &pFullscreenQuadVB, NULL);
    void * v;
    pFullscreenQuadVB->Lock( 0, 4 * 5 * sizeof(float), &v, NULL );
    CopyMemory( v, pQuad, 4 * 5 * sizeof(float) );
    pFullscreenQuadVB->Unlock();

Gargaj's avatar
Gargaj committed
486
    pDevice->CreateVertexDeclaration( pFullscreenQuadElements, &pFullscreenQuadVertexDecl );
Gargaj's avatar
Gargaj committed
487
488
489

    //////////////////////////////////////////////////////////////////////////

490
491
492
493
494
495
496
497
    pDevice->CreateVertexBuffer( GUIQUADVB_SIZE * 6 * sizeof(float), D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_DEFAULT, &pGUIQuadVB, NULL);

    //////////////////////////////////////////////////////////////////////////

    LPD3DXBUFFER pShader = NULL;
    LPD3DXBUFFER pErrors = NULL;

    if (D3DXCompileShader( defaultVertexShader, strlen(defaultVertexShader), NULL, NULL, "main", "vs_3_0", NULL, &pShader, &pErrors, NULL ) != D3D_OK)
Gargaj's avatar
Gargaj committed
498
    {
Gargaj's avatar
Gargaj committed
499
      printf("[Renderer] D3DXCompileShader failed\n");
500
501
      return false;
    }
Gargaj's avatar
Gargaj committed
502

503
504
    if (pDevice->CreateVertexShader( (DWORD*)pShader->GetBufferPointer(), &pVertexShader ) != D3D_OK)
    {
Gargaj's avatar
Gargaj committed
505
      printf("[Renderer] CreateVertexShader failed\n");
506
507
      return false;
    }
Gargaj's avatar
Gargaj committed
508

Gargaj's avatar
Gargaj committed
509
510
511
512
513
514
    if (pDevice->CreateOffscreenPlainSurface( settings->nWidth, settings->nHeight, d3dpp.BackBufferFormat, D3DPOOL_SYSTEMMEM, &pFrameGrabTexture, NULL) != D3D_OK)
    {
      printf("[Renderer] CreateOffscreenPlainSurface failed\n");
      return false;
    }

Gargaj's avatar
Gargaj committed
515
516
517
    return true;
  }

Gargaj's avatar
Gargaj committed
518
  unsigned int nCacheFlushCount = 0;
Gargaj's avatar
Gargaj committed
519
520
  void StartFrame()
  {
Gargaj's avatar
Gargaj committed
521
    nCacheFlushCount = 0;
Gargaj's avatar
Gargaj committed
522
    MSG msg;
Gargaj's avatar
Gargaj committed
523
524
    if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) 
    {
Gargaj's avatar
Gargaj committed
525
526
527
528
      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }

Gargaj's avatar
Gargaj committed
529
    pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0xFF808080, 1.0f, 0 );
Gargaj's avatar
Gargaj committed
530
    pDevice->BeginScene();
Gargaj's avatar
Gargaj committed
531
532
533
  }
  void EndFrame()
  {
Gargaj's avatar
Gargaj committed
534
535
    pDevice->EndScene();
    pDevice->Present( NULL, NULL, NULL, NULL );
Gargaj's avatar
Gargaj committed
536
537
538
539
540
541
542
  }
  bool WantsToQuit()
  {
    return !run;
  }
  void Close()
  {
Gargaj's avatar
Gargaj committed
543
544
545
546
547
    if (pFullscreenQuadVB) pFullscreenQuadVB->Release();
    if (pFullscreenQuadVertexDecl) pFullscreenQuadVertexDecl->Release();
    if (pGUIQuadVB) pGUIQuadVB->Release();
    if (pVertexShader) pVertexShader->Release();
    if (theShader) theShader->Release();
Gargaj's avatar
Gargaj committed
548
549
    if (pDevice) pDevice->Release();
    if (pD3D) pD3D->Release();
Gargaj's avatar
Gargaj committed
550
551
552
553
554
    if (!hWnd) 
    {
      DestroyWindow(hWnd);
      UnregisterClass(_T("fwzwnd"),GetModuleHandle(NULL));
    }
Gargaj's avatar
Gargaj committed
555
556
557
558
  }

  void RenderFullscreenQuad()
  {
Gargaj's avatar
Gargaj committed
559
560
    pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, false );

561
    pDevice->SetVertexShader( pVertexShader );
Gargaj's avatar
Gargaj committed
562
563
    pDevice->SetPixelShader( theShader );
    
Gargaj's avatar
Gargaj committed
564
    pDevice->SetVertexDeclaration( pFullscreenQuadVertexDecl );
Gargaj's avatar
Gargaj committed
565
566
    pDevice->SetStreamSource( 0, pFullscreenQuadVB, 0, sizeof(float) * 5 ); 
    pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
Gargaj's avatar
Gargaj committed
567
568
569
570
  }

  bool ReloadShader( char * szShaderCode, int nShaderCodeSize, char * szErrorBuffer, int nErrorBufferSize )
  {
Gargaj's avatar
Gargaj committed
571
572
573
    LPD3DXBUFFER pShader = NULL;
    LPD3DXBUFFER pErrors = NULL;

574
    if (D3DXCompileShader( szShaderCode, nShaderCodeSize, NULL, NULL, "main", "ps_3_0", NULL, &pShader, &pErrors, &pConstantTable ) != D3D_OK)
Gargaj's avatar
Gargaj committed
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    {
      memset( szErrorBuffer, 0, nErrorBufferSize );
      strncpy( szErrorBuffer, (char*)pErrors->GetBufferPointer(), nErrorBufferSize - 1 );
      return false;
    }

    if (theShader) 
    {
      theShader->Release();
      theShader = NULL;
    }

    if (pDevice->CreatePixelShader( (DWORD*)pShader->GetBufferPointer(), &theShader ) != D3D_OK)
    {
      return false;
    }

Gargaj's avatar
Gargaj committed
592
593
594
595
596
    return true;
  }

  void SetShaderConstant( char * szConstName, float x )
  {
Gargaj's avatar
Gargaj committed
597
    pConstantTable->SetFloat( pDevice, szConstName, x );
Gargaj's avatar
Gargaj committed
598
599
600
601
  }

  void SetShaderConstant( char * szConstName, float x, float y )
  {
Gargaj's avatar
Gargaj committed
602
    pConstantTable->SetVector( pDevice, szConstName, &D3DXVECTOR4(x, y, 0, 0) );
Gargaj's avatar
Gargaj committed
603
604
605
606
  }

  struct DX9Texture : public Texture
  {
Gargaj's avatar
Gargaj committed
607
    LPDIRECT3DTEXTURE9 pTexture;
Gargaj's avatar
Gargaj committed
608
609
610
611
612
  };

  int textureUnit = 0;
  Texture * CreateRGBA8TextureFromFile( char * szFilename )
  {
Gargaj's avatar
Gargaj committed
613
614
615
616
617
618
619
    LPDIRECT3DTEXTURE9 pTex = NULL;
    D3DXIMAGE_INFO info;
    HRESULT h = D3DXCreateTextureFromFileExA(
      pDevice,
      szFilename,
      D3DX_DEFAULT,
      D3DX_DEFAULT,
620
      0,
Gargaj's avatar
Gargaj committed
621
622
623
      NULL,
      D3DFMT_FROM_FILE,
      D3DPOOL_DEFAULT,
624
      D3DX_DEFAULT,
Gargaj's avatar
Gargaj committed
625
626
627
628
629
630
631
632
633
      D3DX_DEFAULT,
      NULL,
      &info,
      NULL,
      &pTex);

    if (!pTex)
      return NULL;

Gargaj's avatar
Gargaj committed
634
    DX9Texture * tex = new DX9Texture();
Gargaj's avatar
Gargaj committed
635
636
637
    tex->pTexture = pTex;
    tex->width = info.Width;
    tex->height = info.Height;
Gargaj's avatar
Gargaj committed
638
639
640
641
642
643
    tex->type = TEXTURETYPE_2D;
    return tex;
  }

  Texture * Create1DR32Texture( int w )
  {
Gargaj's avatar
Gargaj committed
644
645
646
647
648
649
650
651
652
653
654
    LPDIRECT3DTEXTURE9 pTex = NULL;
    pDevice->CreateTexture( w, 1, 0, D3DUSAGE_DYNAMIC, D3DFMT_R32F, D3DPOOL_DEFAULT, &pTex, NULL );

    if (!pTex)
      return NULL;

    D3DLOCKED_RECT rect;
    pTex->LockRect( 0, &rect, NULL, NULL );
    memset( rect.pBits, 0, w * sizeof(float) );
    pTex->UnlockRect(0);

Gargaj's avatar
Gargaj committed
655
    DX9Texture * tex = new DX9Texture();
Gargaj's avatar
Gargaj committed
656
    tex->pTexture = pTex;
Gargaj's avatar
Gargaj committed
657
658
659
660
661
662
663
664
    tex->width = w;
    tex->height = 1;
    tex->type = TEXTURETYPE_1D;
    return tex;
  }

  void SetShaderTexture( char * szTextureName, Texture * tex )
  {
Gargaj's avatar
Gargaj committed
665
    int idx = pConstantTable->GetSamplerIndex( szTextureName );
Gargaj's avatar
Gargaj committed
666
    if (idx >= 0)
667
668
669
670
    {
      pDevice->SetSamplerState( idx, D3DSAMP_SRGBTEXTURE, TRUE );
      pDevice->SetSamplerState( idx, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
      pDevice->SetSamplerState( idx, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
Gargaj's avatar
Gargaj committed
671
      pDevice->SetTexture( idx, ((DX9Texture *)tex)->pTexture );
672
    }
Gargaj's avatar
Gargaj committed
673
674
675
676
  }

  bool UpdateR32Texture( Texture * tex, float * data )
  {
Gargaj's avatar
Gargaj committed
677
678
679
680
681
682
683
    LPDIRECT3DTEXTURE9 pTex = ((DX9Texture *)tex)->pTexture;
    
    D3DLOCKED_RECT rect;
    pTex->LockRect( 0, &rect, NULL, D3DLOCK_DISCARD );
    memcpy( rect.pBits, data, tex->width * sizeof(float) );
    pTex->UnlockRect(0);

Gargaj's avatar
Gargaj committed
684
685
686
687
688
    return true;
  }

  Texture * CreateA8TextureFromData( int w, int h, unsigned char * data )
  {
Gargaj's avatar
Gargaj committed
689
    LPDIRECT3DTEXTURE9 pTex = NULL;
Gargaj's avatar
Gargaj committed
690
    pDevice->CreateTexture( w, h, 0, NULL, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTex, NULL );
Gargaj's avatar
Gargaj committed
691
692
693
694
695
696
697
698
699
700

    if (!pTex)
      return NULL;

    D3DLOCKED_RECT rect;
    pTex->LockRect( 0, &rect, NULL, NULL );
    unsigned char * src = data;
    unsigned char * dst = (unsigned char *)rect.pBits;
    for (int i=0; i<h; i++)
    {
Gargaj's avatar
Gargaj committed
701
702
703
704
705
706
707
708
      unsigned char * srcLine = src;
      unsigned int * dstLine = (unsigned int *)dst;
      for (int j=0; j<w; j++)
      {
        *dstLine = (*srcLine << 24) | 0xFFFFFF;
        srcLine++;
        dstLine++;
      }
Gargaj's avatar
Gargaj committed
709
710
711
712
713
      src += w * sizeof(unsigned char);
      dst += rect.Pitch;
    }
    pTex->UnlockRect(0);

Gargaj's avatar
Gargaj committed
714
    DX9Texture * tex = new DX9Texture();
Gargaj's avatar
Gargaj committed
715
    tex->pTexture = pTex;
Gargaj's avatar
Gargaj committed
716
    tex->width = w;
Gargaj's avatar
Gargaj committed
717
    tex->height = h;
Gargaj's avatar
Gargaj committed
718
719
720
721
    tex->type = TEXTURETYPE_1D;
    return tex;
  }

Gargaj's avatar
Gargaj committed
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
  //////////////////////////////////////////////////////////////////////////
  // text rendering


  void StartTextRendering()
  {
    pDevice->SetVertexShader( NULL );
    pDevice->SetPixelShader( NULL );
    pDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, TRUE );
    //pDevice->SetVertexDeclaration( pGUIVertexDecl );
    pDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
    pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
    pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
    pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

    D3DXMATRIX mat;
    D3DXMatrixIdentity( &mat );
    pDevice->SetTransform( D3DTS_VIEW, &mat );
    pDevice->SetTransform( D3DTS_WORLD, &mat );
    D3DXMatrixOrthoOffCenterLH( (D3DXMATRIX*)&mat, 0, nWidth, nHeight, 0, -1.0f, 1.0f );
    pDevice->SetTransform( D3DTS_PROJECTION, &mat );

Gargaj's avatar
Gargaj committed
744
    pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
Gargaj's avatar
Gargaj committed
745
    pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
Gargaj's avatar
Gargaj committed
746
    pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TEXTURE );
Gargaj's avatar
Gargaj committed
747
748
749
750
751
    pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
    pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
    pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE );
  }

Gargaj's avatar
Gargaj committed
752
753
  void ReleaseTexture( Texture * tex )
  {
Gargaj's avatar
Gargaj committed
754
755
    ((DX9Texture *)tex)->pTexture->Release();
    delete tex;
Gargaj's avatar
Gargaj committed
756
757
  }

Gargaj's avatar
Gargaj committed
758
759
760
761
762
763
764
  int bufferPointer = 0;
  unsigned char buffer[GUIQUADVB_SIZE * sizeof(float) * 6];
  bool lastModeIsQuad = true;
  void __FlushRenderCache()
  {
    if (!bufferPointer) return;

Gargaj's avatar
Gargaj committed
765
    nCacheFlushCount++;
Gargaj's avatar
Gargaj committed
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
    void * v = NULL;
    pGUIQuadVB->Lock( 0, bufferPointer * sizeof(float) * 6, &v, NULL );
    CopyMemory( v, buffer, bufferPointer * sizeof(float) * 6 );
    pGUIQuadVB->Unlock();

    pDevice->SetStreamSource( 0, pGUIQuadVB, 0, sizeof(float) * 6 ); 
    if (lastModeIsQuad)
      pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, bufferPointer / 3 );
    else
      pDevice->DrawPrimitive( D3DPT_LINELIST, 0, bufferPointer / 2 );

    bufferPointer = 0;
  }
  inline unsigned int _dxARGBtoABGR(unsigned int abgr)
  {
    return (abgr&0xff00ff00)+((abgr<<16)&0x00ff0000)+((abgr>>16)&0x000000ff);
  }
Gargaj's avatar
Gargaj committed
783
  Texture * lastTexture = NULL;
Gargaj's avatar
Gargaj committed
784
  void __WriteVertexToBuffer( const Vertex & v )
Gargaj's avatar
Gargaj committed
785
786
787
788
789
790
791
792
793
794
795
  {
    if (bufferPointer >= GUIQUADVB_SIZE)
    {
      __FlushRenderCache();
    }

    float * f = (float*)(buffer + bufferPointer * sizeof(float) * 6);
    *(f++) = v.x;
    *(f++) = v.y;
    *(f++) = 0.0;
    *(unsigned int *)(f++) = _dxARGBtoABGR( v.c );
Gargaj's avatar
Gargaj committed
796
797
    *(f++) = v.u + (lastTexture ? (0.5 / (float)lastTexture->width ) : 0.0);
    *(f++) = v.v + (lastTexture ? (0.5 / (float)lastTexture->height) : 0.0);
Gargaj's avatar
Gargaj committed
798
799
    bufferPointer++;
  }
Gargaj's avatar
Gargaj committed
800
801
  void BindTexture( Texture * tex )
  {
Gargaj's avatar
Gargaj committed
802
803
804
805
806
807
    if (lastTexture != tex)
    {
      __FlushRenderCache();
      lastTexture = tex;
      pDevice->SetTexture( 0, tex ? ((DX9Texture *)tex)->pTexture : NULL );
    }
Gargaj's avatar
Gargaj committed
808
809
  }

Gargaj's avatar
Gargaj committed
810
  void RenderQuad( const Vertex & a, const Vertex & b, const Vertex & c, const Vertex & d )
Gargaj's avatar
Gargaj committed
811
  {
Gargaj's avatar
Gargaj committed
812
813
814
815
816
817
818
819
820
821
    if (!lastModeIsQuad)
    {
      __FlushRenderCache();
      lastModeIsQuad = true;
    }
    __WriteVertexToBuffer(a);
    __WriteVertexToBuffer(b);
    __WriteVertexToBuffer(d);
    __WriteVertexToBuffer(b);
    __WriteVertexToBuffer(c);
822
    __WriteVertexToBuffer(d);
Gargaj's avatar
Gargaj committed
823
824
  }

Gargaj's avatar
Gargaj committed
825
  void RenderLine( const Vertex & a, const Vertex & b )
Gargaj's avatar
Gargaj committed
826
  {
Gargaj's avatar
Gargaj committed
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
    if (lastModeIsQuad)
    {
      __FlushRenderCache();
      lastModeIsQuad = false;
    }
    __WriteVertexToBuffer(a);
    __WriteVertexToBuffer(b);
  }

  void SetTextRenderingViewport( Scintilla::PRectangle rect )
  {
    __FlushRenderCache();
    D3DXMATRIX mat;
    D3DXMatrixIdentity( &mat );
    mat._41 = rect.left;
    mat._42 = rect.top;
    pDevice->SetTransform( D3DTS_WORLD, &mat );

    RECT rc = { rect.left, rect.top, rect.right, rect.bottom };
    pDevice->SetScissorRect( &rc );
  }
  void EndTextRendering()
  {
    __FlushRenderCache();
    pDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, false );
    pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
Gargaj's avatar
Gargaj committed
853
854
  }

Gargaj's avatar
Gargaj committed
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
  //////////////////////////////////////////////////////////////////////////

  bool GrabFrame( void * pPixelBuffer )
  {
    if (!pFrameGrabTexture)
      return false;

    if (pDevice->GetRenderTargetData( pBackBuffer, pFrameGrabTexture ) != D3D_OK)
      return false;

    D3DLOCKED_RECT rect;
    if (pFrameGrabTexture->LockRect( &rect, NULL, NULL ) != D3D_OK)
      return false;
    
    unsigned char* pSrc = (unsigned char*)rect.pBits;
    unsigned char* pDst = (unsigned char*)pPixelBuffer;
    for( int i = 0; i < nHeight; i++ )
    {
      unsigned int* pSrc32 = (unsigned int*)pSrc;
      unsigned int* pDst32 = (unsigned int*)pDst;
      for(int j=0; j < nWidth; j++)
        pDst32[j] = (pSrc32[j] & 0x00FF00) | ((pSrc32[j] >> 16) & 0xFF) | ((pSrc32[j] & 0xFF) << 16) | 0xFF000000;

      pSrc += rect.Pitch;
      pDst += nWidth * 4;
    }

    pFrameGrabTexture->UnlockRect();

    return true;
  }
Gargaj's avatar
Gargaj committed
886
}