Line data Source code
1 :
2 : /* Copyright (c) 2005-2014, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2012-2014, Daniel Nachbaur <danielnachbaur@gmail.com>
4 : * 2009, Makhinya Maxim
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "glWindow.h"
21 :
22 : #include "error.h"
23 : #include "gl.h"
24 : #include "global.h"
25 : #include "pipe.h"
26 :
27 : #include <eq/fabric/drawableConfig.h>
28 : #include <eq/util/frameBufferObject.h>
29 : #include <lunchbox/os.h>
30 : #include <lunchbox/perThread.h>
31 :
32 : template
33 : void lunchbox::perThreadNoDelete< const eq::GLWindow >( const eq::GLWindow* );
34 :
35 : namespace eq
36 : {
37 : namespace
38 : {
39 12 : lunchbox::PerThread< const GLWindow, lunchbox::perThreadNoDelete > _current;
40 : }
41 : namespace detail
42 : {
43 : class GLWindow
44 : {
45 : public:
46 17 : GLWindow()
47 : : glewInitialized( false )
48 17 : , fbo( 0 )
49 : {
50 17 : lunchbox::setZero( &glewContext, sizeof( GLEWContext ));
51 17 : }
52 :
53 17 : ~GLWindow()
54 : {
55 17 : glewInitialized = false;
56 : #ifndef NDEBUG
57 17 : lunchbox::setZero( &glewContext, sizeof( GLEWContext ));
58 : #endif
59 17 : }
60 :
61 : bool glewInitialized ;
62 :
63 : /** Extended OpenGL function entries when window has a context. */
64 : GLEWContext glewContext;
65 :
66 : /** Frame buffer object for FBO drawables. */
67 : util::FrameBufferObject* fbo;
68 : };
69 : }
70 :
71 17 : GLWindow::GLWindow( NotifierInterface& parent, const WindowSettings& settings )
72 : : SystemWindow( parent, settings )
73 17 : , _impl( new detail::GLWindow )
74 : {
75 17 : }
76 :
77 34 : GLWindow::~GLWindow()
78 : {
79 17 : if( _current == this )
80 17 : _current = 0;
81 17 : delete _impl;
82 17 : }
83 :
84 21 : void GLWindow::makeCurrent( const bool useCache ) const
85 : {
86 21 : if( useCache && _current == this )
87 21 : return;
88 :
89 21 : bindFrameBuffer();
90 21 : _current = this;
91 : }
92 :
93 71 : bool GLWindow::isCurrent() const
94 : {
95 71 : return _current == this;
96 : }
97 :
98 17 : void GLWindow::initGLEW()
99 : {
100 17 : if( _impl->glewInitialized )
101 17 : return;
102 :
103 17 : const GLenum result = glewInit();
104 17 : if( result != GLEW_OK )
105 0 : LBWARN << "GLEW initialization failed: " << std::endl;
106 : else
107 17 : _impl->glewInitialized = true;
108 : }
109 :
110 17 : void GLWindow::exitGLEW()
111 : {
112 17 : _impl->glewInitialized = false;
113 17 : }
114 :
115 17 : const util::FrameBufferObject* GLWindow::getFrameBufferObject() const
116 : {
117 17 : return _impl->fbo;
118 : }
119 :
120 56 : const GLEWContext* GLWindow::glewGetContext() const
121 : {
122 56 : return &_impl->glewContext;
123 : }
124 :
125 43 : GLEWContext* GLWindow::glewGetContext()
126 : {
127 43 : return &_impl->glewContext;
128 : }
129 :
130 13 : bool GLWindow::configInitFBO()
131 : {
132 39 : if( !_impl->glewInitialized ||
133 26 : !GLEW_ARB_texture_non_power_of_two || !GLEW_EXT_framebuffer_object )
134 : {
135 0 : sendError( ERROR_FBO_UNSUPPORTED );
136 0 : return false;
137 : }
138 :
139 : // needs glew initialized (see above)
140 13 : _impl->fbo = new util::FrameBufferObject( &_impl->glewContext );
141 :
142 13 : const PixelViewport& pvp = getPixelViewport();
143 13 : const GLuint colorFormat = getColorFormat();
144 :
145 13 : int depthSize = getIAttribute( WindowSettings::IATTR_PLANES_DEPTH );
146 13 : if( depthSize == AUTO )
147 13 : depthSize = 24;
148 :
149 13 : int stencilSize = getIAttribute( WindowSettings::IATTR_PLANES_STENCIL );
150 13 : if( stencilSize == AUTO )
151 7 : stencilSize = 1;
152 :
153 : Error error = _impl->fbo->init( pvp.w, pvp.h, colorFormat, depthSize,
154 13 : stencilSize );
155 13 : if( !error )
156 0 : return true;
157 :
158 13 : if( getIAttribute( WindowSettings::IATTR_PLANES_STENCIL ) == AUTO )
159 7 : error = _impl->fbo->init( pvp.w, pvp.h, colorFormat, depthSize, 0 );
160 :
161 13 : if( !error )
162 7 : return true;
163 :
164 6 : sendError( error );
165 6 : delete _impl->fbo;
166 6 : _impl->fbo = 0;
167 6 : return false;
168 : }
169 :
170 17 : void GLWindow::configExitFBO()
171 : {
172 17 : if( _impl->fbo )
173 7 : _impl->fbo->exit();
174 :
175 17 : delete _impl->fbo;
176 17 : _impl->fbo = 0;
177 17 : }
178 :
179 36 : void GLWindow::bindFrameBuffer() const
180 : {
181 36 : if( !_impl->glewInitialized )
182 53 : return;
183 :
184 19 : if( _impl->fbo )
185 8 : _impl->fbo->bind();
186 11 : else if( GLEW_EXT_framebuffer_object )
187 11 : glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
188 : }
189 :
190 7 : void GLWindow::flush()
191 : {
192 7 : glFlush();
193 7 : }
194 :
195 74 : void GLWindow::finish()
196 : {
197 74 : glFinish();
198 74 : }
199 :
200 15 : void GLWindow::queryDrawableConfig( DrawableConfig& drawableConfig )
201 : {
202 : // GL version
203 15 : const char* glVersion = (const char*)glGetString( GL_VERSION );
204 15 : if( !glVersion ) // most likely no context - fail
205 : {
206 0 : LBWARN << "glGetString(GL_VERSION) returned 0, assuming GL version 1.1"
207 0 : << std::endl;
208 0 : drawableConfig.glVersion = 1.1f;
209 : }
210 : else
211 15 : drawableConfig.glVersion = static_cast<float>( atof( glVersion ));
212 :
213 : // Framebuffer capabilities
214 : GLboolean result;
215 15 : glGetBooleanv( GL_STEREO, &result );
216 15 : drawableConfig.stereo = result;
217 :
218 15 : glGetBooleanv( GL_DOUBLEBUFFER, &result );
219 15 : drawableConfig.doublebuffered = result;
220 :
221 : GLint stencilBits;
222 15 : glGetIntegerv( GL_STENCIL_BITS, &stencilBits );
223 15 : drawableConfig.stencilBits = stencilBits;
224 :
225 : GLint colorBits;
226 15 : glGetIntegerv( GL_RED_BITS, &colorBits );
227 15 : drawableConfig.colorBits = colorBits;
228 :
229 : GLint alphaBits;
230 15 : glGetIntegerv( GL_ALPHA_BITS, &alphaBits );
231 15 : drawableConfig.alphaBits = alphaBits;
232 :
233 : GLint accumBits;
234 15 : glGetIntegerv( GL_ACCUM_RED_BITS, &accumBits );
235 15 : drawableConfig.accumBits = accumBits * 4;
236 :
237 15 : LBINFO << "Window drawable config: " << drawableConfig << std::endl;
238 15 : }
239 :
240 36 : }
|