Выдернуто из моего проекта, каких-то переменных недосчитаешься
Инициализация шейдеров
#include <GL/gl.h>
#include <gl/glext.h>
#define GLH_EXT_SINGLE_FILE
#include <glh/glh_extensions.h>
int InitShaderExtensions()
{
if(!glh_init_extensions("GL_VERSION_1_2 GL_ARB_shader_objects GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_fragment_shader"))
{
ErrorBox("Can`t initialise shader extensions! Could not continue without shader support");
return -1;
}
return 1;
}
void AddShader(unsigned int Program, unsigned int type,const char *code)
{
if(!Program)
return;
GLhandleARB object = glCreateShaderObjectARB(type);
glShaderSourceARB(object, 1, &code, NULL);
glCompileShaderARB(object);
GLint compiled;
glGetObjectParameterivARB(object, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
if(!compiled)
{
GLint length;
glGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
BYTE *buf = new BYTE[length];
glGetInfoLogARB(object, length, &length, (GLcharARB*)buf);
// Log(LOG_ERROR,"Can`t compile %s shader (AddShader func)\n Shader error: \n%s\n",
// (type == GL_FRAGMENT_SHADER_ARB) ? "fragment" : "vertex", buf);
delete []buf;
Program=0;
return;
}
glAttachObjectARB(Program, object);
glDeleteObjectARB(object);
int result=0;
if(Program)
{
glLinkProgramARB(Program);
glGetObjectParameterivARB(Program, GL_OBJECT_LINK_STATUS_ARB, &result);
if(!result)
{
Log("Can`t link %s shader",
(type == GL_FRAGMENT_SHADER_ARB) ? "fragment" : "vertex");
Program=0;
return;
}
glValidateProgramARB(Program);
glGetObjectParameterivARB(Program, GL_OBJECT_VALIDATE_STATUS_ARB, &result);
if(!result)
{
// Log("Can`t validate %s %s shader",Name.c_str(),
// (type == GL_FRAGMENT_SHADER_ARB) ? "fragment" : "vertex");
Program=0;
return;
}
}
}
Далее загрузка собственно:
Program = glCreateProgramObjectARB();
if(!Program)
{
// Log("Can`t create program object for %s shader",name);
Program=0;
return;
}
AddShader(GL_VERTEX_SHADER_ARB, shader_code_vs.c_str());
AddShader(GL_FRAGMENT_SHADER_ARB, shader_code_ps.c_str());
glUseProgramObjectARB(Program);
//повторить для всех самплеров
glUniform1iARB(glGetUniformLocationARB(Program, "BaseSampler"), 0); //имя самплера в коде шейдера, 0 - слой в glMultitexture
glUniform1iARB(glGetUniformLocationARB(Program, "AdditionSampler"), 1);
...
glUseProgramObjectARB(0);
Вот так передаются переменные в шейдер. Желательно GetHandler(hname) сохранить в какую-то переменную, если ты часто передаёшь, и использовать значение этой переменной чтобы по строке постоянно не искать. Передавать надо по 4 переменных, потому что если передавать меньше всё равно будет до 4х достраивать, передавая нули (лишний расход пропускной способности шины)
void Uniform4f(int Program, char*hname,float f0,float f1,float f2,float f3)
{
glUseProgramObjectARB(Program);
SetUniform4f(GetHandler(hname),f0,f1,f2,f3);
glUseProgramObjectARB(0);
}
Включить/выключить шейдер
glUseProgramObjectARB(Program);
glUseProgramObjectARB(0);