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

Revision 657, 7.1 KB checked in by mattausch, 19 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 "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_ptr( 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_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId);
46
47        // Initialise buffer and set usage
48        glBufferDataARB_ptr(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_ptr(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_ptr( 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_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
78            //    GLHardwareBufferManager::getGLUsage(mUsage));
79
80            // TODO: we should be using the below implementation, but nVidia cards
81            // choke on it and perform terribly - for investigation with nVidia
82            access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
83                GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
84            //access = GL_READ_WRITE;
85        }
86        else if(options == HBL_READ_ONLY)
87        {
88            if(mUsage == HBU_WRITE_ONLY)
89            {
90                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
91                    "Invalid attempt to lock a write-only index buffer as read-only",
92                    "GLHardwareIndexBuffer::lock");
93            }
94            access = GL_READ_ONLY_ARB;
95        }
96        else if(options == HBL_NORMAL || options == HBL_NO_OVERWRITE)
97        {
98            // TODO: we should be using the below implementation, but nVidia cards
99            // choke on it and perform terribly - for investigation with nVidia
100            access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
101                GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
102            //access = GL_READ_WRITE;
103        }
104        else
105        {
106            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
107                "Invalid locking option set", "GLHardwareIndexBuffer::lock");
108        }
109
110        void* pBuffer = glMapBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, access );
111
112        if(pBuffer == 0)
113        {
114            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
115                "Index Buffer: Out of memory",
116                "GLHardwareIndexBuffer::lock");
117        }
118
119        mIsLocked = true;
120        // return offsetted
121        return static_cast<void*>(
122            static_cast<unsigned char*>(pBuffer) + offset);
123    }
124        //---------------------------------------------------------------------
125        void GLHardwareIndexBuffer::unlockImpl(void)
126    {
127        glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
128
129        if(!glUnmapBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB ))
130        {
131            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
132                "Buffer data corrupted, please reload",
133                "GLHardwareIndexBuffer::unlock");
134        }
135
136        mIsLocked = false;
137    }
138        //---------------------------------------------------------------------
139    void GLHardwareIndexBuffer::readData(size_t offset, size_t length,
140        void* pDest)
141    {
142        if(mUseShadowBuffer)
143        {
144            // get data from the shadow buffer
145            void* srcData = mpShadowBuffer->lock(offset, length, HBL_READ_ONLY);
146            memcpy(pDest, srcData, length);
147            mpShadowBuffer->unlock();
148        }
149        else
150        {
151            glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
152            glGetBufferSubDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pDest);
153        }
154    }
155        //---------------------------------------------------------------------
156    void GLHardwareIndexBuffer::writeData(size_t offset, size_t length,
157            const void* pSource, bool discardWholeBuffer)
158    {
159        glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
160
161        // Update the shadow buffer
162        if(mUseShadowBuffer)
163        {
164            void* destData = mpShadowBuffer->lock(offset, length,
165                discardWholeBuffer ? HBL_DISCARD : HBL_NORMAL);
166            memcpy(destData, pSource, length);
167            mpShadowBuffer->unlock();
168        }
169
170        if(discardWholeBuffer)
171        {
172            glBufferDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
173                GLHardwareBufferManager::getGLUsage(mUsage));
174        }
175
176        // Now update the real buffer
177        glBufferSubDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pSource);
178    }
179        //---------------------------------------------------------------------
180}
Note: See TracBrowser for help on using the repository browser.