source: OGRE/trunk/ogrenew/RenderSystems/Direct3D7/src/OgreD3D7HardwarePixelBuffer.cpp @ 657

Revision 657, 9.3 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

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 "OgreD3D7Texture.h"
26#include "OgreException.h"
27#include "OgreImage.h"
28#include "OgreLogManager.h"
29#include "OgreHardwarePixelBuffer.h"
30#include "OgreRoot.h"
31#include "OgreD3D7HardwarePixelBuffer.h"
32
33namespace Ogre {
34//----------------------------------------------------------------------------- 
35
36D3D7HardwarePixelBuffer::D3D7HardwarePixelBuffer(HardwareBuffer::Usage usage, IDirect3DDevice7 *device):
37        HardwarePixelBuffer(0, 0, 0, PF_UNKNOWN, usage, false, false),
38        mD3DDevice(device), mSurface(0),
39        mDoMipmapGen(0)
40{
41}
42D3D7HardwarePixelBuffer::~D3D7HardwarePixelBuffer()
43{
44}
45//----------------------------------------------------------------------------- 
46void D3D7HardwarePixelBuffer::bind(LPDIRECTDRAWSURFACE7 surface, PixelFormat format)
47{
48        mSurface = surface;
49        DDSURFACEDESC2 desc;
50        desc.dwSize = sizeof(DDSURFACEDESC2);
51        if(surface->GetSurfaceDesc(&desc) != D3D_OK)
52                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information",
53                 "D3D7HardwarePixelBuffer::D3D7HardwarePixelBuffer");
54        mWidth = desc.dwWidth;
55        mHeight = desc.dwHeight;
56        assert((desc.lPitch%PixelUtil::getNumElemBytes(format))==0);
57        mRowPitch = desc.lPitch/PixelUtil::getNumElemBytes(format);
58        mDepth = 1;
59        mFormat = format;
60
61        // Calculate pitch and size
62        mSlicePitch = mRowPitch*mHeight;
63        mSizeInBytes = mRowPitch*mHeight*PixelUtil::getNumElemBytes(format);
64
65        //std::stringstream str;
66        //str << "bind" << " " << surface << " " << mWidth << " " << mHeight << " " << mFormat << " " << mRowPitch;
67    //LogManager::getSingleton().logMessage(str.str());
68}
69//----------------------------------------------------------------------------- 
70PixelBox D3D7HardwarePixelBuffer::lockImpl(const Image::Box lockBox,  LockOptions options)
71{
72        assert(lockBox.getDepth() == 1);
73        // Set extents and format
74        PixelBox rval(lockBox, mFormat);
75
76        // Set locking flags according to options
77        DWORD flags = DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT;
78        switch(options)
79        {
80        case HBL_DISCARD:
81                flags |= DDLOCK_WRITEONLY;
82                break;
83        case HBL_READ_ONLY:
84                flags |= DDLOCK_READONLY;
85                break;
86        default:
87                break;
88        };
89       
90        DDSURFACEDESC2 lrect; // Filled in by D3D
91        HRESULT hr;
92
93        if (lockBox.left == 0 && lockBox.top == 0
94                && lockBox.right == mWidth && lockBox.bottom == mHeight)
95       
96        {
97                // Lock whole surface
98                mpRect = NULL;
99        }
100        else
101        {
102                mLockRect.left = lockBox.left;
103                mLockRect.right = lockBox.right;
104                mLockRect.top = lockBox.top;
105                mLockRect.bottom = lockBox.bottom;
106                mpRect = &mLockRect;
107        }
108        hr = mSurface->Lock(mpRect, &lrect, flags, NULL);
109        if (FAILED(hr))         
110                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Surface locking failed",
111                        "D3D7HardwarePixelBuffer::lockImpl");
112       
113        rval.rowPitch = mRowPitch;
114        rval.slicePitch = mSlicePitch;
115        rval.data = lrect.lpSurface;
116        return rval;
117}
118//----------------------------------------------------------------------------- 
119void D3D7HardwarePixelBuffer::unlockImpl(void)
120{
121        HRESULT hr;     
122        // Crazy DX7 convention: Unlock needs the same rect pointer that Lock got
123        hr = mSurface->Unlock(mpRect); 
124        if( FAILED( hr ) )
125        OGRE_EXCEPT( hr, "Error during Unlock operation.", "D3D7HardwarePixelBuffer::unlockImpl" );
126
127        if(mDoMipmapGen)
128        {
129                // Update mipmaps
130                _genMipmaps(mLockRect);
131        }
132}
133//----------------------------------------------------------------------------- 
134void D3D7HardwarePixelBuffer::blit(HardwarePixelBuffer *src, const Image::Box &srcBox, const Image::Box &dstBox)
135{
136        // TODO
137        // D3DXLoadTextureFromSurface
138        HardwarePixelBuffer::blit(src, srcBox, dstBox);
139}
140//----------------------------------------------------------------------------- 
141void D3D7HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox)
142{
143        /* No 3D textures support in D3D7 */
144        assert(src.getDepth() == 1);
145        assert(dstBox.getDepth() == 1);
146
147        /* We need a temporary surface in which to load the image data. */
148    LPDIRECTDRAWSURFACE7 pddsTempSurface;
149    HRESULT hr;
150    D3DX_SURFACEFORMAT surfFmt, texFmt;
151        MemoryDataStreamPtr buf;
152        PixelBox converted;
153
154    /* Compute the pixel format for the image. */
155        if(src.format != mFormat)
156        {
157                /* Format is not directly supported, or the pixelbox is not consecutive; conversion is needed */
158                PixelFormat tempFormat = mFormat;
159                buf.bind(new MemoryDataStream(
160                        PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(),
161                                                                                tempFormat)));
162                converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), tempFormat, buf->getPtr());
163                PixelUtil::bulkPixelConversion(src, converted);
164        }
165        else
166        {
167                converted = src;
168        }
169        surfFmt = D3DTexture::OgreFormat_to_D3DXFormat(mFormat);
170       
171    /* Compute the current pixel format of the texture. */
172        texFmt = D3DTexture::OgreFormat_to_D3DXFormat(mFormat);
173       
174    /* We generate the mip-maps by hand. */
175    DWORD mipFlag, numMips;
176    mipFlag = D3DX_TEXTURE_NOMIPMAP;
177
178    /* Set the width and height. */
179    DWORD dwWidth = src.getWidth(), dwHeight = src.getHeight();
180
181    /* Create the temporary surface. */
182    if( FAILED( hr = D3DXCreateTexture(
183        mD3DDevice,
184        NULL,
185        &dwWidth,
186        &dwHeight,
187        &texFmt,
188        NULL,
189        &pddsTempSurface,
190        &numMips ) ) )
191    {
192        OGRE_EXCEPT( hr, "Error during blit operation.", "D3D7HardwarePixelBuffer::blitFromMemory" );
193    }
194
195    /* Load the image into the temporary surface. */
196    if( FAILED( hr = D3DXLoadTextureFromMemory(
197        mD3DDevice,
198        pddsTempSurface,
199        D3DX_DEFAULT,
200        converted.data,
201        NULL,
202        surfFmt,
203                converted.rowPitch * PixelUtil::getNumElemBytes(converted.format),
204        NULL,
205        D3DX_FT_LINEAR ) ) )
206    {
207        pddsTempSurface->Release();
208        OGRE_EXCEPT( hr, "Error during D3DXLoadTextureFromMemory operation.", "D3D7HardwarePixelBuffer::blitFromMemory" );
209    }
210       
211        RECT texRect;
212        texRect.top = dstBox.top;
213        texRect.bottom = dstBox.bottom;
214        texRect.left = dstBox.left;
215        texRect.right = dstBox.right;
216
217    if( FAILED( hr = mSurface->Blt(
218        &texRect,
219        pddsTempSurface,
220        NULL,
221        DDBLT_WAIT,
222        NULL ) ) )
223    {
224        pddsTempSurface->Release();
225        OGRE_EXCEPT( hr, "Error during blit operation.", "D3DTexture::blitImage" );
226    }
227
228    /* Release the temporary surface. */
229    pddsTempSurface->Release();
230
231        if(mDoMipmapGen)
232                _genMipmaps(texRect);
233        OgreUnguard();
234}
235//----------------------------------------------------------------------------- 
236void D3D7HardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst)
237{
238        OGRE_EXCEPT(Exception::UNIMPLEMENTED_FEATURE,
239                                "Function not yet implemented",
240                                "D3D7HardwarePixelBuffer::blitToMemory");
241}
242//----------------------------------------------------------------------------- 
243void D3D7HardwarePixelBuffer::_setMipmapping(bool doMipmapGen)
244{
245        mDoMipmapGen = doMipmapGen;
246}
247//----------------------------------------------------------------------------- 
248void D3D7HardwarePixelBuffer::_genMipmaps(const RECT &texRect)
249{
250        /* Load the image in all the mip-maps (if there are any, that is). */
251        LPDIRECTDRAWSURFACE7 ddsMipLevel, ddsNextLevel;
252        DDSCAPS2 ddsCaps;
253        HRESULT mipRes = DD_OK;
254        uint mipLevel = 1;
255
256        ZeroMemory(&ddsCaps, sizeof(DDSCAPS2));
257        ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
258
259        /* Get the base level and increae the reference count. */
260        ddsMipLevel = mSurface;
261        ddsMipLevel->AddRef();
262       
263        /* While we can get a next level in the mip-map chain. */
264        while( ddsMipLevel->GetAttachedSurface( &ddsCaps, &ddsNextLevel ) == DD_OK )
265        {
266                /* Calculate the destination rect. */
267                RECT mipRect = {
268                        texRect.left >> mipLevel,
269                        texRect.top  >> mipLevel,
270                        texRect.right >> mipLevel,
271                        texRect.bottom >> mipLevel
272                };
273
274                /* Blit using D3DX in order to use bilinear filtering. */
275                D3DXLoadTextureFromSurface(
276                        mD3DDevice,
277                        ddsNextLevel,
278                        0,
279                        mSurface,
280                        (RECT*)&texRect,
281                        (RECT*)&mipRect,
282                        D3DX_FT_LINEAR );
283               
284                /* Release the current level and get the next one, incrementing the mip depth. */
285                ddsMipLevel->Release();
286                ddsMipLevel = ddsNextLevel;
287                mipLevel++;
288        }
289
290        /* Release the last mip-map level surface. */
291        ddsMipLevel->Release();
292}
293
294
295};
Note: See TracBrowser for help on using the repository browser.