void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl, CachedData* programData) { GR_GL_CALL(gl, DeleteShader(programData->fVShaderID)); if (programData->fGShaderID) { GR_GL_CALL(gl, DeleteShader(programData->fGShaderID)); } GR_GL_CALL(gl, DeleteShader(programData->fFShaderID)); GR_GL_CALL(gl, DeleteProgram(programData->fProgramID)); GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));) }
// Compiles a GL shader, attaches it to a program, and releases the shader's reference. // (That way there's no need to hang on to the GL shader id and delete it later.) static bool attach_shader(const GrGLContext& glCtx, GrGLuint programId, GrGLenum type, const SkString& shaderSrc) { const GrGLInterface* gli = glCtx.interface(); GrGLuint shaderId; GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); if (0 == shaderId) { return false; } const GrGLchar* sourceStr = shaderSrc.c_str(); GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); GR_GL_CALL(gli, CompileShader(shaderId)); // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. bool checkCompiled = !glCtx.info().isChromium(); #ifdef SK_DEBUG checkCompiled = true; #endif if (checkCompiled) { GrGLint compiled = GR_GL_INIT_ZERO; GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); if (!compiled) { GrGLint infoLen = GR_GL_INIT_ZERO; GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger if (infoLen > 0) { // retrieve length even though we don't need it to workaround bug in Chromium cmd // buffer param validation. GrGLsizei length = GR_GL_INIT_ZERO; GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get())); GrPrintf(shaderSrc.c_str()); GrPrintf("\n%s", log.get()); } SkDEBUGFAIL("Shader compilation failed!"); GR_GL_CALL(gli, DeleteShader(shaderId)); return false; } } if (c_PrintShaders) { GrPrintf(shaderSrc.c_str()); GrPrintf("\n"); } GR_GL_CALL(gli, AttachShader(programId, shaderId)); GR_GL_CALL(gli, DeleteShader(shaderId)); return true; }
// 終了処理をする void Shader_Finalize(Shader *self) { if (self->active_pass != -1) { fprintf(stderr, "warning: unfinished pass (#%d)\n", self->active_pass); } DeleteGraph(self->depthmap_screen); DeleteShader(self->depthmap_vs); DeleteShader(self->depthmap_ps); DeleteShader(self->phong_vs); DeleteShader(self->phong_ps); delete self; }
bool GrGLShaderBuilder::finish() { SkASSERT(0 == fOutput.fProgramID); GL_CALL_RET(fOutput.fProgramID, CreateProgram()); if (!fOutput.fProgramID) { return false; } SkTDArray<GrGLuint> shadersToDelete; if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { GL_CALL(DeleteProgram(fOutput.fProgramID)); return false; } this->bindProgramLocations(fOutput.fProgramID); if (fUniformManager->isUsingBindUniform()) { fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); } GL_CALL(LinkProgram(fOutput.fProgramID)); // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. bool checkLinked = !fGpu->ctxInfo().isChromium(); #ifdef SK_DEBUG checkLinked = true; #endif if (checkLinked) { GrGLint linked = GR_GL_INIT_ZERO; GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked)); if (!linked) { GrGLint infoLen = GR_GL_INIT_ZERO; GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger if (infoLen > 0) { // retrieve length even though we don't need it to workaround // bug in chrome cmd buffer param validation. GrGLsizei length = GR_GL_INIT_ZERO; GL_CALL(GetProgramInfoLog(fOutput.fProgramID, infoLen+1, &length, (char*)log.get())); GrPrintf((char*)log.get()); } SkDEBUGFAIL("Error linking program"); GL_CALL(DeleteProgram(fOutput.fProgramID)); fOutput.fProgramID = 0; return false; } } if (!fUniformManager->isUsingBindUniform()) { fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); } for (int i = 0; i < shadersToDelete.count(); ++i) { GL_CALL(DeleteShader(shadersToDelete[i])); } return true; }
GrGLuint GrGLProgram::CompileShader(GrGLenum type, int stringCnt, const char** strings, int* stringLengths) { GrGLuint shader = GR_GL(CreateShader(type)); if (0 == shader) { return 0; } GrGLint compiled = GR_GL_INIT_ZERO; GR_GL(ShaderSource(shader, stringCnt, strings, stringLengths)); GR_GL(CompileShader(shader)); GR_GL(GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); if (!compiled) { GrGLint infoLen = GR_GL_INIT_ZERO; GR_GL(GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger if (infoLen > 0) { GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get())); for (int i = 0; i < stringCnt; ++i) { if (NULL == stringLengths || stringLengths[i] < 0) { GrPrintf(strings[i]); } else { GrPrintf("%.*s", stringLengths[i], strings[i]); } } GrPrintf("\n%s", log.get()); } GrAssert(!"Shader compilation failed!"); GR_GL(DeleteShader(shader)); return 0; } return shader; }
// Compiles a GL shader and attaches it to a program. Returns the shader ID if // successful, or 0 if not. static GrGLuint attach_shader(const GrGLContext& glCtx, GrGLuint programId, GrGLenum type, const SkString& shaderSrc) { const GrGLInterface* gli = glCtx.interface(); GrGLuint shaderId; GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); if (0 == shaderId) { return 0; } const GrGLchar* sourceStr = shaderSrc.c_str(); GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); GR_GL_CALL(gli, CompileShader(shaderId)); // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. bool checkCompiled = !glCtx.isChromium(); #ifdef SK_DEBUG checkCompiled = true; #endif if (checkCompiled) { GrGLint compiled = GR_GL_INIT_ZERO; GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); if (!compiled) { GrGLint infoLen = GR_GL_INIT_ZERO; GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger if (infoLen > 0) { // retrieve length even though we don't need it to workaround bug in Chromium cmd // buffer param validation. GrGLsizei length = GR_GL_INIT_ZERO; GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get())); GrPrintf(shaderSrc.c_str()); GrPrintf("\n%s", log.get()); } SkDEBUGFAIL("Shader compilation failed!"); GR_GL_CALL(gli, DeleteShader(shaderId)); return 0; } } TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader", TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str())); if (c_PrintShaders) { GrPrintf(shaderSrc.c_str()); GrPrintf("\n"); } // Attach the shader, but defer deletion until after we have linked the program. // This works around a bug in the Android emulator's GLES2 wrapper which // will immediately delete the shader object and free its memory even though it's // attached to a program, which then causes glLinkProgram to fail. GR_GL_CALL(gli, AttachShader(programId, shaderId)); return shaderId; }
GrGLProgram::~GrGLProgram() { if (fVShaderID) { GL_CALL(DeleteShader(fVShaderID)); } if (fGShaderID) { GL_CALL(DeleteShader(fGShaderID)); } if (fFShaderID) { GL_CALL(DeleteShader(fFShaderID)); } if (fProgramID) { GL_CALL(DeleteProgram(fProgramID)); } for (int i = 0; i < GrDrawState::kNumStages; ++i) { delete fProgramStage[i]; } }
int CShaderListBox::DownShader(UINT nIndex) { int ret = LB_ERR; if ((int)nIndex + 1 < GetCount()) { ASSERT(nIndex < m_List.size()); Shader shader = m_List.at(nIndex); VERIFY(DeleteShader(nIndex) != LB_ERR); ret = InsertShader(nIndex + 1, shader); } return ret; }
bool CShaderListBox::DeleteCurrentShader() { bool ret = false; int sel = GetCurSel(); if (sel != LB_ERR) { if (DeleteShader(sel) != LB_ERR) { ret = true; if (GetCount() == sel) { sel--; } if (sel >= 0) { VERIFY(SetCurSel(sel) != LB_ERR); } } else { ASSERT(FALSE); } } return ret; }
//static variables GLuint ab=0; #define BUFFER_OFFSET(i) ((char *)NULL + (i)) int main () { int i=0; int ab=0; float clr[3] = {0.0f, 0.3f, 0.6f}; float add[3] = {0.001f, 0.002f, 0.003f}; unsigned int position_attrib_idx = 0; //GL stuff SShader vertexShader; SShader fragmentShader; SShaderProgram program; CPlatform platform; Create(&platform, "", 2, 1, 1024, 768, 8, 8, 8, 8, 16, 8, 0); //------------------- //setup the shaders CreateShader(&vertexShader, VERT, &pVertexShader, 1); CreateShader(&fragmentShader, FRAG, &pFragmentShader, 1); CreateShaderProgram(&program); AddShaderToProgram(&program, &vertexShader); AddShaderToProgram(&program, &fragmentShader); SetAttributeLocation(&program, position_attrib_idx, "position"); //needs to be calleb before linking LinkShaderProgram(&program); glGenBuffers(1, &ab); //array buffer //fill buffers glBindBuffer(GL_ARRAY_BUFFER, ab); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //------------------- //tell openGL how to interperet the data glBindBuffer(GL_ARRAY_BUFFER, ab); glEnableVertexAttribArray(0); glVertexAttribPointer(position_attrib_idx, 3, GL_FLOAT, GL_FALSE, 12, 0); //set rendering states glEnable(GL_CULL_FACE); glClearColor(0, 0, 0, 0.0f); //alpha to 0, should make triangle appear over console Start(&program); //even when glDeleteProgram is called the program won't be deleted until it is out of use while (!IS_BUTTON_PRESSED(platform.m_keyboard.key[KB_ESC])) { Tick(&platform); glClear(GL_COLOR_BUFFER_BIT); SetVec3ByName(&program, "uColour", clr); glDrawArrays( GL_TRIANGLES, 0, 3); SwapBuffers(&platform); for(i=0;i<3;i++) { clr[i]+=add[i]; if(clr[i]>1.0f)add[i]*=-1.0f; if(clr[i]<0.0f)add[i]*=-1.0f; } } Stop();
static GrGLuint compile_shader(const GrGLContext* ctx) { const char* version = GrGLGetGLSLVersionDecl(*ctx); // setup vertex shader GrGLShaderVar aPosition("a_position", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier); GrGLShaderVar aColor("a_color", kVec3f_GrSLType, GrShaderVar::kAttribute_TypeModifier); GrGLShaderVar oColor("o_color", kVec3f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier); SkString vshaderTxt(version); aPosition.appendDecl(*ctx, &vshaderTxt); vshaderTxt.append(";\n"); aColor.appendDecl(*ctx, &vshaderTxt); vshaderTxt.append(";\n"); oColor.appendDecl(*ctx, &vshaderTxt); vshaderTxt.append(";\n"); vshaderTxt.append( "void main()\n" "{\n" "gl_Position = vec4(a_position, 0.f, 1.f);\n" "o_color = a_color;\n" "}\n"); const GrGLInterface* gl = ctx->interface(); GrGLuint vertexShader = load_shader(gl, vshaderTxt.c_str(), GR_GL_VERTEX_SHADER); // setup fragment shader GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier); SkString fshaderTxt(version); GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->fStandard, &fshaderTxt); oColor.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier); oColor.appendDecl(*ctx, &fshaderTxt); fshaderTxt.append(";\n"); const char* fsOutName; if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { oFragColor.appendDecl(*ctx, &fshaderTxt); fshaderTxt.append(";\n"); fsOutName = oFragColor.c_str(); } else { fsOutName = "gl_FragColor"; } fshaderTxt.appendf( "void main()\n" "{\n" "%s = vec4(o_color, 1.0f);\n" "}\n", fsOutName); GrGLuint fragmentShader = load_shader(gl, fshaderTxt.c_str(), GR_GL_FRAGMENT_SHADER); GrGLint shaderProgram; GR_GL_CALL_RET(gl, shaderProgram, CreateProgram()); GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader)); GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader)); GR_GL_CALL(gl, LinkProgram(shaderProgram)); // Check for linking errors GrGLint success; GrGLchar infoLog[512]; GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success)); if (!success) { GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, NULL, infoLog)); SkDebugf("Linker Error: %s\n", infoLog); } GR_GL_CALL(gl, DeleteShader(vertexShader)); GR_GL_CALL(gl, DeleteShader(fragmentShader)); return shaderProgram; }
void GrGpuGLShaders::DeleteProgram(GrGLProgram::CachedData* programData) { GR_GL(DeleteShader(programData->fVShaderID)); GR_GL(DeleteShader(programData->fFShaderID)); GR_GL(DeleteProgram(programData->fProgramID)); GR_DEBUGCODE(memset(programData, 0, sizeof(*programData));) }
void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { for (int i = 0; i < shaderIDs.count(); ++i) { GL_CALL(DeleteShader(shaderIDs[i])); } }
GLuint OpenGLInterface::LoadShader(const char* filename, GLenum shader_type, bool check_errors) { GLuint result = 0; // Attempt to open the given file by name std::ifstream t(filename); // Test if the file open step was successful if ((t.rdstate() & std::ifstream::failbit) == 0) { std::string str; // Determine the size of the file and preallocate the size of the string we will be reading into t.seekg(0, std::ios::end); str.reserve((size_t)t.tellg()); t.seekg(0, std::ios::beg); // Read the entire file's contents into the string str.assign((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); // Create an empty shader of the given type // The valid types are: // GL_COMPUTE_SHADER // GL_VERTEX_SHADER // GL_TESS_CONTROL_SHADER // GL_TESS_EVALUATION_SHADER // GL_GEOMETRY_SHADER // GL_FRAGMENT_SHADER // Returns zero unpon failure result = CreateShader(shader_type); if (result) { const char* data = str.c_str(); ShaderSource(result, 1, &data, NULL); CompileShader(result); if (check_errors) { GLint status = 0; GetObjectParameterivARB(result, GL_COMPILE_STATUS, &status); if (!status) { char buffer[4096]; GetShaderInfoLog(result, 4096, NULL, buffer); OutputDebugStringA(filename); OutputDebugStringA(":"); OutputDebugStringA(buffer); OutputDebugStringA("\n"); DeleteShader(result); } } } else { // Failed shader alloc OutputDebugStringA("Failed shader alloc\n"); } } else { // Failed to open shader text file OutputDebugStringA("Failed to open shader file\n"); } return result; }
GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader) { CONTEXT_EXEC(DeleteShader(shader)); }
static void SetupShaders(void){ int got = 0; SShader vtxTxShdr, frgTxShdr; SShader vtxClrShdr, frgClrShdr; SShader vtxLightShdr, frgLightShdr; const char *pDVertStr[3] = {0,0,0}, *pDFragStr[3] = {0,0,0}; glswInit(); glswSetPath("./id1/shaders/", ".glsl"); glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(TRANSFORM_UBO_BINDING)); glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(LIGHT_UBO_BINDING)); glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(MAX_DIRECTION_LIGHTS)); glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(MAX_POINT_LIGHTS)); glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(MAX_SPOT_LIGHTS)); glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(TEXT_TEX_UNIT)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(POSITION_LOCATION)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(COLOUR_LOCATION)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(NORMAL_LOCATION)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(JOINT_WEIGHT_LOCATION)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(JOINT_INDEX_LOCATION)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(UV_LOCATION0)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(UV_LOCATION1)); glswAddDirectiveToken("Vertex", HASH_DEFINE_VALUE(TEXT_LOCATION)); //glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(SKINNING_TEXTURE_BINDING)); //glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(WEIGHTS_PER_VERTEX)); //glswAddDirectiveToken("Shared", HASH_DEFINE(TEXTURE_BUFFER_SKINNING)); //glswAddDirectiveToken("Shared", HASH_DEFINE_VALUE(RESERVED_JOINTS)); //shader (TEXTURED) got = glswGetShadersAlt("shaders.Header.Vertex+shaders.Shared+shaders.SimpleVertexTextured", pDVertStr, 3); CreateShader(&vtxTxShdr, VERT, pDVertStr, got); got = glswGetShadersAlt("shaders.Header.Fragment+shaders.Shared+shaders.SimpleFragmentTextured", pDFragStr, 3); CreateShader(&frgTxShdr, FRAG, pDFragStr, got); CreateShaderProgram(&texture_shader); AddShaderToProgram(&texture_shader,&vtxTxShdr); AddShaderToProgram(&texture_shader,&frgTxShdr); LinkShaderProgram(&texture_shader); //shader (COLOUR) got = glswGetShadersAlt("shaders.Header.Vertex+shaders.Shared+shaders.SimpleVertexColoured", pDVertStr, 3); CreateShader(&vtxClrShdr, VERT, pDVertStr, got); got = glswGetShadersAlt("shaders.Header.Fragment+shaders.Shared+shaders.SimpleFragmentColoured", pDFragStr, 3); CreateShader(&frgClrShdr, FRAG, pDFragStr, got); CreateShaderProgram(&colour_shader); AddShaderToProgram(&colour_shader,&vtxClrShdr); AddShaderToProgram(&colour_shader,&frgClrShdr); LinkShaderProgram(&colour_shader); //shader (LIGHTMAP) got = glswGetShadersAlt("shaders.Header.Vertex+shaders.Shared+shaders.SimpleVertexLightmap", pDVertStr, 3); CreateShader(&vtxLightShdr, VERT, pDVertStr, got); got = glswGetShadersAlt("shaders.Header.Fragment+shaders.Shared+shaders.SimpleFragmentLightmap", pDFragStr, 3); CreateShader(&frgLightShdr, FRAG, pDFragStr, got); CreateShaderProgram(&light_map_shader); AddShaderToProgram(&light_map_shader, &vtxLightShdr); AddShaderToProgram(&light_map_shader, &frgLightShdr); LinkShaderProgram(&light_map_shader); //this will delete them after we have deleted the program associated with them DeleteShader(&vtxTxShdr); DeleteShader(&frgTxShdr); DeleteShader(&vtxClrShdr); DeleteShader(&frgClrShdr); DeleteShader(&vtxLightShdr); DeleteShader(&frgLightShdr); }
Shader::~Shader(void) { DeleteShader(sh); }