| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #include "ShaderProgramGL.h"
- #include "VertexDeclarationGL.h"
- #include "oxgl.h"
- #ifndef __S3E__
- #include "SDL.h"
- #endif
- namespace oxygine
- {
- ShaderProgramGL::ShaderProgramGL(GLuint p) : _program(p)
- {
- }
- ShaderProgramGL::ShaderProgramGL(GLuint vs, GLuint ps, const VertexDeclarationGL* decl)
- {
- _program = createProgram(vs, ps, decl);
- }
- ShaderProgramGL::~ShaderProgramGL()
- {
- if (_program)
- oxglDeleteProgram(_program);
- CHECKGL();
- }
- unsigned int ShaderProgramGL::getID() const
- {
- return _program;
- }
- int ShaderProgramGL::getUniformLocation(const char* id) const
- {
- int i = oxglGetUniformLocation(_program, id);
- //if (i == -1)
- CHECKGL();
- return i;
- }
- bool ShaderProgramGL::getShaderBuildLog(GLuint shader, std::string& str)
- {
- GLint length = 0;
- GLint success = GL_TRUE;
- oxglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
- if (length)
- {
- str.resize(length);
- oxglGetShaderInfoLog(shader, (int)str.size(), NULL, &str[0]);
- }
- else
- str.clear();
- GLint status = GL_TRUE;
- oxglGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- return status == GL_TRUE;
- }
- bool ShaderProgramGL::getProgramBuildLog(GLuint program, std::string& str)
- {
- GLint length = 0;
- GLint success = GL_TRUE;
- oxglGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
- if (length)
- {
- str.resize(length);
- oxglGetProgramInfoLog(program, (int)str.size(), NULL, &str[0]);
- }
- else
- str.clear();
- GLint status = GL_TRUE;
- oxglGetProgramiv(program, GL_LINK_STATUS, &status);
- return status == GL_TRUE;
- }
- unsigned int ShaderProgramGL::createShader(unsigned int type, const char* data, const char* prepend, const char* append, error_policy ep)
- {
- GLuint shader = oxglCreateShader(type);
- const char* sources[16];
- const char** ptr = &sources[0];
- bool gles = false;
- #ifdef __S3E__
- gles = true;
- #elif OXYGINE_SDL
- int profile = 0;
- SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile);
- gles = profile == SDL_GL_CONTEXT_PROFILE_ES;
- #else
- #endif
- #ifndef EMSCRIPTEN
- if (!gles)
- {
- //log::messageln("not gles version");
- static const char nonGLES[] =
- "#define lowp\n"
- "#define mediump\n"
- "#define highp\n";
- *ptr = nonGLES;
- ptr++;
- }
- #endif
- #ifdef __ANDROID__
- *ptr = "#define ANDROID 1\n";
- ptr++;
- #endif
- if (prepend)
- {
- *ptr = prepend;
- ptr++;
- }
- *ptr = data;
- ptr++;
- if (append)
- {
- *ptr = append;
- ptr++;
- }
- int num = (int)(ptr - sources);
- oxglShaderSource(shader, num, sources, 0);
- oxglCompileShader(shader);
- std::string log;
- bool success = getShaderBuildLog(shader, log);
- if (success)
- {
- log::messageln("compiled shader: %s", log.c_str());
- }
- else
- {
- handleErrorPolicy(ep, "can't compile shader: %s", log.c_str());
- }
- checkGLError();
- return shader;
- }
- unsigned int ShaderProgramGL::createProgram(int vs, int fs, const VertexDeclarationGL* decl, bool deleteAttachedShaders)
- {
- int p = oxglCreateProgram();
- oxglAttachShader(p, vs);
- oxglAttachShader(p, fs);
- for (int i = 0; i < decl->numElements; ++i)
- oxglBindAttribLocation(p, decl->elements[i].index, decl->elements[i].name);
- oxglLinkProgram(p);
- std::string log;
- bool success = getProgramBuildLog(p, log);
- if (success)
- {
- //log::messageln("compiled shader: %s", log.c_str());
- oxglDetachShader(p, vs);
- oxglDetachShader(p, fs);
- if (deleteAttachedShaders)
- {
- oxglDeleteShader(vs);
- oxglDeleteShader(fs);
- }
- }
- else
- {
- log::error("can't link gl program: %s", log.c_str());
- oxglDeleteProgram(p);
- p = 0;
- }
- CHECKGL();
- return p;
- }
- }
|