1 /*!
2 	@file
3 	@author		Losev Vasiliy aka bool
4 	@date		06/2009
5 */
6 
7 #include <d3dx9.h>
8 #include "MyGUI_DirectXRenderManager.h"
9 #include "MyGUI_DirectXTexture.h"
10 #include "MyGUI_DirectXVertexBuffer.h"
11 #include "MyGUI_DirectXDiagnostic.h"
12 #include "MyGUI_Gui.h"
13 #include "MyGUI_Timer.h"
14 
15 namespace MyGUI
16 {
17 
DirectXRenderManager()18 	DirectXRenderManager::DirectXRenderManager() :
19 		mIsInitialise(false),
20 		mpD3DDevice(nullptr),
21 		mUpdate(false)
22 	{
23 	}
24 
initialise(IDirect3DDevice9 * _device)25 	void DirectXRenderManager::initialise(IDirect3DDevice9* _device)
26 	{
27 		MYGUI_PLATFORM_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
28 		MYGUI_PLATFORM_LOG(Info, "* Initialise: " << getClassTypeName());
29 
30 		mpD3DDevice = _device;
31 
32 		mVertexFormat = VertexColourType::ColourARGB;
33 
34 		memset(&mInfo, 0, sizeof(mInfo));
35 		if (mpD3DDevice != nullptr)
36 		{
37 			D3DVIEWPORT9 vp;
38 			mpD3DDevice->GetViewport(&vp);
39 			setViewSize(vp.Width, vp.Height);
40 		}
41 
42 		mUpdate = false;
43 
44 		if (mpD3DDevice != nullptr)
45 		{
46 			D3DCAPS9 caps;
47 			mpD3DDevice->GetDeviceCaps(&caps);
48 			if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
49 			{
50 				MYGUI_PLATFORM_LOG(Warning, "Non-squared textures not supported.");
51 			}
52 		}
53 
54 		MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully initialized");
55 		mIsInitialise = true;
56 	}
57 
shutdown()58 	void DirectXRenderManager::shutdown()
59 	{
60 		MYGUI_PLATFORM_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
61 		MYGUI_PLATFORM_LOG(Info, "* Shutdown: " << getClassTypeName());
62 
63 		destroyAllResources();
64 		mpD3DDevice = nullptr;
65 
66 		MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully shutdown");
67 		mIsInitialise = false;
68 	}
69 
createVertexBuffer()70 	IVertexBuffer* DirectXRenderManager::createVertexBuffer()
71 	{
72 		return new DirectXVertexBuffer(mpD3DDevice, this);
73 	}
74 
destroyVertexBuffer(IVertexBuffer * _buffer)75 	void DirectXRenderManager::destroyVertexBuffer(IVertexBuffer* _buffer)
76 	{
77 		delete _buffer;
78 	}
79 
doRender(IVertexBuffer * _buffer,ITexture * _texture,size_t _count)80 	void DirectXRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count)
81 	{
82 		DirectXTexture* dxTex = static_cast<DirectXTexture*>(_texture);
83 		mpD3DDevice->SetTexture(0, dxTex->getDirectXTexture());
84 		DirectXVertexBuffer* dxVB = static_cast<DirectXVertexBuffer*>(_buffer);
85 		dxVB->setToStream(0);
86 		// count in vertexes, triangle_list = vertexes / 3
87 		mpD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, _count / 3);
88 	}
89 
drawOneFrame()90 	void DirectXRenderManager::drawOneFrame()
91 	{
92 		Gui* gui = Gui::getInstancePtr();
93 		if (gui == nullptr)
94 			return;
95 
96 		static Timer timer;
97 		static unsigned long last_time = timer.getMilliseconds();
98 		unsigned long now_time = timer.getMilliseconds();
99 		unsigned long time = now_time - last_time;
100 
101 		onFrameEvent((float)((double)(time) / (double)1000));
102 
103 		last_time = now_time;
104 
105 		begin();
106 		onRenderToTarget(this, mUpdate);
107 		end();
108 
109 		mUpdate = false;
110 	}
111 
begin()112 	void DirectXRenderManager::begin()
113 	{
114 		mpD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
115 
116 		mpD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
117 		mpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
118 		mpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
119 		mpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
120 
121 		mpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
122 		mpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG0, D3DTA_DIFFUSE);
123 		mpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
124 		mpD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
125 
126 		mpD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
127 		mpD3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
128 		mpD3DDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
129 
130 		mpD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
131 		mpD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
132 
133 		mpD3DDevice->SetRenderState(D3DRS_SRCBLEND,   D3DBLEND_SRCALPHA);
134 		mpD3DDevice->SetRenderState(D3DRS_DESTBLEND,  D3DBLEND_INVSRCALPHA);
135 
136 		mpD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
137 		mpD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
138 		mpD3DDevice->SetRenderState(D3DRS_LIGHTING, 0);
139 		mpD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
140 
141 		mpD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
142 
143 		mpD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
144 
145 		D3DXMATRIX m;
146 		D3DXMatrixIdentity(&m);
147 		mpD3DDevice->SetTransform(D3DTS_WORLD, &m);
148 		mpD3DDevice->SetTransform(D3DTS_VIEW, &m);
149 		mpD3DDevice->SetTransform(D3DTS_PROJECTION, &m);
150 	}
151 
end()152 	void DirectXRenderManager::end()
153 	{
154 	}
155 
createTexture(const std::string & _name)156 	ITexture* DirectXRenderManager::createTexture(const std::string& _name)
157 	{
158 		MapTexture::const_iterator item = mTextures.find(_name);
159 		MYGUI_PLATFORM_ASSERT(item == mTextures.end(), "Texture '" << _name << "' already exist");
160 
161 		DirectXTexture* texture = new DirectXTexture(_name, mpD3DDevice);
162 		mTextures[_name] = texture;
163 		return texture;
164 	}
165 
destroyTexture(ITexture * _texture)166 	void DirectXRenderManager::destroyTexture(ITexture* _texture)
167 	{
168 		if (_texture == nullptr)
169 			return;
170 
171 		MapTexture::iterator item = mTextures.find(_texture->getName());
172 		MYGUI_PLATFORM_ASSERT(item != mTextures.end(), "Texture '" << _texture->getName() << "' not found");
173 
174 		mTextures.erase(item);
175 		delete _texture;
176 	}
177 
getTexture(const std::string & _name)178 	ITexture* DirectXRenderManager::getTexture(const std::string& _name)
179 	{
180 		MapTexture::const_iterator item = mTextures.find(_name);
181 		if (item != mTextures.end())
182 			return item->second;
183 		return nullptr;
184 	}
185 
isFormatSupported(PixelFormat _format,TextureUsage _usage)186 	bool DirectXRenderManager::isFormatSupported(PixelFormat _format, TextureUsage _usage)
187 	{
188 		D3DFORMAT internalFormat = D3DFMT_UNKNOWN;
189 		unsigned long internalUsage = 0;
190 		D3DPOOL internalPool = D3DPOOL_MANAGED;
191 
192 		if (_usage == TextureUsage::RenderTarget)
193 		{
194 			internalUsage |= D3DUSAGE_RENDERTARGET;
195 			internalPool = D3DPOOL_MANAGED;
196 		}
197 		else if (_usage == TextureUsage::Dynamic)
198 			internalUsage |= D3DUSAGE_DYNAMIC;
199 		else if (_usage == TextureUsage::Stream)
200 			internalUsage |= D3DUSAGE_DYNAMIC;
201 
202 		if (_format == PixelFormat::R8G8B8A8)
203 		{
204 			internalFormat = D3DFMT_A8R8G8B8;
205 		}
206 		else if (_format == PixelFormat::R8G8B8)
207 		{
208 			internalFormat = D3DFMT_R8G8B8;
209 		}
210 		else if (_format == PixelFormat::L8A8)
211 		{
212 			internalFormat = D3DFMT_A8L8;
213 		}
214 		else if (_format == PixelFormat::L8)
215 		{
216 			internalFormat = D3DFMT_L8;
217 		}
218 
219 		D3DFORMAT requestedlFormat = internalFormat;
220 		D3DXCheckTextureRequirements(mpD3DDevice, nullptr, nullptr, nullptr, internalUsage, &internalFormat, internalPool);
221 
222 		bool result = requestedlFormat == internalFormat;
223 		if (!result)
224 			MYGUI_PLATFORM_LOG(Warning, "Texture format '" << requestedlFormat << "'is not supported.");
225 		return result;
226 	}
227 
destroyAllResources()228 	void DirectXRenderManager::destroyAllResources()
229 	{
230 		for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item)
231 		{
232 			delete item->second;
233 		}
234 		mTextures.clear();
235 	}
236 
setViewSize(int _width,int _height)237 	void DirectXRenderManager::setViewSize(int _width, int _height)
238 	{
239 		if (_height == 0)
240 			_height = 1;
241 		if (_width == 0)
242 			_width = 1;
243 
244 		mViewSize.set(_width, _height);
245 
246 		mInfo.maximumDepth = 0.0f;
247 		mInfo.hOffset = -0.5f / float(mViewSize.width);
248 		mInfo.vOffset = -0.5f / float(mViewSize.height);
249 		mInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
250 		mInfo.pixScaleX = 1.0f / float(mViewSize.width);
251 		mInfo.pixScaleY = 1.0f / float(mViewSize.height);
252 
253 		onResizeView(mViewSize);
254 
255 		mUpdate = true;
256 	}
257 
deviceLost()258 	void DirectXRenderManager::deviceLost()
259 	{
260 		MYGUI_PLATFORM_LOG(Info, "device D3D lost");
261 
262 		for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item)
263 		{
264 			static_cast<DirectXTexture*>(item->second)->deviceLost();
265 		}
266 	}
267 
deviceRestore()268 	void DirectXRenderManager::deviceRestore()
269 	{
270 		MYGUI_PLATFORM_LOG(Info, "device D3D restore");
271 
272 		for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item)
273 		{
274 			static_cast<DirectXTexture*>(item->second)->deviceRestore();
275 		}
276 
277 		mUpdate = true;
278 	}
279 
280 } // namespace MyGUI
281