Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/RenderSystems/GL/src/GLX/OgreGLXRenderTexture.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 8.6 KB
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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30
31#include "OgreException.h"
32#include "OgreLogManager.h"
33#include "OgreRoot.h"
34#include "OgreStringConverter.h"
35
36#include "OgreGLRenderSystem.h"
37
38#include "OgreGLXRenderTexture.h"
39#include "OgreGLXContext.h"
40#include "OgreGLXUtils.h"
41
42#include <iostream>
43
44/// ATI: GLX_ATI_pixel_format_float
45#ifndef GLX_RGBA_FLOAT_ATI_BIT
46#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100
47#endif
48
49/// ARB: GLX_ARB_fbconfig_float
50#ifndef GLX_RGBA_FLOAT_BIT
51#define GLX_RGBA_FLOAT_BIT 0x00000004
52#endif
53
54#ifndef GLX_RGBA_FLOAT_TYPE
55#define GLX_RGBA_FLOAT_TYPE 0x20B9
56#endif
57
58
59namespace Ogre
60{
61    GLXPBuffer::GLXPBuffer(PixelComponentType format, size_t width, size_t height):
62        GLPBuffer(format, width, height),
63        _hPBuffer(0),
64        mContext(0)
65    {
66        createPBuffer();
67        // Create context
68        mContext = new GLXContext(_pDpy, _hPBuffer, _hGLContext, mFBConfig);
69    }
70       
71    GLContext *GLXPBuffer::getContext()
72    {
73        return mContext;
74    }
75
76    void GLXPBuffer::createPBuffer() {       
77        //LogManager::getSingleton().logMessage(
78        //"GLXPBuffer::Creating PBuffer"
79        //);
80        _pDpy = glXGetCurrentDisplay();
81        ::GLXContext context = glXGetCurrentContext();
82        int screen = DefaultScreen(_pDpy);
83        int attribs[50], ideal[50];
84        int attrib;
85       
86        // Process format
87        int bits=0;
88        bool isFloat=false;
89        switch(mFormat)
90        {
91            case PCT_BYTE:
92                bits=8; isFloat=false;
93                break;
94            case PCT_SHORT:
95                bits=16; isFloat=false;
96                break;
97            case PCT_FLOAT16:
98                bits=16; isFloat=true;
99                break;
100            case PCT_FLOAT32:
101                bits=32; isFloat=true;
102                break;
103            default: break;
104        };
105        RTFType floatBuffer = RTF_NONE;
106        if(isFloat)
107        {
108            floatBuffer = detectRTFType();
109            if(floatBuffer == RTF_NONE || floatBuffer == RTF_NV)
110            {
111                OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Floating point PBuffers not supported on this hardware",  "GLRenderTexture::createPBuffer");
112            }
113        }
114
115        // Create base required format description
116        attrib = 0;
117        if (floatBuffer == RTF_ATI) {
118            attribs[attrib++] = GLX_RENDER_TYPE;
119            attribs[attrib++] = GLX_RGBA_FLOAT_ATI_BIT;
120        } 
121        else if (floatBuffer == RTF_ARB) 
122        {
123            attribs[attrib++] = GLX_RENDER_TYPE;
124            attribs[attrib++] = GLX_RGBA_FLOAT_BIT;
125        }
126        else
127        {
128            attribs[attrib++] = GLX_RENDER_TYPE;
129            attribs[attrib++] = GLX_RGBA_BIT;
130        }     
131        attribs[attrib++] = GLX_DRAWABLE_TYPE;
132        attribs[attrib++] = GLX_PBUFFER_BIT;
133        attribs[attrib++] = GLX_DOUBLEBUFFER;
134        attribs[attrib++] = 0;
135        /*
136        if (floatBuffer == RTF_NV) {
137                    attribs[attrib++] = GLX_FLOAT_COMPONENTS_NV;
138                    attribs[attrib++] = 1;
139            }
140        */
141        attribs[attrib++] = None;
142       
143        // Create "ideal" format description
144        attrib = 0;
145        ideal[attrib++] = GLX_RED_SIZE;
146        ideal[attrib++] = bits;       
147        ideal[attrib++] = GLX_GREEN_SIZE;
148        ideal[attrib++] = bits;
149        ideal[attrib++] = GLX_BLUE_SIZE;
150        ideal[attrib++] = bits;       
151        ideal[attrib++] = GLX_ALPHA_SIZE;
152        ideal[attrib++] = bits;
153        ideal[attrib++] = GLX_DEPTH_SIZE;
154        ideal[attrib++] = 24;
155        ideal[attrib++] = GLX_STENCIL_SIZE;
156        ideal[attrib++] = 8;
157        ideal[attrib++] = GLX_ACCUM_RED_SIZE;
158        ideal[attrib++] = 0;    // Accumulation buffer not used
159        ideal[attrib++] = GLX_ACCUM_GREEN_SIZE;
160        ideal[attrib++] = 0;    // Accumulation buffer not used
161        ideal[attrib++] = GLX_ACCUM_BLUE_SIZE;
162        ideal[attrib++] = 0;    // Accumulation buffer not used
163        ideal[attrib++] = GLX_ACCUM_ALPHA_SIZE;
164        ideal[attrib++] = 0;    // Accumulation buffer not used
165        ideal[attrib++] = None;
166
167        // Create vector of existing config data formats       
168        mFBConfig = GLXUtils::findBestMatch(_pDpy, screen, attribs, ideal);
169
170        // Create the pbuffer in the best matching format
171        attrib = 0;
172        attribs[attrib++] = GLX_PBUFFER_WIDTH;
173        attribs[attrib++] = mWidth; // Get from texture?
174        attribs[attrib++] = GLX_PBUFFER_HEIGHT;
175        attribs[attrib++] = mHeight; // Get from texture?
176        attribs[attrib++] = GLX_PRESERVED_CONTENTS;
177        attribs[attrib++] = 1;
178        attribs[attrib++] = None;
179
180        FBConfigData configData(_pDpy, mFBConfig);
181        LogManager::getSingleton().logMessage(
182                LML_NORMAL,
183                "GLXPBuffer::PBuffer chose format "+configData.toString());                   
184
185        _hPBuffer = glXCreatePbuffer(_pDpy, mFBConfig, attribs);
186        if (!_hPBuffer) 
187            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "glXCreatePbuffer() failed", "GLRenderTexture::createPBuffer");
188
189        _hGLContext = glXCreateNewContext(_pDpy, mFBConfig, GLX_RGBA_TYPE, context, True);
190        if (!_hGLContext) 
191            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "glXCreateContext() failed", "GLRenderTexture::createPBuffer");       
192
193        // Query real width and height
194        GLuint iWidth, iHeight;
195        glXQueryDrawable(_pDpy, _hPBuffer, GLX_WIDTH, &iWidth);
196        glXQueryDrawable(_pDpy, _hPBuffer, GLX_HEIGHT, &iHeight);
197
198        LogManager::getSingleton().logMessage(
199             LML_NORMAL,
200                "GLXPBuffer::PBuffer created -- Real dimensions "+
201                StringConverter::toString(iWidth)+"x"+StringConverter::toString(iHeight)+
202                ", number of bits is "+
203                StringConverter::toString(bits)+
204                ", floating point is "+
205                StringConverter::toString(isFloat)
206        );
207        mWidth = iWidth; 
208        mHeight = iHeight;
209    }
210
211    GLXPBuffer::~GLXPBuffer()
212    {
213        // Destroy and unregister context
214        delete mContext;
215        // Destroy GL context
216        glXDestroyContext(_pDpy, _hGLContext);
217        _hGLContext = 0;
218        glXDestroyPbuffer(_pDpy, _hPBuffer);
219        _hPBuffer = 0;
220        LogManager::getSingleton().logMessage(
221             LML_NORMAL,
222                "GLXPBuffer::PBuffer destroyed");
223    }
224   
225    GLXPBuffer::RTFType GLXPBuffer::detectRTFType()
226    {
227        RTFType floatBuffer = RTF_NONE;
228        /// Query supported float buffer extensions
229        /// Choose the best one
230        std::stringstream ext;
231        std::string instr;
232        ext << glXQueryExtensionsString(_pDpy, DefaultScreen(_pDpy)) << " " << glXGetClientString(_pDpy, GLX_EXTENSIONS);
233        while(ext >> instr)
234        {
235            if(instr == "GLX_NV_float_buffer" && floatBuffer<RTF_NV)
236                floatBuffer = RTF_NV;
237            if(instr == "GLX_ATI_pixel_format_float" && floatBuffer<RTF_ATI)
238                floatBuffer = RTF_ATI;
239            if(instr == "GLX_ARB_fbconfig_float" && floatBuffer<RTF_ARB)
240                floatBuffer = RTF_ARB;
241        }
242        return floatBuffer;
243    }
244 
245}
Note: See TracBrowser for help on using the repository browser.