source: OGRE/trunk/ogrenew/RenderSystems/Direct3D7/src/OgreD3D7Device.cpp @ 690

Revision 690, 11.9 KB checked in by mattausch, 19 years ago (diff)

added ogre 1.07 main

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreD3D7RenderSystem.h"
26#include "OgreD3D7Device.h"
27#include "OgreDDDriver.h"
28#include "OgreDDVideoMode.h"
29#include "OgreLight.h"
30#include "OgreCamera.h"
31#include "OgreLogManager.h"
32#include "OgreException.h"
33
34namespace Ogre {
35
36    static HRESULT CALLBACK EnumZBuffersCallback(DDPIXELFORMAT* pddpf,
37            VOID* pFormats)
38    {
39        // Add to list of formats
40        std::vector<DDPIXELFORMAT> *vec;
41        vec = (std::vector<DDPIXELFORMAT>*)pFormats;
42
43        if (pddpf->dwFlags & DDPF_ZBUFFER)
44            vec->push_back(*pddpf);
45        return D3DENUMRET_OK;
46
47    }
48
49
50
51
52    D3DDevice D3DDevice::operator=(const D3DDevice &orig)
53    {
54
55
56        mDeviceName = orig.mDeviceName;
57        mDeviceDescription = orig.mDeviceDescription;
58        mD3DDeviceDesc = orig.mD3DDeviceDesc;
59        mIsHardwareAccelerated = orig.mIsHardwareAccelerated;
60        mNeedsZBuffer = orig.mNeedsZBuffer;
61
62
63        return *this;
64
65    }
66
67    // Default constructor
68    D3DDevice::D3DDevice()
69    {
70        // Init pointers
71        lpD3D = NULL;
72
73    }
74
75    // Copy Constructor
76    D3DDevice::D3DDevice(const D3DDevice &ob)
77    {
78        lpD3D = ob.lpD3D;
79        mViewport = ob.mViewport;
80        mDeviceDescription = ob.mDeviceDescription;
81        mDeviceName = ob.mDeviceName;
82        mD3DDeviceDesc = ob.mD3DDeviceDesc;
83        mIsHardwareAccelerated = ob.mIsHardwareAccelerated;
84        mNeedsZBuffer = ob.mNeedsZBuffer;
85
86    }
87
88    // Enum constructor
89    D3DDevice::D3DDevice(LPDIRECT3D7 lpDirect3D, LPSTR lpDeviceDesc, LPSTR lpDeviceName,
90                    LPD3DDEVICEDESC7 lpD3DDeviceDesc)
91    {
92        // Init pointers
93        lpD3D = NULL;
94
95        // Copy pointer to Direct3D7 interface
96        lpD3D = lpDirect3D;
97
98        // Copy Name and Description
99        mDeviceDescription = lpDeviceDesc;
100        mDeviceName = lpDeviceName;
101
102        // Is this a hardware or emulation device?
103        mIsHardwareAccelerated = ( 0 != (lpD3DDeviceDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) );
104
105
106        // Copy device description
107        // No need to differentiate between SW and HW anymore
108        memcpy(&mD3DDeviceDesc, lpD3DDeviceDesc, sizeof(D3DDEVICEDESC7));
109
110        StringUtil::StrStreamType str;
111        str << "Detected Direct3D Device " << lpDeviceDesc;
112        LogManager::getSingleton().logMessage(str.str());
113        logCaps();
114
115        // Do we need a Z Buffer?
116        mNeedsZBuffer = !(mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR);
117        if (mNeedsZBuffer)
118            LogManager::getSingleton().logMessage("This device needs a Z-Buffer");
119        else
120            LogManager::getSingleton().logMessage("This device does not need a Z-Buffer");
121
122
123    }
124
125    D3DDevice::~D3DDevice()
126    {
127    }
128
129    LPDIRECT3DDEVICE7 D3DDevice::createDevice(LPDIRECTDRAWSURFACE7 renderTarget)
130    {
131        LPDIRECT3DDEVICE7 dev;
132        HRESULT hr;
133
134        hr = lpD3D->CreateDevice(mD3DDeviceDesc.deviceGUID, renderTarget, &dev);
135        if(FAILED(hr))
136            throw Exception(hr, "Error creating new D3D device.",
137            "D3DDevice::createDevice");
138
139        return dev;
140
141    }
142
143    LPDIRECT3D7 D3DDevice::getID3D(void)
144    {
145        return lpD3D;
146    }
147
148
149    bool D3DDevice::HardwareAccelerated(void) const
150    {
151        return mIsHardwareAccelerated;
152    }
153
154    void D3DDevice::logCaps(void) const
155    {
156        // Sends capabilities of this driver to the log
157        char msg[255];
158
159        LogManager::getSingleton().logMessage("Direct3D Device Capabilities:");
160
161        sprintf(msg, "  Hardware Accelerated: %i", HardwareAccelerated());
162        LogManager::getSingleton().logMessage(msg);
163
164        sprintf(msg, "  Mipmapping: %i", CanMipmap());
165        LogManager::getSingleton().logMessage(msg);
166
167        sprintf(msg, "  Bilinear Filtering: %i", CanBilinearFilter());
168        LogManager::getSingleton().logMessage(msg);
169
170        sprintf(msg, "  Trilinear Filtering: %i", CanTrilinearFilter());
171        LogManager::getSingleton().logMessage(msg);
172
173        sprintf(msg, "  Hardware Transform & Light: %i", CanHWTransformAndLight());
174        LogManager::getSingleton().logMessage(msg);
175
176        sprintf(msg, "  Max rendering colour depth: %i", RenderBitDepth());
177        LogManager::getSingleton().logMessage(msg);
178
179        sprintf(msg, "  Max single-pass texture layers: %i", MaxSinglePassTextureLayers());
180        LogManager::getSingleton().logMessage(msg);
181
182        sprintf(msg, "  Pixel fog supported: %i", ( mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGTABLE ) );
183        LogManager::getSingleton().logMessage(msg);
184
185        sprintf(msg, "  Vertex fog supported: %i", ( mD3DDeviceDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_FOGVERTEX) );
186        LogManager::getSingleton().logMessage(msg);
187
188
189
190    }
191
192
193    void D3DDevice::Cleanup(void)
194    {
195        // Release DirectX Objects
196
197        lpD3D = NULL;
198    }
199
200
201
202
203    String D3DDevice::DeviceName(void) const
204    {
205        return mDeviceName;
206    }
207
208    String D3DDevice::DeviceDescription(void) const
209    {
210        return mDeviceDescription;
211    }
212
213
214    void D3DDevice::createDepthBuffer(LPDIRECTDRAWSURFACE7 renderTarget)
215    {
216        DWORD bestDepth, bestStencil;
217        DDSURFACEDESC2 ddsd, src_ddsd;
218        LPDIRECTDRAW7 lpDD7;
219        LPDIRECTDRAWSURFACE7 lpZBuffer;
220        HRESULT hr;
221
222        LogManager::getSingleton().logMessage("Direct3D - Creating Z-Buffer");
223
224        // First check we NEED a depth buffer - e.g. PowerVR doesn't need one
225        if (mNeedsZBuffer)
226        {
227            // Get description from source surface
228            ZeroMemory(&src_ddsd, sizeof(DDSURFACEDESC2));
229            src_ddsd.dwSize = sizeof(DDSURFACEDESC2);
230            renderTarget->GetSurfaceDesc(&src_ddsd);
231
232            // Enumerate Depth Buffers
233            mDepthBufferFormats.clear();
234            lpD3D->EnumZBufferFormats(
235                                mD3DDeviceDesc.deviceGUID,
236                                EnumZBuffersCallback,
237                                (LPVOID)&mDepthBufferFormats );
238
239            // Choose the best one
240            // NB make sure Z buffer is the same depth as colour buffer (GeForce TnL problem)
241            // Also use best stencil if z depth is the same
242            bestDepth = 0;
243            bestStencil = 0;
244
245            std::vector<DDPIXELFORMAT>::iterator it, best_it;
246            for(
247                it = mDepthBufferFormats.begin();
248                it != mDepthBufferFormats.end();
249                ++it )
250            {
251                if( ( (*it).dwZBufferBitDepth > bestDepth || (*it).dwStencilBitDepth > bestStencil)
252                    &&
253                    (*it).dwZBufferBitDepth <= src_ddsd.ddpfPixelFormat.dwZBufferBitDepth )
254                {
255                    best_it = it;
256                    bestDepth = (*it).dwZBufferBitDepth;
257                    bestStencil = (*it).dwStencilBitDepth;
258                }
259            }
260
261            // Setup the surface desc for the z-buffer.
262            ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
263
264            ddsd.dwSize         = sizeof(DDSURFACEDESC2);
265            ddsd.dwFlags        = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
266
267            ddsd.dwWidth        = src_ddsd.dwWidth;
268            ddsd.dwHeight       = src_ddsd.dwHeight;
269
270            ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
271
272            memcpy( &ddsd.ddpfPixelFormat, &(*best_it), sizeof(DDPIXELFORMAT) );
273
274            // Software devices require system-memory depth buffers.
275            if( mIsHardwareAccelerated )
276                ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
277            else
278                ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
279
280            // Create the depth-buffer.
281            renderTarget->GetDDInterface( (VOID**)&lpDD7 );
282            lpDD7->Release();
283
284            if( FAILED( hr = lpDD7->CreateSurface( &ddsd, &lpZBuffer, NULL ) ) )
285                OGRE_EXCEPT(
286                    hr,
287                    "Error creating depth buffer",
288                    "D3DDevice::createDepthBuffer" );
289
290            if( FAILED( hr = renderTarget->AddAttachedSurface(lpZBuffer) ) )
291                OGRE_EXCEPT(
292                    hr,
293                    "Error attaching depth buffer to render target",
294                    "D3DDevice::createDepthBuffer" );
295
296            // Log stencil buffer depth
297            mStencilBufferDepth = ddsd.ddpfPixelFormat.dwStencilBitDepth;
298
299            StringUtil::StrStreamType str;
300            str << "Depth-Buffer created (" << ddsd.ddpfPixelFormat.dwZBufferBitDepth
301                << "-bit, " << mStencilBufferDepth << "-bit stencil)";
302            LogManager::getSingleton().logMessage(
303                LML_NORMAL, str.str());
304            if (mStencilBufferDepth == 0)
305            {
306                LogManager::getSingleton().logMessage("Warning: software stencilling "
307                    "in use, stencil operations will not be hardware accelerated.");
308            }
309        }
310    }
311
312    bool D3DDevice::CanMipmap(void) const
313    {
314        return (mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MIPNEAREST) > 0;
315    }
316
317    bool D3DDevice::CanBilinearFilter(void) const
318    {
319        return (mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR) > 0;
320    }
321
322    bool D3DDevice::CanTrilinearFilter(void) const
323    {
324        return (mD3DDeviceDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR) > 0;
325    }
326
327    unsigned int D3DDevice::RenderBitDepth(void) const
328    {
329
330        if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_32)
331            return 32;
332        else if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_24)
333            return 24;
334        else if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_16)
335            return 16;
336        else if (mD3DDeviceDesc.dwDeviceRenderBitDepth & DDBD_8)
337            return 8;
338        else
339            return 0;
340    }
341
342    unsigned int D3DDevice::ZBufferBitDepth(void) const
343    {
344        switch(mD3DDeviceDesc.dwDeviceZBufferBitDepth)
345        {
346        case DDBD_8:
347            return 8;
348        case DDBD_16:
349            return 16;
350        case DDBD_24:
351            return 24;
352        case DDBD_32:
353            return 32;
354        }
355
356        return 0;
357
358    }
359    bool D3DDevice::NeedsZBuffer(void) const
360    {
361        return mNeedsZBuffer;
362    }
363
364    bool D3DDevice::CanHWTransformAndLight(void) const
365    {
366        return (mD3DDeviceDesc.dwDevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) > 0;
367    }
368
369    unsigned int D3DDevice::MaxSinglePassTextureLayers(void) const
370    {
371        // The maximum number of texture layers the device can support in a singe pass
372
373        return mD3DDeviceDesc.wMaxSimultaneousTextures;
374    }
375
376    ushort D3DDevice::StencilBufferBitDepth(void) const
377    {
378        return mStencilBufferDepth;
379    }
380
381
382} // Namespace
Note: See TracBrowser for help on using the repository browser.