inline bool CompileShaderFromFile(ZZshProgram& program, const std::string& DefineString, std::string main_entry, GLenum ShaderType) { std::string header(""); header += format("#version %d\n", GLSL_VERSION); header += format("#define %s main\n", main_entry.c_str()); if (ShaderType == GL_VERTEX_SHADER) header += "#define VERTEX_SHADER 1\n"; else if (ShaderType == GL_FRAGMENT_SHADER) header += "#define FRAGMENT_SHADER 1\n"; header += DefineString; const GLchar* ShaderSource[2]; ShaderSource[0] = header.c_str(); ShaderSource[1] = (const GLchar*)ZZshSource; program = glCreateShaderProgramv(ShaderType, 2, &ShaderSource[0]); ZZLog::Debug_Log("Creating program %d for %s", program, main_entry.c_str()); #if defined(DEVBUILD) || defined(_DEBUG) if (!ValidateProgram(program)) return false; #endif return true; }
GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel) { ASSERT(glsl_h_code != NULL); GLuint program = 0; // Note it is better to separate header and source file to have the good line number // in the glsl compiler report const int shader_nb = 3; const char* sources[shader_nb]; std::string header = GenGlslHeader(entry, type, macro_sel); sources[0] = header.c_str(); sources[1] = common_header_glsl; sources[2] = glsl_h_code; program = glCreateShaderProgramv(type, shader_nb, sources); bool status = ValidateProgram(program); if (!status) { // print extra info fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), program); fprintf(stderr, "\n%s", macro_sel.c_str()); fprintf(stderr, "\n"); } m_prog_to_delete.push_back(program); return program; }
void GSShaderOGL::UseProgram() { if (GLState::dirty_prog) { if (!GLLoader::found_GL_ARB_separate_shader_objects) { hash_map<uint64, GLuint >::iterator it; // Note: shader are integer lookup pointer. They start from 1 and incr // every time you create a new shader OR a new program. // Note2: vs & gs are precompiled at startup. FGLRX and radeon got value < 128. GS has only 2 programs // We migth be able to pack the value in a 32bits int // I would need to check the behavior on Nvidia (pause/resume). uint64 sel = (uint64)GLState::vs << 40 | (uint64)GLState::gs << 20 | GLState::ps; it = m_single_prog.find(sel); if (it == m_single_prog.end()) { GLState::program = LinkNewProgram(); m_single_prog[sel] = GLState::program; ValidateProgram(GLState::program); glUseProgram(GLState::program); } else { GLuint prog = it->second; if (prog != GLState::program) { GLState::program = prog; glUseProgram(GLState::program); } } } } GLState::dirty_prog = false; }
ShaderProgram::ShaderProgram(const char* vertexshader, const char* fragmentshader) : _blend_sfactor(GL_ONE), _blend_dfactor(GL_ZERO) { _program = glCreateProgram(); CHECK_ERROR_GL(); GLuint vertex_shader = CompileShader(GL_VERTEX_SHADER, vertexshader); GLuint fragment_shader = CompileShader(GL_FRAGMENT_SHADER, fragmentshader); glAttachShader(_program, vertex_shader); CHECK_ERROR_GL(); glAttachShader(_program, fragment_shader); CHECK_ERROR_GL(); if (!LinkProgram(_program)) { if (_program) { glDeleteProgram(_program); CHECK_ERROR_GL(); _program = 0; } return; } ValidateProgram(_program); glDetachShader(_program, vertex_shader); CHECK_ERROR_GL(); glDetachShader(_program, fragment_shader); CHECK_ERROR_GL(); glDeleteShader(vertex_shader); CHECK_ERROR_GL(); glDeleteShader(fragment_shader); CHECK_ERROR_GL(); }
void Shader::Init(const char* vertexShaderPath, const char* fragmentShaderPath) { _vertexProgram = glCreateShader(GL_VERTEX_SHADER); _fragmentProgram = glCreateShader(GL_FRAGMENT_SHADER); std::string vertexShaderText; std::string fragmentShaderText; if (!ReadShader(vertexShaderPath, vertexShaderText) || !ReadShader(fragmentShaderPath, fragmentShaderText)) { std::cerr << "Either vertex shader or fragment shader file not found." << std::endl; return; } const char* constVST = vertexShaderText.c_str(); const char* constFST = fragmentShaderText.c_str(); glShaderSource(_vertexProgram, 1, &constVST, 0); glShaderSource(_fragmentProgram, 1, &constFST, 0); glCompileShader(_vertexProgram); ValidateShader(_vertexProgram, vertexShaderPath); glCompileShader(_fragmentProgram); ValidateShader(_fragmentProgram, fragmentShaderPath); _id = glCreateProgram(); glAttachShader(_id, _vertexProgram); glAttachShader(_id, _fragmentProgram); glLinkProgram(_id); ValidateProgram(_id); }
void Shader::Compile() { Preprocessor p(m_ShaderSource, m_VsEntry, m_PsEntry, m_Defines); p.Process(m_ShaderFileName, m_ShaderPath); std::string vsCode = p.GetVSCode(); std::string psCode = p.GetPSCode(); m_VSObject = glCreateShader(GL_VERTEX_SHADER); m_FSObject = glCreateShader(GL_FRAGMENT_SHADER); GLchar const* filesVS[]{ vsCode.c_str() }; GLchar const* filesFS[]{ psCode.c_str() }; glShaderSource(m_VSObject, 1, filesVS, 0); glShaderSource(m_FSObject, 1, filesFS, 0); glCompileShader(m_VSObject); ValidateShader(m_VSObject); glCompileShader(m_FSObject); ValidateShader(m_FSObject); m_ShaderObject = glCreateProgram(); glAttachShader(m_ShaderObject, m_VSObject); glAttachShader(m_ShaderObject, m_FSObject); glLinkProgram(m_ShaderObject); ValidateProgram(m_ShaderObject); m_Compiled = true; }
void Shader::LinkProgram() { GLint status; glLinkProgram(m_programId); #if defined(_DEBUG) GLint logLength; glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetProgramInfoLog(m_programId, logLength, &logLength, log); printf("Program link log:\n%s", log); free(log); } #endif glGetProgramiv(m_programId, GL_LINK_STATUS, &status); if (status == 0) { return; assert(false); } ValidateProgram(m_programId); }
bool ShaderProgram::Validate() { if (!ValidateProgram(program_)) { LOGW("Failed to validate program: %d", program_); return false; } return true; }
GLuint GSShaderOGL::LinkNewProgram() { GLuint p = gl_CreateProgram(); if (GLState::vs) gl_AttachShader(p, GLState::vs); if (GLState::ps) gl_AttachShader(p, GLState::ps); if (GLState::gs) gl_AttachShader(p, GLState::gs); gl_LinkProgram(p); ValidateProgram(p); return p; }
GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel) { ASSERT(glsl_h_code != NULL); GLuint program = 0; #ifndef ENABLE_GLES if (type == GL_GEOMETRY_SHADER && !GLLoader::found_geometry_shader) { return program; } #endif // Note it is better to separate header and source file to have the good line number // in the glsl compiler report const char* sources[2]; std::string header = GenGlslHeader(entry, type, macro_sel); int shader_nb = 1; #if 1 sources[0] = header.c_str(); sources[1] = glsl_h_code; shader_nb++; #else sources[0] = header.append(glsl_h_code).c_str(); #endif if (GLLoader::found_GL_ARB_separate_shader_objects) { #ifndef ENABLE_GLES program = gl_CreateShaderProgramv(type, shader_nb, sources); #endif } else { program = gl_CreateShader(type); gl_ShaderSource(program, shader_nb, sources, NULL); gl_CompileShader(program); } bool status; if (GLLoader::found_GL_ARB_separate_shader_objects) status = ValidateProgram(program); else status = ValidateShader(program); if (!status) { // print extra info fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), program); fprintf(stderr, "\n%s", macro_sel.c_str()); fprintf(stderr, "\n"); } return program; }
GLboolean ValidateShaderProgram(GLuint program) { GLint stat; ValidateProgram(program); GetProgramiv(program, GL_VALIDATE_STATUS, &stat); if (!stat) { GLchar log[1000]; GLsizei len; GetProgramInfoLog(program, 1000, &len, log); wxLogError(wxT("BR24radar_pi: program validation error: %s"), log); return 0; } return (GLboolean)stat; }
void GSShaderOGL::UseProgram() { if (GLState::dirty_prog) { if (!GLLoader::found_GL_ARB_separate_shader_objects) { GLState::dirty_subroutine_vs = true; GLState::dirty_subroutine_ps = true; GLState::dirty_ressources = true; hash_map<uint64, GLuint >::iterator it; // Note: shader are integer lookup pointer. They start from 1 and incr // every time you create a new shader OR a new program. // Note2: vs & gs are precompiled at startup. FGLRX and radeon got value < 128. // We migth be able to pack the value in a 32bits int // I would need to check the behavior on Nvidia (pause/resume). uint64 sel = (uint64)GLState::vs << 40 | (uint64)GLState::gs << 20 | GLState::ps; it = m_single_prog.find(sel); if (it == m_single_prog.end()) { GLState::program = LinkNewProgram(); m_single_prog[sel] = GLState::program; ValidateProgram(GLState::program); gl_UseProgram(GLState::program); // warning it must be done after the "setup" of the program SetupUniform(); } else { GLuint prog = it->second; if (prog != GLState::program) { GLState::program = prog; gl_UseProgram(GLState::program); } } } else { ValidatePipeline(m_pipeline); SetupUniform(); } } SetupRessources(); SetupSubroutineUniform(); GLState::dirty_prog = false; }
GLuint GSShaderOGL::LinkProgram(GLuint vs, GLuint gs, GLuint ps) { uint32 hash = ((vs ^ gs) << 24) ^ ps; auto it = m_program.find(hash); if (it != m_program.end()) return it->second; GLuint p = glCreateProgram(); if (vs) glAttachShader(p, vs); if (ps) glAttachShader(p, ps); if (gs) glAttachShader(p, gs); glLinkProgram(p); ValidateProgram(p); m_prog_to_delete.push_back(p); m_program[hash] = p; return p; }
static void PutParametersAndRun(VERTEXSHADER* vs, FRAGMENTSHADER* ps) { UNIFORM_ERROR_LOG("Run program %s(%d) \t+\t%s(%d)", ShaderNames[vs->Shader], vs->Shader, ShaderNames[ps->Shader], ps->Shader); glUseProgram(ZZshMainProgram); if (glGetError() != GL_NO_ERROR) { ZZLog::Error_Log("Something weird happened on Linking stage."); glUseProgram(0); return; } PutSInProgam(vs->ParametersStart, vs->ParametersFinish); PutSInProgam(ps->ParametersStart, ps->ParametersFinish); PutParametersInProgam(0, NumGlobalUniforms); PutParametersInProgam(vs->ParametersStart, vs->ParametersFinish); PutParametersInProgam(ps->ParametersStart, ps->ParametersFinish); ValidateProgram(ZZshMainProgram); GL_REPORT_ERRORD(); }
bool SpriteShader::Init(GLuint vertexShader, GLuint fragmentShader) { if (vertexShader == 0) { LogError("Invalid vertex shader."); return false; } if (fragmentShader == 0) { LogError("Invalid fragment shader."); return false; } this->program = glCreateProgram(); if (!this->program) { LogError("glCreateProgram() has failed."); return false; } LogSpam("Shader program created: %d", this->program); glAttachShader(this->program, vertexShader); glAttachShader(this->program, fragmentShader); // Bind shader attribute locations. glBindAttribLocation(this->program, DEFAULT_VERTEX_ATTRIB_POSITION, "a_position"); glBindAttribLocation(this->program, DEFAULT_VERTEX_ATTRIB_TEXTURE, "a_textureCoord"); if (!LinkProgram()) { glDetachShader(this->program, vertexShader); glDeleteShader(vertexShader); glDetachShader(this->program, fragmentShader); glDeleteShader(fragmentShader); glDeleteProgram(this->program); this->program = 0; LogError("Failure linking shader program."); return false; } if (!ValidateProgram()) { glDetachShader(this->program, vertexShader); glDeleteShader(vertexShader); glDetachShader(this->program, fragmentShader); glDeleteShader(fragmentShader); glDeleteProgram(this->program); this->program = 0; LogError("Failure validating shader program."); return false; } LoadUniformLocation(DEFAULT_SHADER_UNIFORM_MVP, "u_mvp"); LoadUniformLocation(DEFAULT_SHADER_UNIFORM_TEXTURE, "u_sampler"); GL_CHECK_ERROR(); this->vertexShader = vertexShader; this->fragmentShader = fragmentShader; return true; }
GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program) { CONTEXT_EXEC(ValidateProgram(program)); }