00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027 #include <iostream>
00028 #include <sstream>
00029
00030 #include "ShError.hpp"
00031 #include "ShEnvironment.hpp"
00032 #include "WGLPBufferStreams.hpp"
00033
00034 namespace shgl {
00035
00036 using namespace SH;
00037
00038 class WGLPBufferStreamException: public ShException
00039 {
00040 public:
00041 WGLPBufferStreamException(const std::string& message) :
00042 ShException("WGL PBuffer Stream Execution: " + message)
00043 {
00044 }
00045 };
00046
00047 WGLPBufferStreams::WGLPBufferStreams(void) :
00048 m_orig_hdc(NULL),
00049 m_orig_hglrc(NULL)
00050 {
00051 }
00052
00053 WGLPBufferStreams::~WGLPBufferStreams()
00054 {
00055 }
00056
00057 StreamStrategy* WGLPBufferStreams::create(void)
00058 {
00059 return new WGLPBufferStreams;
00060 }
00061
00062 FloatExtension WGLPBufferStreams::setupContext(int width, int height)
00063 {
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 bool delete_dc = false;
00077 m_orig_hdc = wglGetCurrentDC();
00078 if (m_orig_hdc == NULL)
00079 {
00080 delete_dc = true;
00081 m_orig_hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
00082 if (m_orig_hdc == NULL)
00083 {
00084 std::stringstream msg;
00085 msg << "CreateDC failed (" << GetLastError() << ")";
00086 shError(WGLPBufferStreamException(msg.str()));
00087 }
00088 }
00089 else
00090 {
00091 m_orig_hglrc = wglGetCurrentContext();
00092 }
00093
00094
00095 ShWGLPBufferInfo match;
00096 for(std::list<ShWGLPBufferInfo>::iterator itr = m_infos.begin();
00097 itr != m_infos.end();
00098 itr++)
00099 {
00100 if ((*itr).valid() && (*itr).width == width && (*itr).height == height)
00101 {
00102 match = (*itr);
00103 break;
00104 }
00105 }
00106
00107
00108
00109 if (!match.valid())
00110 {
00111 match = createContext(width, height);
00112 m_infos.push_back(match);
00113 }
00114
00115
00116 if (!wglMakeCurrent(match.pbuffer_hdc, match.pbuffer_hglrc))
00117 {
00118 wglReleasePbufferDCARB(match.pbuffer, match.pbuffer_hdc);
00119 wglDestroyPbufferARB(match.pbuffer);
00120 wglDeleteContext(match.pbuffer_hglrc);
00121
00122 match.pbuffer = NULL;
00123 match.pbuffer_hdc = NULL;
00124 match.pbuffer_hglrc = NULL;
00125
00126 std::stringstream msg;
00127 msg << "wglMakeCurrent failed (" << GetLastError() << ")";
00128 shError(WGLPBufferStreamException(msg.str()));
00129 }
00130
00131
00132
00133 if (delete_dc)
00134 {
00135 DeleteDC(m_orig_hdc);
00136 m_orig_hdc = NULL;
00137 }
00138
00139 return match.extension;
00140 }
00141
00142 void WGLPBufferStreams::restoreContext(void)
00143 {
00144 if (m_orig_hdc != NULL && m_orig_hglrc != NULL)
00145 {
00146 if (!wglMakeCurrent(m_orig_hdc, m_orig_hglrc))
00147 {
00148 std::stringstream msg;
00149 msg << "wglMakeCurrent failed (" << GetLastError() << ")";
00150 shError(WGLPBufferStreamException(msg.str()));
00151 }
00152 else
00153 {
00154 m_orig_hdc = NULL;
00155 m_orig_hglrc = NULL;
00156 }
00157 }
00158 }
00159
00160 ShWGLPBufferInfo WGLPBufferStreams::createContext(int width, int height)
00161 {
00162 ShWGLPBufferInfo ret;
00163 ret.width = width;
00164 ret.height = height;
00165
00166 int nfattribs = 0;
00167 int niattribs = 0;
00168
00169 std::vector<int> fb_base_attribs;
00170 fb_base_attribs.push_back(WGL_DOUBLE_BUFFER_ARB); fb_base_attribs.push_back(false);
00171 fb_base_attribs.push_back(WGL_RED_BITS_ARB); fb_base_attribs.push_back(32);
00172 fb_base_attribs.push_back(WGL_GREEN_BITS_ARB); fb_base_attribs.push_back(32);
00173 fb_base_attribs.push_back(WGL_BLUE_BITS_ARB); fb_base_attribs.push_back(32);
00174 fb_base_attribs.push_back(WGL_DRAW_TO_PBUFFER_ARB); fb_base_attribs.push_back(true);
00175 fb_base_attribs.push_back(WGL_SUPPORT_OPENGL_ARB); fb_base_attribs.push_back(true);
00176
00177 bool found_pixelformat = false;
00178 int format = 0;
00179
00180
00181 if (!found_pixelformat)
00182 {
00183 std::vector<int> fb_attribs(fb_base_attribs);
00184
00185 fb_attribs.push_back(WGL_PIXEL_TYPE_ARB); fb_attribs.push_back(WGL_TYPE_RGBA_ARB);
00186 fb_attribs.push_back(WGL_FLOAT_COMPONENTS_NV); fb_attribs.push_back(true);
00187 fb_attribs.push_back(0);
00188
00189 unsigned int nformats = 0;
00190 if (!wglChoosePixelFormatARB(m_orig_hdc, &fb_attribs[0], NULL, 1, &format, &nformats))
00191 {
00192 SH_DEBUG_WARN("wglChoosePixelFormatARB failed (" << GetLastError() << ")");
00193 }
00194
00195 if (nformats > 0)
00196 {
00197 found_pixelformat = true;
00198 ret.extension = SH_ARB_NV_FLOAT_BUFFER;
00199 }
00200 }
00201
00202
00203 if (!found_pixelformat)
00204 {
00205 std::vector<int> fb_attribs(fb_base_attribs);
00206
00207 fb_attribs.push_back(WGL_PIXEL_TYPE_ARB); fb_attribs.push_back(WGL_TYPE_RGBA_FLOAT_ATI);
00208 fb_attribs.push_back(0);
00209
00210 unsigned int nformats = 0;
00211 if (!wglChoosePixelFormatARB(m_orig_hdc, &fb_attribs[0], NULL, 1, &format, &nformats))
00212 {
00213 SH_DEBUG_WARN("wglChoosePixelFormatARB failed (" << GetLastError() << ")");
00214 }
00215
00216 if (nformats > 0)
00217 {
00218 found_pixelformat = true;
00219 ret.extension = SH_ARB_ATI_PIXEL_FORMAT_FLOAT;
00220 }
00221 }
00222
00223 if (!found_pixelformat)
00224 {
00225 shError(WGLPBufferStreamException("Could not find appropriate pixel format!"));
00226 }
00227
00228 if (ret.extension == SH_ARB_NO_FLOAT_EXT)
00229 {
00230 shError(WGLPBufferStreamException("Could not choose a floating-point extension!"));
00231 }
00232
00233
00234 int pbuffer_attribs[] = {
00235 WGL_PBUFFER_LARGEST_ARB, false,
00236 0
00237 };
00238
00239
00240
00241
00242
00243 int temp_width = std::max(ret.width, 8);
00244 int temp_height = std::max(ret.height, 8);
00245
00246 ret.pbuffer = wglCreatePbufferARB(m_orig_hdc, format, temp_width, temp_height, pbuffer_attribs);
00247 if (ret.pbuffer == NULL)
00248 {
00249 std::stringstream msg;
00250 msg << "wglCreatePbufferARB failed (" << GetLastError() << ")";
00251 shError(WGLPBufferStreamException(msg.str()));
00252 }
00253
00254 ret.pbuffer_hdc = wglGetPbufferDCARB(ret.pbuffer);
00255 if (ret.pbuffer_hdc == NULL)
00256 {
00257 wglDestroyPbufferARB(ret.pbuffer);
00258
00259 ret.pbuffer = NULL;
00260
00261 std::stringstream msg;
00262 msg << "wglGetPbufferDCARB failed (" << GetLastError() << ")";
00263 shError(WGLPBufferStreamException(msg.str()));
00264 }
00265
00266
00267 ret.pbuffer_hglrc = wglCreateContext(ret.pbuffer_hdc);
00268 if (ret.pbuffer_hglrc == NULL)
00269 {
00270 wglReleasePbufferDCARB(ret.pbuffer, ret.pbuffer_hdc);
00271 wglDestroyPbufferARB(ret.pbuffer);
00272
00273 ret.pbuffer = NULL;
00274 ret.pbuffer_hdc = NULL;
00275
00276 std::stringstream msg;
00277 msg << "wglCreateContext failed (" << GetLastError() << ")";
00278 shError(WGLPBufferStreamException(msg.str()));
00279 }
00280
00281 return ret;
00282 }
00283
00284 }