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