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 "GlBackend.hpp"
00028 #include "ShDebug.hpp"
00029 #include "ShError.hpp"
00030
00031 #include <sstream>
00032
00033 #ifdef WIN32
00034
00035 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = 0;
00036 PFNGLBINDPROGRAMARBPROC glBindProgramARB = 0;
00037 PFNGLGENPROGRAMSARBPROC glGenProgramsARB = 0;
00038 PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = 0;
00039 PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = 0;
00040 PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = 0;
00041 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = 0;
00042
00043 PFNGLTEXIMAGE3DPROC glTexImage3D = 0;
00044 PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = 0;
00045
00046
00047 PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = 0;
00048 PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = 0;
00049 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = 0;
00050
00051
00052 PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = 0;
00053 PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = 0;
00054 PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = 0;
00055 PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = 0;
00056 PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = 0;
00057
00058 #endif
00059
00060 namespace shgl {
00061
00062 using namespace SH;
00063
00064 #ifdef WIN32
00065 LRESULT CALLBACK shGlWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00066 {
00067
00068
00069
00070
00071
00072 return DefWindowProc(hWnd, uMsg, wParam, lParam);
00073 }
00074 #endif
00075
00076 void shGlCheckError(const char* desc, const char* file, int line)
00077 {
00078 GLenum errnum = glGetError();
00079 char* error = 0;
00080 switch (errnum) {
00081 case GL_NO_ERROR:
00082 return;
00083 case GL_INVALID_ENUM:
00084 error = "GL_INVALID_ENUM";
00085 break;
00086 case GL_INVALID_VALUE:
00087 error = "GL_INVALID_VALUE";
00088 break;
00089 case GL_INVALID_OPERATION:
00090 error = "GL_INVALID_OPERATION";
00091 break;
00092 case GL_STACK_OVERFLOW:
00093 error = "GL_STACK_OVERFLOW";
00094 break;
00095 case GL_STACK_UNDERFLOW:
00096 error = "GL_STACK_UNDERFLOW";
00097 break;
00098 case GL_OUT_OF_MEMORY:
00099 error = "GL_OUT_OF_MEMORY";
00100 break;
00101 case GL_TABLE_TOO_LARGE:
00102 error = "GL_TABLE_TOO_LARGE";
00103 break;
00104 default:
00105 error = "Unknown error!";
00106 break;
00107 }
00108 SH_DEBUG_PRINT("GL ERROR on " << file << ": " <<line<<": "<< error);
00109 SH_DEBUG_PRINT("GL ERROR call: " << desc);
00110 }
00111
00112 #ifdef WIN32
00113 #define GET_WGL_PROCEDURE(x, T) \
00114 if ((x = reinterpret_cast<PFN ## T ## PROC>(wglGetProcAddress(#x))) == NULL) \
00115 { \
00116 std::stringstream msg; \
00117 msg << "wglGetProcAddress failed (" << GetLastError() << ")"; \
00118 shError(ShException(msg.str())); \
00119 }
00120 #endif
00121
00122 GlBackend::GlBackend(CodeStrategy* code, TextureStrategy* texture, StreamStrategy* stream) :
00123 m_code(code),
00124 m_texture(texture),
00125 m_stream(stream)
00126 {
00127
00128 #ifdef WIN32
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 HWND hWnd = NULL;
00154 HDC hdc = wglGetCurrentDC();
00155 HGLRC hglrc = wglGetCurrentContext();
00156 if (hdc == NULL && hglrc == NULL)
00157 {
00158 WNDCLASSEX wc;
00159 ZeroMemory(&wc, sizeof (WNDCLASSEX));
00160 wc.cbSize = sizeof(WNDCLASSEX);
00161 wc.style = 0;
00162 wc.lpfnWndProc = shGlWindowProc;
00163 wc.cbClsExtra = 0;
00164 wc.cbWndExtra = 0;
00165 wc.hInstance = NULL;
00166 wc.hIcon = NULL;
00167 wc.hCursor = NULL;
00168 wc.hbrBackground = NULL;
00169 wc.lpszMenuName = NULL;
00170 wc.lpszClassName = "shGlWindow";
00171 wc.hIconSm = NULL;
00172
00173 if (!RegisterClassEx(&wc))
00174 {
00175 std::stringstream msg;
00176 msg << "RegisterClassEx failed (" << GetLastError() << ")";
00177 shError(ShException(msg.str()));
00178 }
00179
00180 hWnd = CreateWindowEx(0, "shGlWindow", "shGlWindow", WS_POPUP,
00181 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
00182 NULL, NULL, NULL, NULL);
00183
00184 if (hWnd == NULL)
00185 {
00186 std::stringstream msg;
00187 msg << "CreateWindowEx failed (" << GetLastError() << ")";
00188 shError(ShException(msg.str()));
00189 }
00190
00191 hdc = GetDC(hWnd);
00192 if (hdc == NULL)
00193 {
00194 DestroyWindow(hWnd);
00195
00196 std::stringstream msg;
00197 msg << "GetDC failed (" << GetLastError() << ")";
00198 shError(ShException(msg.str()));
00199 }
00200
00201 PIXELFORMATDESCRIPTOR pfd;
00202 ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
00203 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00204 pfd.nVersion = 1;
00205 pfd.dwFlags = PFD_SUPPORT_OPENGL;
00206 pfd.iPixelType = PFD_TYPE_RGBA;
00207 pfd.iLayerType = PFD_MAIN_PLANE;
00208
00209 int pf = ChoosePixelFormat(hdc, &pfd);
00210 if (pf == 0)
00211 {
00212 std::stringstream msg;
00213 msg << "ChoosePixelFormat failed (" << GetLastError() << ")";
00214 shError(ShException(msg.str()));
00215 }
00216
00217 if (!SetPixelFormat(hdc, pf, &pfd))
00218 {
00219 std::stringstream msg;
00220 msg << "SetPixelFormat failed (" << GetLastError() << ")";
00221 shError(ShException(msg.str()));
00222 }
00223
00224 hglrc = wglCreateContext(hdc);
00225 if (hglrc == NULL)
00226 {
00227 ReleaseDC(hWnd, hdc);
00228 DestroyWindow(hWnd);
00229
00230 std::stringstream msg;
00231 msg << "wglCreateContext failed (" << GetLastError() << ")";
00232 shError(ShException(msg.str()));
00233 }
00234
00235 if (!wglMakeCurrent(hdc, hglrc))
00236 {
00237 wglDeleteContext(hglrc);
00238 ReleaseDC(hWnd, hdc);
00239 DestroyWindow(hWnd);
00240
00241 std::stringstream msg;
00242 msg << "wglMakeCurrent failed (" << GetLastError() << ")";
00243 shError(ShException(msg.str()));
00244 }
00245 }
00246 else
00247 {
00248 hdc = NULL;
00249 hglrc = NULL;
00250 }
00251
00252 GET_WGL_PROCEDURE(glProgramStringARB, GLPROGRAMSTRINGARB);
00253 GET_WGL_PROCEDURE(glBindProgramARB, GLBINDPROGRAMARB);
00254 GET_WGL_PROCEDURE(glGenProgramsARB, GLGENPROGRAMSARB);
00255 GET_WGL_PROCEDURE(glActiveTextureARB, GLACTIVETEXTUREARB);
00256 GET_WGL_PROCEDURE(glProgramEnvParameter4fvARB, GLPROGRAMENVPARAMETER4FVARB);
00257 GET_WGL_PROCEDURE(glProgramLocalParameter4fvARB, GLPROGRAMLOCALPARAMETER4FVARB);
00258 GET_WGL_PROCEDURE(glGetProgramivARB, GLGETPROGRAMIVARB);
00259
00260 GET_WGL_PROCEDURE(glTexImage3D, GLTEXIMAGE3D);
00261 GET_WGL_PROCEDURE(glTexSubImage3D, GLTEXSUBIMAGE3D);
00262
00263
00264 GET_WGL_PROCEDURE(wglGetPixelFormatAttribivARB, WGLGETPIXELFORMATATTRIBIVARB);
00265 GET_WGL_PROCEDURE(wglGetPixelFormatAttribfvARB, WGLGETPIXELFORMATATTRIBFVARB);
00266 GET_WGL_PROCEDURE(wglChoosePixelFormatARB, WGLCHOOSEPIXELFORMATARB);
00267
00268
00269 GET_WGL_PROCEDURE(wglCreatePbufferARB, WGLCREATEPBUFFERARB);
00270 GET_WGL_PROCEDURE(wglGetPbufferDCARB, WGLGETPBUFFERDCARB);
00271 GET_WGL_PROCEDURE(wglReleasePbufferDCARB, WGLRELEASEPBUFFERDCARB);
00272 GET_WGL_PROCEDURE(wglDestroyPbufferARB, WGLDESTROYPBUFFERARB);
00273 GET_WGL_PROCEDURE(wglQueryPbufferARB, WGLQUERYPBUFFERARB);
00274
00275 if (hWnd)
00276 {
00277 wglMakeCurrent(NULL, NULL);
00278 ReleaseDC(hWnd, hdc);
00279 wglDeleteContext(hglrc);
00280 DestroyWindow(hWnd);
00281 }
00282
00283 #endif
00284 }
00285
00286 SH::ShBackendCodePtr
00287 GlBackend::generateCode(const std::string& target,
00288 const SH::ShProgramNodeCPtr& shader)
00289 {
00290 return m_code->generate(target, shader, m_texture);
00291 }
00292
00293 void
00294 GlBackend::execute(const SH::ShProgramNodeCPtr& program,
00295 SH::ShStream& dest)
00296 {
00297 m_stream->execute(program, dest);
00298 }
00299
00300 }