source: OGRE/trunk/ogrenew/RenderSystems/GL/src/OgreGLHardwareIndexBuffer.cpp @ 692

Revision 692, 6.8 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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 "OgreGLHardwareIndexBuffer.h"
26#include "OgreGLHardwareBufferManager.h"
27#include "OgreException.h"
28
29namespace Ogre {
30
31        //---------------------------------------------------------------------
32    GLHardwareIndexBuffer::GLHardwareIndexBuffer(IndexType idxType,
33        size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer)
34        : HardwareIndexBuffer(idxType, numIndexes, usage, false, useShadowBuffer)
35    {
36        glGenBuffersARB( 1, &mBufferId );
37
38        if (!mBufferId)
39        {
40            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
41                "Cannot create GL index buffer",
42                "GLHardwareIndexBuffer::GLHardwareIndexBuffer");
43        }
44
45        glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId);
46
47        // Initialise buffer and set usage
48        glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
49            GLHardwareBufferManager::getGLUsage(usage));
50
51        //std::cerr << "creating index buffer " << mBufferId << std::endl;
52    }
53        //---------------------------------------------------------------------
54    GLHardwareIndexBuffer::~GLHardwareIndexBuffer()
55    {
56        glDeleteBuffersARB(1, &mBufferId);
57    }
58        //---------------------------------------------------------------------
59    void* GLHardwareIndexBuffer::lockImpl(size_t offset,
60        size_t length, LockOptions options)
61    {
62        GLenum access = 0;
63
64        if(mIsLocked)
65        {
66            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
67                "Invalid attempt to lock an index buffer that has already been locked",
68                    "GLHardwareIndexBuffer::lock");
69        }
70
71        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
72       
73        if(options == HBL_DISCARD)
74        {
75            //TODO: really we should use this to indicate our discard of the buffer
76            //However it makes no difference to fps on nVidia, and can crash some ATI
77            //glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
78            //    GLHardwareBufferManager::getGLUsage(mUsage));
79
80            access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
81                GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
82        }
83        else if(options == HBL_READ_ONLY)
84        {
85            if(mUsage == HBU_WRITE_ONLY)
86            {
87                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
88                    "Invalid attempt to lock a write-only index buffer as read-only",
89                    "GLHardwareIndexBuffer::lock");
90            }
91            access = GL_READ_ONLY_ARB;
92        }
93        else if(options == HBL_NORMAL || options == HBL_NO_OVERWRITE)
94        {
95            // TODO: we should be using the below implementation, but nVidia cards
96            // choke on it and perform terribly - for investigation with nVidia
97            access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
98                GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
99            //access = GL_READ_WRITE;
100        }
101        else
102        {
103            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
104                "Invalid locking option set", "GLHardwareIndexBuffer::lock");
105        }
106
107        void* pBuffer = glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, access );
108
109        if(pBuffer == 0)
110        {
111            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
112                "Index Buffer: Out of memory",
113                "GLHardwareIndexBuffer::lock");
114        }
115
116        mIsLocked = true;
117        // return offsetted
118        return static_cast<void*>(
119            static_cast<unsigned char*>(pBuffer) + offset);
120    }
121        //---------------------------------------------------------------------
122        void GLHardwareIndexBuffer::unlockImpl(void)
123    {
124        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
125
126        if(!glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB ))
127        {
128            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
129                "Buffer data corrupted, please reload",
130                "GLHardwareIndexBuffer::unlock");
131        }
132
133        mIsLocked = false;
134    }
135        //---------------------------------------------------------------------
136    void GLHardwareIndexBuffer::readData(size_t offset, size_t length,
137        void* pDest)
138    {
139        if(mUseShadowBuffer)
140        {
141            // get data from the shadow buffer
142            void* srcData = mpShadowBuffer->lock(offset, length, HBL_READ_ONLY);
143            memcpy(pDest, srcData, length);
144            mpShadowBuffer->unlock();
145        }
146        else
147        {
148            glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
149            glGetBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pDest);
150        }
151    }
152        //---------------------------------------------------------------------
153    void GLHardwareIndexBuffer::writeData(size_t offset, size_t length,
154            const void* pSource, bool discardWholeBuffer)
155    {
156        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
157
158        // Update the shadow buffer
159        if(mUseShadowBuffer)
160        {
161            void* destData = mpShadowBuffer->lock(offset, length,
162                discardWholeBuffer ? HBL_DISCARD : HBL_NORMAL);
163            memcpy(destData, pSource, length);
164            mpShadowBuffer->unlock();
165        }
166
167        if(discardWholeBuffer)
168        {
169            glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
170                GLHardwareBufferManager::getGLUsage(mUsage));
171        }
172
173        // Now update the real buffer
174        glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pSource);
175    }
176        //---------------------------------------------------------------------
177}
Note: See TracBrowser for help on using the repository browser.