2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "surfacewin.h"
26 //This is stuff for rendering the OSD
34 external_driving=false;
35 event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
36 d3dmutex = CreateMutex(NULL,FALSE,NULL);
42 if (initted) shutdown();
44 CloseHandle(d3dmutex);
49 if (!initted) return 0;
53 int OsdWin::init(void* device)
55 if (initted) return 0;
56 Video* video = Video::getInstance();
57 //First Create Direct 3D Object
58 d3d=Direct3DCreate9(D3D_SDK_VERSION);
61 Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 object!");
64 // then create the Device
65 D3DPRESENT_PARAMETERS d3dparas;
66 ZeroMemory(&d3dparas,sizeof(d3dparas));
67 d3dparas.BackBufferWidth=video->getScreenWidth();
68 d3dparas.BackBufferHeight=video->getScreenHeight();
69 d3dparas.Windowed=TRUE;
70 d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
71 if (d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,*((HWND*) device),
72 D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dparas,&d3ddevice)!=D3D_OK) {
73 Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 device!");
76 //TODO a render function and a device lost detection
78 if (!InitVertexBuffer()) {
79 Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 vertex buf!");
83 //Now we will create the Screen
84 screen = new SurfaceWin(Surface::SCREEN);
85 SetEvent(event);//Now all devices are ready
86 screen->create(video->getScreenWidth(), video->getScreenHeight());
88 initted = 1; // must set this here or create surface won't work
94 int OsdWin::InitVertexBuffer() {
95 Video* video = Video::getInstance();
96 FLOAT texx=((float)video->getScreenWidth())/1024.f;
97 FLOAT texy=((float)video->getScreenHeight())/1024.f;
98 D3DCOLOR osdcolor=D3DCOLOR_RGBA(255,255,255,255);
99 osdvertices[0].c=osdcolor;
100 osdvertices[0].x=0.f-0.5f;
101 osdvertices[0].y=0.f-0.5f;
102 osdvertices[0].z=0.5f;
103 osdvertices[0].rhw=1.f;
104 osdvertices[0].u=0.f;
105 osdvertices[0].v=0.f;
106 osdvertices[1].c=osdcolor;
107 osdvertices[1].x=((float)video->getScreenWidth())-0.5f;-0.5f;
108 osdvertices[1].y=0.f-0.5f;
109 osdvertices[1].z=0.5f;
110 osdvertices[1].u=texx;
111 osdvertices[1].v=0.f;
112 osdvertices[1].rhw=1.f;
113 osdvertices[2].c=osdcolor;
114 osdvertices[2].x=((float)video->getScreenWidth())-0.5f;
115 osdvertices[2].y=((float)video->getScreenHeight())-0.5f;
116 osdvertices[2].z=0.5f;
117 osdvertices[2].rhw=1.f;
118 osdvertices[2].u=texx;
119 osdvertices[2].v=texy;
120 osdvertices[3].c=osdcolor;
121 osdvertices[3].x=0.f-0.5f;
122 osdvertices[3].y=((float)video->getScreenHeight())-0.5f;
124 osdvertices[3].rhw=1.f;
125 osdvertices[3].u=0.f;
126 osdvertices[3].v=texy;
131 if (d3ddevice->CreateVertexBuffer(4*sizeof(OSDVERTEX),0,D3DFVF_OSDVERTEX,D3DPOOL_MANAGED,
132 &d3dvb,NULL)!=D3D_OK) {
136 if (d3dvb->Lock(0,sizeof(osdvertices),&pvertex,0)!=D3D_OK) {
139 memcpy(pvertex,osdvertices,sizeof(osdvertices));
144 int OsdWin::shutdown()
146 if (!initted) return 0;
148 d3ddevice->Release();
154 void OsdWin::screenShot(char* fileName)
156 screen->screenShot(fileName);
159 // This function is called from the WinMain function in order to get Screen updates
160 void OsdWin::Render()
162 if (!initted) return ;
163 if (external_driving) {
164 Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads
171 void OsdWin::InternalRendering(){
172 WaitForSingleObject(event,INFINITE);
174 if (external_driving) {
175 //Copy video to Backbuffer
178 d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
181 if (d3ddevice->BeginScene()==D3D_OK) {
182 d3ddevice->SetStreamSource(0,d3dvb,0,sizeof(OSDVERTEX));
183 d3ddevice->SetFVF(D3DFVF_OSDVERTEX);
184 d3ddevice->SetTexture(0,((SurfaceWin*)screen)->getD3dtexture());
185 //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
186 d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_MODULATE);
187 d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
188 d3ddevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
189 d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
190 d3ddevice->SetRenderState(D3DRS_LIGHTING,FALSE);
193 d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
194 d3ddevice->EndScene();
195 //Show it to the user!
196 if (d3ddevice->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST){
202 if (!external_driving) {
203 Sleep(4);//The User can wait for 4 milliseconds to see his changes
207 void OsdWin::DoLost(){
208 Log::getInstance()->log("OSD", Log::DEBUG, "Direct3D Device Lost! Reobtaining...");
210 //First we free up all resources
211 Video* video = Video::getInstance();
212 ((SurfaceWin*)screen)->ReleaseSurface();
215 D3DPRESENT_PARAMETERS d3dparas;
216 ZeroMemory(&d3dparas,sizeof(d3dparas));
217 d3dparas.BackBufferWidth=video->getScreenWidth();
218 d3dparas.BackBufferHeight=video->getScreenHeight();
219 d3dparas.Windowed=TRUE;
220 d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
221 if (d3ddevice->Reset(&d3dparas)!=D3D_OK){
224 screen->create(video->getScreenWidth(), video->getScreenHeight());
227 //Redraw Views, Chris could you add a member function to viewman, so that
228 // I can cause it to completely redraw the Views?
229 // Otherwise the OSD would be distorted after Device Lost
233 LPDIRECT3DDEVICE9 OsdWin::getD3dDev() {
234 WaitForSingleObject(event,INFINITE);//We will only return if we are initted
238 void OsdWin::BeginPainting() {//We synchronize calls to d3d between different threads
239 WaitForSingleObject(d3dmutex,INFINITE);
242 void OsdWin::EndPainting() {
243 ReleaseMutex(d3dmutex);