1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4     (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 
29 #include "OgreRoot.h"
30 #include "OgreLogManager.h"
31 #include "OgreRenderSystem.h"
32 #include "OgreImageCodec.h"
33 #include "OgreException.h"
34 #include "OgreStringConverter.h"
35 #include "OgreWin32RenderTexture.h"
36 #include "OgreWin32GLSupport.h"
37 #include "OgreWin32Context.h"
38 
39 namespace Ogre {
40 
Win32PBuffer(PixelComponentType format,size_t width,size_t height)41      Win32PBuffer::Win32PBuffer(PixelComponentType format, size_t width, size_t height):
42         GLPBuffer(format, width, height),
43         mContext(0)
44     {
45         createPBuffer();
46 
47         // Create context
48         mContext = new Win32Context(mHDC, mGlrc);
49 #if 0
50         if(mUseBind)
51         {
52             // Bind texture
53             glBindTextureEXT(GL_TEXTURE_2D, static_cast<GLTexture*>(mTexture.get())->getGLID());
54             wglBindTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB);
55         }
56 #endif
57     }
~Win32PBuffer()58      Win32PBuffer::~Win32PBuffer()
59     {
60 #if 0
61         if(mUseBind)
62         {
63             // Unbind texture
64             glBindTextureEXT(GL_TEXTURE_2D,
65                 static_cast<GLTexture*>(mTexture.get())->getGLID());
66             glBindTextureEXT(GL_TEXTURE_2D,
67                 static_cast<GLTexture*>(mTexture.get())->getGLID());
68             wglReleaseTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB);
69         }
70 #endif
71         // Unregister and destroy mContext
72         delete mContext;
73 
74         // Destroy pbuffer
75         destroyPBuffer();
76     }
77 
createPBuffer()78     void Win32PBuffer::createPBuffer()
79     {
80 
81         // Process format
82         int bits=0;
83         bool isFloat=false;
84 #if 0
85         bool hasAlpha=true;
86 #endif
87         switch(mFormat)
88         {
89             case PCT_BYTE:
90                 bits=8; isFloat=false;
91                 break;
92             case PCT_SHORT:
93                 bits=16; isFloat=false;
94                 break;
95             case PCT_FLOAT16:
96                 bits=16; isFloat=true;
97                 break;
98             case PCT_FLOAT32:
99                 bits=32; isFloat=true;
100                 break;
101             default: break;
102         };
103         LogManager::getSingleton().logMessage(
104             " Win32PBuffer::Creating PBuffer of format bits="+
105             StringConverter::toString(bits)+
106             " float="+StringConverter::toString(isFloat)
107         );
108 
109 
110         HDC old_hdc = wglGetCurrentDC();
111         HGLRC old_context = wglGetCurrentContext();
112 
113         // Bind to RGB or RGBA texture
114         int bttype = 0;
115 #if 0
116         if(mUseBind)
117         {
118             // Only provide bind type when actually binding
119             bttype = PixelUtil::hasAlpha(mInternalFormat)?
120                 WGL_BIND_TO_TEXTURE_RGBA_ARB : WGL_BIND_TO_TEXTURE_RGB_ARB;
121         }
122         int texformat = hasAlpha?
123             WGL_TEXTURE_RGBA_ARB : WGL_TEXTURE_RGB_ARB;
124 #endif
125         // Make a float buffer?
126         int pixeltype = isFloat?
127             WGL_TYPE_RGBA_FLOAT_ARB: WGL_TYPE_RGBA_ARB;
128 
129         int attrib[] = {
130             WGL_RED_BITS_ARB,bits,
131             WGL_GREEN_BITS_ARB,bits,
132             WGL_BLUE_BITS_ARB,bits,
133             WGL_ALPHA_BITS_ARB,bits,
134             WGL_STENCIL_BITS_ARB,1,
135             WGL_DEPTH_BITS_ARB,15,
136             WGL_DRAW_TO_PBUFFER_ARB,true,
137             WGL_SUPPORT_OPENGL_ARB,true,
138             WGL_PIXEL_TYPE_ARB,pixeltype,
139             //WGL_DOUBLE_BUFFER_ARB,true,
140             //WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, // Make sure it is accelerated
141             bttype,true, // must be last, as bttype can be zero
142             0
143         };
144         int pattrib_default[] = {
145             0
146         };
147 #if 0
148         int pattrib_bind[] = {
149             WGL_TEXTURE_FORMAT_ARB, texformat,
150             WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB,
151             WGL_PBUFFER_LARGEST_ARB, true,
152             0
153         };
154 #endif
155         int format;
156         unsigned int count;
157 
158         PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
159 
160         // Choose suitable pixel format
161         wglChoosePixelFormatARB(old_hdc,attrib,NULL,1,&format,&count);
162         if(count == 0)
163             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglChoosePixelFormatARB() failed", " Win32PBuffer::createPBuffer");
164 
165         // Analyse pixel format
166         const int piAttributes[]={
167                 WGL_RED_BITS_ARB,WGL_GREEN_BITS_ARB,WGL_BLUE_BITS_ARB,WGL_ALPHA_BITS_ARB,
168                 WGL_DEPTH_BITS_ARB,WGL_STENCIL_BITS_ARB
169         };
170         int piValues[sizeof(piAttributes)/sizeof(const int)];
171 
172         PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribiv = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
173         wglGetPixelFormatAttribiv(old_hdc,format,0,sizeof(piAttributes)/sizeof(const int),piAttributes,piValues);
174 
175         LogManager::getSingleton().stream()
176             << " Win32PBuffer::PBuffer -- Chosen pixel format rgba="
177             << piValues[0] << ","
178             << piValues[1] << ","
179             << piValues[2] << ","
180             << piValues[3]
181             << " depth=" << piValues[4]
182             << " stencil=" << piValues[5];
183         // FIXME lookup procaddress
184         mPBuffer = 0;//wglCreatePbufferARB(old_hdc,format,mWidth,mHeight,pattrib_default);
185         if(!mPBuffer)
186             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreatePbufferARB() failed", " Win32PBuffer::createPBuffer");
187 #if 0
188         mHDC = wglGetPbufferDCARB(mPBuffer);
189         if(!mHDC) {
190             wglDestroyPbufferARB(mPBuffer);
191             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglGetPbufferDCARB() failed", " Win32PBuffer::createPBuffer");
192         }
193 
194         mGlrc = wglCreateContext(mHDC);
195         if(!mGlrc) {
196             wglReleasePbufferDCARB(mPBuffer,mHDC);
197             wglDestroyPbufferARB(mPBuffer);
198             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreateContext() failed", " Win32PBuffer::createPBuffer");
199         }
200 
201         if(!wglShareLists(old_context,mGlrc)) {
202             wglDeleteContext(mGlrc);
203             wglReleasePbufferDCARB(mPBuffer,mHDC);
204             wglDestroyPbufferARB(mPBuffer);
205             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32PBuffer::createPBuffer");
206         }
207 
208         // Query real width and height
209         int iWidth, iHeight;
210         wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_WIDTH_ARB, &iWidth);
211         wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &iHeight);
212         mWidth = iWidth;
213         mHeight = iHeight;
214         LogManager::getSingleton().stream()
215             << "Win32RenderTexture::PBuffer created -- Real dimensions "
216             << mWidth << "x" << mHeight;
217 #endif
218     }
destroyPBuffer()219     void Win32PBuffer::destroyPBuffer()
220     {
221         wglDeleteContext(mGlrc);
222         // FIXME lookup procaddress
223 #if 0
224         wglReleasePbufferDCARB(mPBuffer,mHDC);
225         wglDestroyPbufferARB(mPBuffer);
226 #endif
227     }
228 
229 
230 }
231