source: OGRE/trunk/ogrenew/RenderSystems/GL/src/OgreGLHardwareVertexBuffer.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 "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( 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(GL_ARRAY_BUFFER_ARB, mBufferId);
47
48        // Initialise mapped buffer and set usage
49        glBufferDataARB(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(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(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(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
79            //    GLHardwareBufferManager::getGLUsage(mUsage));
80
81            access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
82                GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
83
84        }
85        else if(options == HBL_READ_ONLY)
86        {
87            if(mUsage == HBU_WRITE_ONLY)
88            {
89                LogManager::getSingleton().logMessage(
90                    "GLHardwareVertexBuffer: Locking a write-only vertex "
91                    "buffer for reading, performance warning.");
92            }
93            access = GL_READ_ONLY_ARB;
94        }
95        else if(options == HBL_NORMAL || options == HBL_NO_OVERWRITE)
96        {
97            // TODO: we should be using the below implementation, but nVidia cards
98            // choke on it and perform terribly - for investigation with nVidia
99            //access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
100            //    GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
101            access = GL_READ_WRITE;
102        }
103        else
104        {
105            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
106                "Invalid locking option set", "GLHardwareVertexBuffer::lock");
107        }
108
109        void* pBuffer = glMapBufferARB( GL_ARRAY_BUFFER_ARB, access);
110
111        if(pBuffer == 0)
112        {
113            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
114                "Vertex Buffer: Out of memory", "GLHardwareVertexBuffer::lock");
115        }
116
117        mIsLocked = true;
118        // return offsetted
119        return static_cast<void*>(
120            static_cast<unsigned char*>(pBuffer) + offset);
121    }
122        //---------------------------------------------------------------------
123        void GLHardwareVertexBuffer::unlockImpl(void)
124    {
125        glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId);
126
127        if(!glUnmapBufferARB( GL_ARRAY_BUFFER_ARB ))
128        {
129            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
130                "Buffer data corrupted, please reload",
131                "GLHardwareVertexBuffer::unlock");
132        }
133
134        mIsLocked = false;
135    }
136        //---------------------------------------------------------------------
137    void GLHardwareVertexBuffer::readData(size_t offset, size_t length,
138        void* pDest)
139    {
140        if(mUseShadowBuffer)
141        {
142            // get data from the shadow buffer
143            void* srcData = mpShadowBuffer->lock(offset, length, HBL_READ_ONLY);
144            memcpy(pDest, srcData, length);
145            mpShadowBuffer->unlock();
146        }
147        else
148        {
149            // get data from the real buffer
150            glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId);
151       
152            glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, pDest);
153        }
154    }
155        //---------------------------------------------------------------------
156    void GLHardwareVertexBuffer::writeData(size_t offset, size_t length,
157            const void* pSource, bool discardWholeBuffer)
158    {
159        glBindBufferARB(GL_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(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
173                GLHardwareBufferManager::getGLUsage(mUsage));
174        }
175
176        // Now update the real buffer
177        glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, pSource);
178    }
179        //---------------------------------------------------------------------
180
181}
Note: See TracBrowser for help on using the repository browser.