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
00030
#ifdef WIN32
00031
00032 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = 0;
00033 PFNGLBINDPROGRAMARBPROC glBindProgramARB = 0;
00034 PFNGLGENPROGRAMSARBPROC glGenProgramsARB = 0;
00035 PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = 0;
00036 PFNGLTEXIMAGE3DPROC glTexImage3D = 0;
00037 PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB = 0;
00038 PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB = 0;
00039 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB = 0;
00040
00041
#endif
00042
00043
namespace shgl {
00044
00045
00046
void shGlCheckError(
const char* desc,
const char* file,
int line)
00047 {
00048 GLenum errnum = glGetError();
00049
char* error = 0;
00050
switch (errnum) {
00051
case GL_NO_ERROR:
00052
return;
00053
case GL_INVALID_ENUM:
00054 error =
"GL_INVALID_ENUM";
00055
break;
00056
case GL_INVALID_VALUE:
00057 error =
"GL_INVALID_VALUE";
00058
break;
00059
case GL_INVALID_OPERATION:
00060 error =
"GL_INVALID_OPERATION";
00061
break;
00062
case GL_STACK_OVERFLOW:
00063 error =
"GL_STACK_OVERFLOW";
00064
break;
00065
case GL_STACK_UNDERFLOW:
00066 error =
"GL_STACK_UNDERFLOW";
00067
break;
00068
case GL_OUT_OF_MEMORY:
00069 error =
"GL_OUT_OF_MEMORY";
00070
break;
00071
case GL_TABLE_TOO_LARGE:
00072 error =
"GL_TABLE_TOO_LARGE";
00073
break;
00074
default:
00075 error =
"Unknown error!";
00076
break;
00077 }
00078 SH_DEBUG_PRINT(
"GL ERROR on " << file <<
": " <<line<<
": "<< error);
00079 SH_DEBUG_PRINT(
"GL ERROR call: " << desc);
00080 }
00081
00082
#ifdef WIN32
00083
#define GET_WGL_PROCEDURE(x, T) do { x = reinterpret_cast<PFN ## T ## PROC>(wglGetProcAddress(#x)); } while(0)
00084
#else
00085
#define GET_WGL_PROCEDURE(x, T) do { } while (0)
00086
#endif
00087
00088 GlBackend::GlBackend(CodeStrategy* code, TextureStrategy* textures,
00089 StreamStrategy* streams)
00090 : m_curContext(0)
00091 {
00092 m_contexts.push_back(Context(code, textures, streams));
00093
00094 GET_WGL_PROCEDURE(glProgramStringARB,
00095 GLPROGRAMSTRINGARB);
00096 GET_WGL_PROCEDURE(glBindProgramARB,
00097 GLBINDPROGRAMARB);
00098 GET_WGL_PROCEDURE(glGenProgramsARB,
00099 GLGENPROGRAMSARB);
00100 GET_WGL_PROCEDURE(glActiveTextureARB,
00101 GLACTIVETEXTUREARB);
00102 GET_WGL_PROCEDURE(glTexImage3D,
00103 GLTEXIMAGE3D);
00104 GET_WGL_PROCEDURE(glProgramEnvParameter4fvARB,
00105 GLPROGRAMENVPARAMETER4FVARB);
00106 GET_WGL_PROCEDURE(glProgramLocalParameter4fvARB,
00107 GLPROGRAMLOCALPARAMETER4FVARB);
00108 GET_WGL_PROCEDURE(glGetProgramivARB,
00109 GLGETPROGRAMIVARB);
00110 }
00111
00112
SH::ShBackendCodePtr
00113 GlBackend::generateCode(
const std::string& target,
00114
const SH::ShProgramNodeCPtr& shader)
00115 {
00116
return m_contexts[m_curContext].code->generate(target, shader,
00117 m_contexts[m_curContext].textures);
00118 }
00119
00120
void
00121 GlBackend::execute(
const SH::ShProgramNodeCPtr& program,
00122
SH::ShStream& dest)
00123 {
00124
00125
if (m_contexts[m_curContext].streams) {
00126 m_contexts[m_curContext].streams->execute(program, dest);
00127 }
00128 }
00129
00130
int GlBackend::newContext()
00131 {
00132
int context_num = m_contexts.size();
00133
const Context& c = m_contexts[0];
00134 m_contexts.push_back(Context(c.code->create(context_num),
00135 c.textures->create(context_num),
00136 c.streams->create(context_num)));
00137
00138 setContext(context_num);
00139
return context_num;
00140 }
00141
00142
int GlBackend::context()
const
00143
{
00144
return m_curContext;
00145 }
00146
00147
void GlBackend::setContext(
int context)
00148 {
00149 SH_DEBUG_ASSERT(0 <= context && context < m_contexts.size());
00150 m_curContext = context;
00151 }
00152
00153
void GlBackend::destroyContext()
00154 {
00155
if (m_curContext == 0)
return;
00156
00157 Context& c = m_contexts[m_curContext];
00158
delete c.code; c.code = 0;
00159
delete c.textures; c.textures = 0;
00160
delete c.streams; c.streams = 0;
00161 setContext(0);
00162 }
00163
00164 }