/** * Set the currently active shader * @param shader_obj Pointer to an opengl_shader_t object. This function calls glUseProgramARB with parameter 0 if shader_obj is NULL or if function is called without parameters, causing OpenGL to revert to fixed-function processing */ void opengl_shader_set_current(opengl_shader_t *shader_obj) { if (shader_obj != NULL) { if(!Current_shader || (Current_shader->program_id != shader_obj->program_id)) { Current_shader = shader_obj; vglUseProgramObjectARB(Current_shader->program_id); #ifndef NDEBUG if ( opengl_check_for_errors("shader_set_current()") ) { vglValidateProgramARB(Current_shader->program_id); GLint obj_status = 0; vglGetObjectParameterivARB(Current_shader->program_id, GL_OBJECT_VALIDATE_STATUS_ARB, &obj_status); if ( !obj_status ) { opengl_shader_check_info_log(Current_shader->program_id); mprintf(("VALIDATE INFO-LOG:\n")); if (strlen(GLshader_info_log) > 5) { mprintf(("%s\n", GLshader_info_log)); } else { mprintf(("<EMPTY>\n")); } } } #endif } } else { Current_shader = NULL; vglUseProgramObjectARB(0); } }
/** * Pass a GLSL shader source to OpenGL and compile it into a usable shader object. * Prints compilation errors (if any) to the log. * Note that this will only compile shaders into objects, linking them into executables happens later * * @param shader_source GLSL sourcecode for the shader * @param shader_type OpenGL ID for the type of shader being used, like GL_FRAGMENT_SHADER_ARB, GL_VERTEX_SHADER_ARB * @return OpenGL handle for the compiled shader object */ GLhandleARB opengl_shader_compile_object(const GLcharARB *shader_source, GLenum shader_type) { GLhandleARB shader_object = 0; GLint status = 0; shader_object = vglCreateShaderObjectARB(shader_type); vglShaderSourceARB(shader_object, 1, &shader_source, NULL); vglCompileShaderARB(shader_object); // check if the compile was successful vglGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status); opengl_shader_check_info_log(shader_object); // we failed, bail out now... if (status == 0) { // basic error check mprintf(("%s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", GLshader_info_log)); // this really shouldn't exist, but just in case if (shader_object) { vglDeleteObjectARB(shader_object); } return 0; } // we succeeded, maybe output warnings too if (strlen(GLshader_info_log) > 5) { nprintf(("SHADER-DEBUG", "%s shader compiled with warnings:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", GLshader_info_log)); } return shader_object; }
/** * Link vertex shader, fragment shader and geometry shader objects into a * usable shader executable. * * Prints linker errors (if any) to the log. * * @param vertex_object Compiled vertex shader object * @param fragment_object Compiled fragment shader object * @param geometry_object Compiled geometry shader object * @return Shader executable */ GLhandleARB opengl_shader_link_object(GLhandleARB vertex_object, GLhandleARB fragment_object, GLhandleARB geometry_object) { GLhandleARB shader_object = 0; GLint status = 0; shader_object = vglCreateProgramObjectARB(); if (vertex_object) { vglAttachObjectARB(shader_object, vertex_object); } if (fragment_object) { vglAttachObjectARB(shader_object, fragment_object); } if (geometry_object) { vglAttachObjectARB(shader_object, geometry_object); if ( Current_geo_sdr_params != NULL) { #ifdef __APPLE__ vglProgramParameteriEXT((long)shader_object, GL_GEOMETRY_INPUT_TYPE_EXT, Current_geo_sdr_params->input_type); vglProgramParameteriEXT((long)shader_object, GL_GEOMETRY_OUTPUT_TYPE_EXT, Current_geo_sdr_params->output_type); vglProgramParameteriEXT((long)shader_object, GL_GEOMETRY_VERTICES_OUT_EXT, Current_geo_sdr_params->vertices_out); #else vglProgramParameteriEXT((GLuint)shader_object, GL_GEOMETRY_INPUT_TYPE_EXT, Current_geo_sdr_params->input_type); vglProgramParameteriEXT((GLuint)shader_object, GL_GEOMETRY_OUTPUT_TYPE_EXT, Current_geo_sdr_params->output_type); vglProgramParameteriEXT((GLuint)shader_object, GL_GEOMETRY_VERTICES_OUT_EXT, Current_geo_sdr_params->vertices_out); #endif } } vglLinkProgramARB(shader_object); // check if the link was successful vglGetObjectParameterivARB(shader_object, GL_OBJECT_LINK_STATUS_ARB, &status); opengl_shader_check_info_log(shader_object); // we failed, bail out now... if (status == 0) { mprintf(("Shader failed to link:\n%s\n", GLshader_info_log)); if (shader_object) { vglDeleteObjectARB(shader_object); } return 0; } // we succeeded, maybe output warnings too if (strlen(GLshader_info_log) > 5) { nprintf(("SHADER-DEBUG", "Shader linked with warnings:\n%s\n", GLshader_info_log)); } return shader_object; }
/** * Pass a GLSL shader source to OpenGL and compile it into a usable shader object. * Prints compilation errors (if any) to the log. * Note that this will only compile shaders into objects, linking them into executables happens later * * @param shader_source GLSL sourcecode for the shader * @param shader_type OpenGL ID for the type of shader being used, like GL_FRAGMENT_SHADER_ARB, GL_VERTEX_SHADER_ARB * @return OpenGL handle for the compiled shader object */ GLhandleARB opengl_shader_compile_object(const SCP_vector<SCP_string>& shader_source, GLenum shader_type) { GLhandleARB shader_object = 0; GLint status = 0; SCP_vector<const GLcharARB*> sources; sources.reserve(shader_source.size()); for (auto it = shader_source.begin(); it != shader_source.end(); ++it) { sources.push_back(it->c_str()); } shader_object = vglCreateShaderObjectARB(shader_type); vglShaderSourceARB(shader_object, sources.size(), &sources[0], NULL); vglCompileShaderARB(shader_object); // check if the compile was successful vglGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status); opengl_shader_check_info_log(shader_object); // we failed, bail out now... if (status == 0) { // basic error check mprintf(("%s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : ((shader_type == GL_GEOMETRY_SHADER_EXT) ? "Geometry" : "Fragment"), GLshader_info_log)); // this really shouldn't exist, but just in case if (shader_object) { vglDeleteObjectARB(shader_object); } return 0; } // we succeeded, maybe output warnings too if (strlen(GLshader_info_log) > 5) { nprintf(("SHADER-DEBUG", "%s shader compiled with warnings:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : ((shader_type == GL_GEOMETRY_SHADER_EXT) ? "Geometry" : "Fragment"), GLshader_info_log)); } return shader_object; }
/** * Link a vertex shader object and a fragment shader object into a usable shader executable. * Prints linker errors (if any) to the log. * * @param vertex_object Compiled vertex shader object * @param fragment_object Compiled fragment shader object * @return Shader executable */ GLhandleARB opengl_shader_link_object(GLhandleARB vertex_object, GLhandleARB fragment_object) { GLhandleARB shader_object = 0; GLint status = 0; shader_object = vglCreateProgramObjectARB(); if (vertex_object) { vglAttachObjectARB(shader_object, vertex_object); } if (fragment_object) { vglAttachObjectARB(shader_object, fragment_object); } vglLinkProgramARB(shader_object); // check if the link was successful vglGetObjectParameterivARB(shader_object, GL_OBJECT_LINK_STATUS_ARB, &status); opengl_shader_check_info_log(shader_object); // we failed, bail out now... if (status == 0) { mprintf(("Shader failed to link:\n%s\n", GLshader_info_log)); if (shader_object) { vglDeleteObjectARB(shader_object); } return 0; } // we succeeded, maybe output warnings too if (strlen(GLshader_info_log) > 5) { nprintf(("SHADER-DEBUG", "Shader linked with warnings:\n%s\n", GLshader_info_log)); } return shader_object; }