Shader::~Shader() { glDeleteShader(mShader); }
GLuint GlProgram::loadShader(GLenum type, const GLchar* src){ //LOGD("loadShader()"); GLuint shaderHandle = glCreateShader(type); glShaderSource(shaderHandle, 1, &src, NULL); glCompileShader(shaderHandle); GLint compileStatus; glGetShaderiv(shaderHandle, GL_COMPILE_STATUS,&compileStatus); if(compileStatus == GL_FALSE) { glDeleteShader(shaderHandle); LOGE("Failed to compile %s",((type == GL_VERTEX_SHADER)? "vertex":"fragment")); return UNBIND_HANDLE; } //Parse shader to store attributes and uniform handles string srcString(src); size_t mainStart = srcString.find("void main()"); bool goOn = true; size_t pos = 0; while(goOn){ pos = srcString.find("attribute ", pos); if(pos < mainStart && pos != string::npos){ int start = pos + 9; while(srcString.at(++start) == ' '); while(srcString.at(++start) != ' '); while(srcString.at(++start) == ' '); int stop = start; while(srcString.at(stop) != ' ' && srcString.at(stop) != ';') stop++; GLchar *attributeName = new GLchar[(stop-start)+1]; srcString.copy(attributeName, stop-start,start); attributeName[stop-start] = '\0'; if(this->attributeHandles.count(attributeName) == 0){ this->attributeHandles[attributeName] = UNBIND_HANDLE; } pos = stop; } else{ goOn = false; } } goOn = true; pos = 0; while(goOn){ pos = srcString.find("uniform ", pos); if(pos < mainStart && pos != string::npos){ int start = pos + 7; while(srcString.at(++start) == ' '); while(srcString.at(++start) != ' '); while(srcString.at(++start) == ' '); int stop = start; while(srcString.at(stop) != ' ' && srcString.at(stop) != ';') stop++; GLchar *uniformName = new GLchar[(stop-start)+1]; srcString.copy(uniformName, stop-start,start); uniformName[stop-start] = '\0'; if(this->uniformHandles.count(uniformName) == 0){ this->uniformHandles[uniformName] = UNBIND_HANDLE; } pos = stop; } else{ goOn = false; } } return shaderHandle; }
Apsis::Primitives::VertexShader::~VertexShader() { if (_counter.isAlone()) { glDeleteShader(this->_vertexShader); } }
bool ShaderLoad(GLhandleARB programId, char* shaderSrc, GLenum shaderType) { FILE *fp; GLhandleARB h_shader; GLcharARB *shader_string; GLint str_length, maxLength; GLint isCompiled = GL_FALSE, isLinked = GL_FALSE; GLcharARB *pInfoLog; // open the file of shader source code if ((fp = fopen(shaderSrc, "r")) == NULL) { fprintf(stderr, "Error : Failed to read the OpenGL shader source \"%s\".\n", shaderSrc); return false; } // allocate memory for program string and load it. shader_string = (GLcharARB*)malloc(sizeof(GLcharARB) * 65536); str_length = (GLint)fread(shader_string, 1, 65536, fp); fclose(fp); // Create and load shader string. h_shader = glCreateShader(shaderType); if (h_shader == 0) { fprintf(stderr, "Error : Failed to create OpenGL shader object \"%s\".\n", shaderSrc); return false; } glShaderSource(h_shader, 1, (const GLcharARB**)&shader_string, &str_length); free(shader_string); // Compile the vertex shader, print out the compiler log message. glCompileShader(h_shader); // get compile state information glGetObjectParameterivARB(h_shader, GL_OBJECT_COMPILE_STATUS_ARB, &isCompiled); if (!isCompiled) { fprintf(stderr, "Error : Failed to compile OpenGL shader source \"%s\".\n", shaderSrc); glGetObjectParameterivARB(h_shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); pInfoLog = (GLcharARB *)malloc(maxLength * sizeof(GLcharARB)); glGetInfoLogARB(h_shader, maxLength, &str_length, pInfoLog); fprintf(stderr, "%s\n", pInfoLog); free(pInfoLog); return false; } glAttachShader(programId, h_shader); // delete the shader object, since we have attached it with the program object. glDeleteShader(h_shader); // Link the program and print out the linker log message glLinkProgram(programId); glGetObjectParameterivARB(programId, GL_OBJECT_LINK_STATUS_ARB, &isLinked); if (!isLinked) { fprintf(stderr, "Error : Failed to link OpenGL shader \"%s\".\n", shaderSrc); glGetObjectParameterivARB(programId, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); pInfoLog = (GLcharARB *)malloc(maxLength * sizeof(GLcharARB)); glGetInfoLogARB(programId, maxLength, &str_length, pInfoLog); fprintf(stderr, "%s\n", pInfoLog); free(pInfoLog); return false; } return true; }
// The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // Build and compile our shader program // Vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); // Check for compile time errors GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // Check for compile time errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // Check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { -0.5f, -0.5f, 0.0f, // Left 0.5f, -0.5f, 0.0f, // Right -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f // Top }; GLuint indices[] = { 0,1,3, 3,2,0 }; GLuint VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs) // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Draw our first triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
bool Renderer::LoadShaders(std::string vertex, std::string fragment) { const char* vertex_file_path = vertex.c_str(); const char* fragment_file_path = fragment.c_str(); // Create the shaders GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); // Read the Vertex Shader code from the file std::string VertexShaderCode; std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); if (VertexShaderStream.is_open()) { std::string Line = ""; while (getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } else { fprintf(stderr, "RENDERER: Impossible to open shader file: \"%s\".\n", vertex_file_path); return false; } // Read the Fragment Shader code from the file std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); if (FragmentShaderStream.is_open()) { std::string Line = ""; while (getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } else { fprintf(stderr, "RENDERER: Impossible to open shader file: \"%s\".\n", vertex_file_path); return false; } GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader char const * VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); glCompileShader(VertexShaderID); // Check Vertex Shader glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); // When empty, Info Log contains only \0 char, making the length = 1 if (InfoLogLength > 1) { std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); if (!VertexShaderErrorMessage.empty()) fprintf(stderr, "RENDERER: Vertex shaders compilation errors:\n%s\n", &VertexShaderErrorMessage[0]); } // Compile Fragment Shader char const * FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); glCompileShader(FragmentShaderID); // Check Fragment Shader glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); // When empty, Info Log contains only \0 char, making the length = 1 if (InfoLogLength > 1) { std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); if (!FragmentShaderErrorMessage.empty()) fprintf(stderr, "RENDERER: Vertex shaders compilation errors:\n%s\n", &FragmentShaderErrorMessage[0]); } // Link the program mProgram = glCreateProgram(); glAttachShader(mProgram, VertexShaderID); glAttachShader(mProgram, FragmentShaderID); glLinkProgram(mProgram); // Check the program glGetProgramiv(mProgram, GL_LINK_STATUS, &Result); glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &InfoLogLength); // When empty, Info Log contains only \0 char, making the length = 1 if (InfoLogLength > 1) { std::vector<char> ProgramErrorMessage(InfoLogLength + 1); glGetProgramInfoLog(mProgram, InfoLogLength, NULL, &ProgramErrorMessage[0]); if (!ProgramErrorMessage.empty()) fprintf(stderr, "RENDERER: Shaders linking errors:\n%s\n", &ProgramErrorMessage[0]); } // Clean up glDetachShader(mProgram, VertexShaderID); glDetachShader(mProgram, FragmentShaderID); glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return true; }
GLuint initProgram(string vertexFile, string fragmentFile) { // Create shaders GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); string tempV = getAeonDir()+vertexFile; string tempF = getAeonDir()+fragmentFile; string vertexCode; string fragmentCode; // Read vertex shader from file ifstream vertexShaderStream(tempV.c_str(), std::ios::in); if(vertexShaderStream.is_open()) { string vLine = ""; while(getline(vertexShaderStream, vLine)) vertexCode += "\n" + vLine; vertexShaderStream.close(); } else { log("Failed to open vertex shader at: \""+tempV+"\"", AEON_ERROR); return 0; } // Read fragment shader from file ifstream fragmentShaderStream(tempF.c_str(), std::ios::in); if(fragmentShaderStream.is_open()) { string fLine = ""; while(getline(fragmentShaderStream, fLine)) fragmentCode += "\n" + fLine; fragmentShaderStream.close(); } else { log("Failed to open fragment shader at: \""+tempF+"\"", AEON_ERROR); return 0; } GLint result = GL_FALSE; int infoLogLength; // Compile Vertex Shader log("Compiling vertex shader: \""+vertexFile+"\"", AEON_INFO); char const * vertexSourcePointer = vertexCode.c_str(); glShaderSource(vertexShaderID, 1, &vertexSourcePointer, NULL); glCompileShader(vertexShaderID); // Check Vertex Shader glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &result); glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); if ( infoLogLength > 0 ) { std::vector<char> vertexShaderErrorMessage(infoLogLength+1); glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, &vertexShaderErrorMessage[0]); if(vertexShaderErrorMessage.size() > 2) log(vertexShaderErrorMessage, AEON_ERROR); } // Compile Fragment Shader log("Compiling fragment shader: \""+fragmentFile+"\"", AEON_INFO); char const * fragmentSourcePointer = fragmentCode.c_str(); glShaderSource(fragmentShaderID, 1, &fragmentSourcePointer, NULL); glCompileShader(fragmentShaderID); // Check Vertex Shader glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &result); glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); if ( infoLogLength > 0 ) { std::vector<char> fragmentShaderErrorMessage(infoLogLength+1); glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, &fragmentShaderErrorMessage[0]); if(fragmentShaderErrorMessage.size() > 2) log(fragmentShaderErrorMessage, AEON_ERROR); } // Link program log("Linking program.", AEON_INFO); GLuint programID = glCreateProgram(); glAttachShader(programID, vertexShaderID); glAttachShader(programID, fragmentShaderID); glLinkProgram(programID); // Check the program glGetProgramiv(programID, GL_LINK_STATUS, &result); glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength); if ( infoLogLength > 0 ) { std::vector<char> programErrorMessage(infoLogLength+1); glGetProgramInfoLog(programID, infoLogLength, NULL, &programErrorMessage[0]); if(programErrorMessage.size() > 2) log(programErrorMessage, AEON_ERROR); } // Clean up glDeleteShader(vertexShaderID); glDeleteShader(fragmentShaderID); return programID; }
bool ShaderVariation::Create() { Release(); if (!owner_) { compilerOutput_ = "Owner shader has expired"; return false; } object_ = glCreateShader(type_ == VS ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); if (!object_) { compilerOutput_ = "Could not create shader object"; return false; } const String& originalShaderCode = owner_->GetSourceCode(type_); String shaderCode; // Check if the shader code contains a version define unsigned verStart = originalShaderCode.Find('#'); unsigned verEnd = 0; if (verStart != String::NPOS) { if (originalShaderCode.Substring(verStart + 1, 7) == "version") { verEnd = verStart + 9; while (verEnd < originalShaderCode.Length()) { if (IsDigit((unsigned)originalShaderCode[verEnd])) ++verEnd; else break; } // If version define found, insert it first String versionDefine = originalShaderCode.Substring(verStart, verEnd - verStart); shaderCode += versionDefine + "\n"; } } // Force GLSL version 150 if no version define and GL3 is being used if (!verEnd && Graphics::GetGL3Support()) shaderCode += "#version 150\n"; // Distinguish between VS and PS compile in case the shader code wants to include/omit different things shaderCode += type_ == VS ? "#define COMPILEVS\n" : "#define COMPILEPS\n"; // Add define for the maximum number of supported bones shaderCode += "#define MAXBONES " + String(Graphics::GetMaxBones()) + "\n"; // Prepend the defines to the shader code Vector<String> defineVec = defines_.Split(' '); for (unsigned i = 0; i < defineVec.Size(); ++i) { // Add extra space for the checking code below String defineString = "#define " + defineVec[i].Replaced('=', ' ') + " \n"; shaderCode += defineString; // In debug mode, check that all defines are referenced by the shader code #ifdef _DEBUG String defineCheck = defineString.Substring(8, defineString.Find(' ', 8) - 8); if (originalShaderCode.Find(defineCheck) == String::NPOS) URHO3D_LOGWARNING("Shader " + GetFullName() + " does not use the define " + defineCheck); #endif } #ifdef RPI if (type_ == VS) shaderCode += "#define RPI\n"; #endif #ifdef __EMSCRIPTEN__ shaderCode += "#define WEBGL\n"; #endif if (Graphics::GetGL3Support()) shaderCode += "#define GL3\n"; // When version define found, do not insert it a second time if (verEnd > 0) shaderCode += (originalShaderCode.CString() + verEnd); else shaderCode += originalShaderCode; const char* shaderCStr = shaderCode.CString(); glShaderSource(object_, 1, &shaderCStr, 0); glCompileShader(object_); int compiled, length; glGetShaderiv(object_, GL_COMPILE_STATUS, &compiled); if (!compiled) { glGetShaderiv(object_, GL_INFO_LOG_LENGTH, &length); compilerOutput_.Resize((unsigned)length); int outLength; glGetShaderInfoLog(object_, length, &outLength, &compilerOutput_[0]); glDeleteShader(object_); object_ = 0; } else compilerOutput_.Clear(); return object_ != 0; }
void shader_delete(shader* shader) { glDeleteShader(shader_handle(shader)); free(shader); }
void shader_destroy(Shader_t *aShader) { glDeleteShader(aShader->vertexShader); glDeleteShader(aShader->fragmentShader); glDeleteProgram(aShader->program); }
Shader::~Shader() { glDeleteShader(this->ID); }
void BeginRender(const Rect &inRect,bool inForHitTest) { if (!inForHitTest) { if (mContextId!=gTextureContextVersion) { updateContext(); } #ifndef NME_GLES #ifndef SDL_OGL #ifndef GLFW_OGL wglMakeCurrent(mDC,mOGLCtx); #endif #endif #endif if (mHasZombie) { mHasZombie = false; if (mZombieTextures.size()) { glDeleteTextures(mZombieTextures.size(),&mZombieTextures[0]); mZombieTextures.resize(0); } if (mZombieVbos.size()) { glDeleteBuffers(mZombieVbos.size(),&mZombieVbos[0]); mZombieVbos.resize(0); } if (mZombiePrograms.size()) { for(int i=0;i<mZombiePrograms.size();i++) glDeleteProgram(mZombiePrograms[i]); mZombiePrograms.resize(0); } if (mZombieShaders.size()) { for(int i=0;i<mZombieShaders.size();i++) glDeleteShader(mZombieShaders[i]); mZombieShaders.resize(0); } if (mZombieFramebuffers.size()) { glDeleteFramebuffers(mZombieFramebuffers.size(),&mZombieFramebuffers[0]); mZombieFramebuffers.resize(0); } if (mZombieRenderbuffers.size()) { glDeleteRenderbuffers(mZombieRenderbuffers.size(),&mZombieRenderbuffers[0]); mZombieRenderbuffers.resize(0); } } // Force dirty mViewport.w = -1; SetViewport(inRect); glEnable(GL_BLEND); #ifdef WEBOS glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); #endif mLineWidth = 99999; // printf("DrawArrays: %d, DrawBitmaps:%d Buffers:%d\n", sgDrawCount, sgDrawBitmap, sgBufferCount ); sgDrawCount = 0; sgDrawBitmap = 0; } }
static GLuint gl_glsl_compile_program(glsl_shader_data_t *glsl, const char *vertex, const char *fragment, unsigned i) { GLuint vert = 0, frag = 0, prog = glCreateProgram(); if (!prog) return 0; if (vertex) { RARCH_LOG("Found GLSL vertex shader.\n"); vert = glCreateShader(GL_VERTEX_SHADER); if (!gl_glsl_compile_shader( glsl, vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex)) { RARCH_ERR("Failed to compile vertex shader #%u\n", i); return 0; } glAttachShader(prog, vert); } if (fragment) { RARCH_LOG("Found GLSL fragment shader.\n"); frag = glCreateShader(GL_FRAGMENT_SHADER); if (!gl_glsl_compile_shader(glsl, frag, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment)) { RARCH_ERR("Failed to compile fragment shader #%u\n", i); return 0; } glAttachShader(prog, frag); } if (vertex || fragment) { RARCH_LOG("Linking GLSL program.\n"); if (!gl_glsl_link_program(prog)) { RARCH_ERR("Failed to link program #%u.\n", i); return 0; } /* Clean up dead memory. We're not going to relink the program. * Detaching first seems to kill some mobile drivers * (according to the intertubes anyways). */ if (vert) glDeleteShader(vert); if (frag) glDeleteShader(frag); glUseProgram(prog); glUniform1i(gl_glsl_get_uniform(glsl, prog, "Texture"), 0); glUseProgram(0); } return prog; }
int main() { int width = 640; int height = 480; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 4); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3); // create a window if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } // setup windows close callback glfwSetWindowCloseCallback(closedWindow); if (gl3wInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwCloseWindow(); glfwTerminate(); return 1; } // shader source code // the vertex shader simply passes through data std::string vertex_source = "#version 430\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = vposition;\n" "}\n"; // the geometry shader creates the billboard quads std::string geometry_source = "#version 430\n" "uniform mat4 View;\n" "uniform mat4 Projection;\n" "layout (points) in;\n" "layout (triangle_strip, max_vertices = 4) out;\n" "out vec2 txcoord;\n" "void main() {\n" " vec4 pos = View*gl_in[0].gl_Position;\n" " txcoord = vec2(-1,-1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1,-1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2(-1, 1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1, 1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" "}\n"; // the fragment shader creates a bell like radial color distribution std::string fragment_source = "#version 330\n" "in vec2 txcoord;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " float s = 0.2*(1/(1+15.*dot(txcoord, txcoord))-1/16.);\n" " FragColor = s*vec4(0.3,0.3,1.0,1);\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, geometry_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler geometry shader geometry_shader = glCreateShader(GL_GEOMETRY_SHADER); source = geometry_source.c_str(); length = geometry_source.size(); glShaderSource(geometry_shader, 1, &source, &length); glCompileShader(geometry_shader); if(!check_shader_compile_status(geometry_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, geometry_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // obtain location of projection uniform GLint View_location = glGetUniformLocation(shader_program, "View"); GLint Projection_location = glGetUniformLocation(shader_program, "Projection"); std::string compute_source = "#version 430\n" "layout(local_size_x=256) in;\n" "uniform vec3 center[3];\n" "uniform float radius[3];\n" "uniform vec3 g;\n" "uniform float dt;\n" "uniform float bounce;\n" "uniform int seed;\n" "uniform layout(rgba32f) imageBuffer particles;\n" "float hash(int x) {\n" " x = x*1235167 + int(gl_GlobalInvocationID)*948737 + seed*9284365;\n" " x = (x >> 13) ^ x;\n" " return ((x * (x * x * 60493 + 19990303) + 1376312589) & 0x7fffffff)/float(0x7fffffff-1);\n" "}\n" "void main() {\n" " int index = int(gl_GlobalInvocationID);\n" " vec3 inposition = imageLoad(particles, 2*index).xyz;\n" " vec3 invelocity = imageLoad(particles, 2*index+1).xyz;\n" " vec3 outvelocity = invelocity;\n" " for(int j = 0;j<3;++j) {\n" " vec3 diff = inposition-center[j];\n" " float dist = length(diff);\n" " float vdot = dot(diff, invelocity);\n" " if(dist<radius[j] && vdot<0.0)\n" " outvelocity -= bounce*diff*vdot/(dist*dist);\n" " }\n" " outvelocity += dt*g;\n" " vec3 outposition = inposition + dt*outvelocity;\n" " if(outposition.y < -30.0)\n" " {\n" " outvelocity = vec3(0,0,0);\n" " outposition = 0.5-vec3(hash(3*index+0),hash(3*index+1),hash(3*index+2));\n" " outposition = vec3(0,20,0) + 5.0*outposition;\n" " }\n" " imageStore(particles, 2*index, vec4(outposition,1));\n" " imageStore(particles, 2*index+1, vec4(outvelocity,1));\n" "}\n"; // program and shader handles GLuint compute_program, compute_shader; // create and compiler vertex shader compute_shader = glCreateShader(GL_COMPUTE_SHADER); source = compute_source.c_str(); length = compute_source.size(); glShaderSource(compute_shader, 1, &source, &length); glCompileShader(compute_shader); if(!check_shader_compile_status(compute_shader)) { return 1; } // create program compute_program = glCreateProgram(); // attach shaders glAttachShader(compute_program, compute_shader); // link the program and check for errors glLinkProgram(compute_program); check_program_link_status(compute_program); GLint center_location = glGetUniformLocation(compute_program, "center"); GLint radius_location = glGetUniformLocation(compute_program, "radius"); GLint g_location = glGetUniformLocation(compute_program, "g"); GLint dt_location = glGetUniformLocation(compute_program, "dt"); GLint bounce_location = glGetUniformLocation(compute_program, "bounce"); GLint seed_location = glGetUniformLocation(compute_program, "seed"); GLint particles_location = glGetUniformLocation(compute_program, "particles"); const int particles = 128*1024; // randomly place particles in a cube std::vector<glm::vec4> vertexData(2*particles); for(int i = 0;i<particles;++i) { // initial position vertexData[2*i+0] = glm::vec4( 0.5f-float(std::rand())/RAND_MAX, 0.5f-float(std::rand())/RAND_MAX, 0.5f-float(std::rand())/RAND_MAX, 0 ); vertexData[2*i+0] = glm::vec4(0.0f,20.0f,0.0f,1) + 5.0f*vertexData[2*i+0]; // initial velocity vertexData[2*i+1] = glm::vec4(0,0,0,0); } // generate vbos and vaos GLuint vao, vbo; glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); // fill with initial data glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4)*vertexData.size(), &vertexData[0], GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // set up generic attrib pointers glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (char*)0 + 4*sizeof(GLfloat)); // "unbind" vao glBindVertexArray(0); // texture handle GLuint buffer_texture; // generate and bind the buffer texture glGenTextures(1, &buffer_texture); glBindTexture(GL_TEXTURE_BUFFER, buffer_texture); // tell the buffer texture to use glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, vbo); // we are blending so no depth testing glDisable(GL_DEPTH_TEST); // enable blending glEnable(GL_BLEND); // and set the blend function to result = 1*source + 1*destination glBlendFunc(GL_ONE, GL_ONE); // define spheres for the particles to bounce off const int spheres = 3; glm::vec3 center[spheres]; float radius[spheres]; center[0] = glm::vec3(0,12,1); radius[0] = 3; center[1] = glm::vec3(-3,0,0); radius[1] = 7; center[2] = glm::vec3(5,-10,0); radius[2] = 12; // physical parameters float dt = 1.0f/60.0f; glm::vec3 g(0.0f, -9.81f, 0.0f); float bounce = 1.2f; // inelastic: 1.0f, elastic: 2.0f int current_buffer=0; running = true; while(running) { // get the time in seconds float t = glfwGetTime(); // terminate on excape if(glfwGetKey(GLFW_KEY_ESC)) { running = false; } // use the transform shader program glUseProgram(compute_program); // set the uniforms glUniform3fv(center_location, 3, reinterpret_cast<GLfloat*>(center)); glUniform1fv(radius_location, 3, reinterpret_cast<GLfloat*>(radius)); glUniform3fv(g_location, 1, glm::value_ptr(g)); glUniform1f(dt_location, dt); glUniform1f(bounce_location, bounce); glUniform1i(seed_location, std::rand()); glBindImageTexture(0, buffer_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); glUniform1i(particles_location, 0); glDispatchCompute(particles/256, 1, 1); // clear first glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // calculate ViewProjection matrix glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f); // translate the world/view position glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -30.0f)); // make the camera rotate around the origin View = glm::rotate(View, 30.0f, glm::vec3(1.0f, 0.0f, 0.0f)); View = glm::rotate(View, -22.5f*t, glm::vec3(0.0f, 1.0f, 0.0f)); // set the uniform glUniformMatrix4fv(View_location, 1, GL_FALSE, glm::value_ptr(View)); glUniformMatrix4fv(Projection_location, 1, GL_FALSE, glm::value_ptr(Projection)); // bind the current vao glBindVertexArray(vao); // draw glDrawArrays(GL_POINTS, 0, particles); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { std::cerr << gluErrorString(error); running = false; } // finally swap buffers glfwSwapBuffers(); } // delete the created objects glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteTextures(1, &buffer_texture); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, geometry_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(geometry_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glDetachShader(compute_program, compute_shader); glDeleteShader(compute_shader); glDeleteProgram(compute_program); glfwCloseWindow(); glfwTerminate(); return 0; }
ShaderGLES2::Version *ShaderGLES2::get_current_version() { Version *_v = version_map.getptr(conditional_version); if (_v) { if (conditional_version.code_version != 0) { CustomCode *cc = custom_code_map.getptr(conditional_version.code_version); ERR_FAIL_COND_V(!cc, _v); if (cc->version == _v->code_version) return _v; } else { return _v; } } if (!_v) version_map[conditional_version]; Version &v = version_map[conditional_version]; if (!_v) { v.uniform_location = memnew_arr(GLint, uniform_count); } else { if (v.ok) { glDeleteShader(v.vert_id); glDeleteShader(v.frag_id); glDeleteProgram(v.id); v.id = 0; } } v.ok = false; Vector<const char *> strings; #ifdef GLES_OVER_GL strings.push_back("#version 120\n"); strings.push_back("#define USE_GLES_OVER_GL\n"); #else strings.push_back("#version 100\n"); #endif int define_line_ofs = 1; for (int j = 0; j < conditional_count; j++) { bool enable = (conditional_version.version & (1 << j)) > 0; if (enable) { strings.push_back(conditional_defines[j]); define_line_ofs++; DEBUG_PRINT(conditional_defines[j]); } } // keep them around during the functino CharString code_string; CharString code_string2; CharString code_globals; CustomCode *cc = NULL; if (conditional_version.code_version > 0) { cc = custom_code_map.getptr(conditional_version.code_version); ERR_FAIL_COND_V(!cc, NULL); v.code_version = cc->version; define_line_ofs += 2; } // program v.id = glCreateProgram(); ERR_FAIL_COND_V(v.id == 0, NULL); if (cc) { for (int i = 0; i < cc->custom_defines.size(); i++) { strings.push_back(cc->custom_defines[i]); DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i])); } } // vertex shader int string_base_size = strings.size(); strings.push_back(vertex_code0.get_data()); if (cc) { code_globals = cc->vertex_globals.ascii(); strings.push_back(code_globals.get_data()); } strings.push_back(vertex_code1.get_data()); if (cc) { code_string = cc->vertex.ascii(); strings.push_back(code_string.get_data()); } strings.push_back(vertex_code2.get_data()); #ifdef DEBUG_SHADER DEBUG_PRINT("\nVertex Code:\n\n" + String(code_string.get_data())); #endif v.vert_id = glCreateShader(GL_VERTEX_SHADER); glShaderSource(v.vert_id, strings.size(), &strings[0], NULL); glCompileShader(v.vert_id); GLint status; glGetShaderiv(v.vert_id, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLsizei iloglen; glGetShaderiv(v.vert_id, GL_INFO_LOG_LENGTH, &iloglen); if (iloglen < 0) { glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?"); } else { if (iloglen == 0) { iloglen = 4096; // buggy driver (Adreno 220+) } char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); ilogmem[iloglen] = '\0'; glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem); String err_string = get_shader_name() + ": Vertex shader compilation failed:\n"; err_string += ilogmem; err_string = _fix_error_code_line(err_string, vertex_code_start, define_line_ofs); ERR_PRINTS(err_string); Memory::free_static(ilogmem); glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; } ERR_FAIL_V(NULL); } strings.resize(string_base_size); // fragment shader strings.push_back(fragment_code0.get_data()); if (cc) { code_globals = cc->fragment_globals.ascii(); strings.push_back(code_globals.get_data()); } strings.push_back(fragment_code1.get_data()); if (cc) { code_string = cc->fragment.ascii(); strings.push_back(code_string.get_data()); } strings.push_back(fragment_code2.get_data()); if (cc) { code_string2 = cc->light.ascii(); strings.push_back(code_string2.get_data()); } strings.push_back(fragment_code3.get_data()); #ifdef DEBUG_SHADER DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data())); #endif v.frag_id = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(v.frag_id, strings.size(), &strings[0], NULL); glCompileShader(v.frag_id); glGetShaderiv(v.frag_id, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLsizei iloglen; glGetShaderiv(v.frag_id, GL_INFO_LOG_LENGTH, &iloglen); if (iloglen < 0) { glDeleteShader(v.frag_id); glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; ERR_PRINT("No OpenGL fragment shader compiler log. What the frick?"); } else { if (iloglen == 0) { iloglen = 4096; // buggy driver (Adreno 220+) } char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); ilogmem[iloglen] = '\0'; glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem); String err_string = get_shader_name() + ": Fragment shader compilation failed:\n"; err_string += ilogmem; err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs); ERR_PRINTS(err_string); Memory::free_static(ilogmem); glDeleteShader(v.frag_id); glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; } ERR_FAIL_V(NULL); } glAttachShader(v.id, v.frag_id); glAttachShader(v.id, v.vert_id); // bind the attribute locations. This has to be done before linking so that the // linker doesn't assign some random indices for (int i = 0; i < attribute_pair_count; i++) { glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name); } glLinkProgram(v.id); glGetProgramiv(v.id, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLsizei iloglen; glGetProgramiv(v.id, GL_INFO_LOG_LENGTH, &iloglen); if (iloglen < 0) { glDeleteShader(v.frag_id); glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; ERR_PRINT("No OpenGL program link log. What the frick?"); ERR_FAIL_V(NULL); } if (iloglen == 0) { iloglen = 4096; // buggy driver (Adreno 220+) } char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); ilogmem[iloglen] = '\0'; glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem); String err_string = get_shader_name() + ": Program linking failed:\n"; err_string += ilogmem; err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs); ERR_PRINTS(err_string); Memory::free_static(ilogmem); glDeleteShader(v.frag_id); glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; ERR_FAIL_V(NULL); } // get uniform locations glUseProgram(v.id); for (int i = 0; i < uniform_count; i++) { v.uniform_location[i] = glGetUniformLocation(v.id, uniform_names[i]); } for (int i = 0; i < texunit_pair_count; i++) { GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name); if (loc >= 0) glUniform1i(loc, texunit_pairs[i].index); } if (cc) { v.custom_uniform_locations.resize(cc->custom_uniforms.size()); for (int i = 0; i < cc->custom_uniforms.size(); i++) { v.custom_uniform_locations[i] = glGetUniformLocation(v.id, String(cc->custom_uniforms[i]).ascii().get_data()); } } glUseProgram(0); v.ok = true; return &v; }
// Constructor generates the shader on the fly Shader(const GLchar* vertexPath, const GLchar* fragmentPath) { // 1. Retrieve the vertex/fragment source code from filePath std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; // ensures ifstream objects can throw exceptions: vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); try { // Open files vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); // Read file's buffer contents into streams std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); // close file handlers vShaderFile.close(); fShaderFile.close(); // Convert stream into string vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::ifstream::failure e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; } const GLchar* vShaderCode = vertexCode.c_str(); const GLchar * fShaderCode = fragmentCode.c_str(); // 2. Compile shaders GLuint vertex, fragment; GLint success; GLchar infoLog[512]; // Vertex Shader vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); // Print compile errors if any glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment Shader fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); // Print compile errors if any glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Shader Program this->Program = glCreateProgram(); glAttachShader(this->Program, vertex); glAttachShader(this->Program, fragment); glLinkProgram(this->Program); // Print linking errors if any glGetProgramiv(this->Program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(this->Program, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } // Delete the shaders as they're linked into our program now and no longer necessery glDeleteShader(vertex); glDeleteShader(fragment); }
Shader::~Shader() { glDeleteShader(shader_); }
bool ProgramShaderCache::CompileShader ( SHADER& shader, const char* vcode, const char* pcode ) { GLuint vsid = CompileSingleShader(GL_VERTEX_SHADER, vcode); GLuint psid = CompileSingleShader(GL_FRAGMENT_SHADER, pcode); if (!vsid || !psid) { glDeleteShader(vsid); glDeleteShader(psid); return false; } GLuint pid = shader.glprogid = glCreateProgram();; glAttachShader(pid, vsid); glAttachShader(pid, psid); if (g_ogl_config.bSupportsGLSLCache) glProgramParameteri(pid, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); shader.SetProgramBindings(); glLinkProgram(pid); // original shaders aren't needed any more glDeleteShader(vsid); glDeleteShader(psid); GLint linkStatus; glGetProgramiv(pid, GL_LINK_STATUS, &linkStatus); GLsizei length = 0; glGetProgramiv(pid, GL_INFO_LOG_LENGTH, &length); if (linkStatus != GL_TRUE || (length > 1 && DEBUG_GLSL)) { GLsizei charsWritten; GLchar* infoLog = new GLchar[length]; glGetProgramInfoLog(pid, length, &charsWritten, infoLog); ERROR_LOG(VIDEO, "Program info log:\n%s", infoLog); char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_p_%d.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); std::ofstream file; OpenFStream(file, szTemp, std::ios_base::out); file << s_glsl_header << vcode << s_glsl_header << pcode << infoLog; file.close(); if (linkStatus != GL_TRUE) PanicAlert("Failed to link shaders!\nThis usually happens when trying to use Dolphin with an outdated GPU or integrated GPU like the Intel GMA series.\n\nIf you're sure this is Dolphin's error anyway, post the contents of %s along with this error message at the forums.\n\nDebug info (%s, %s, %s):\n%s", szTemp, g_ogl_config.gl_vendor, g_ogl_config.gl_renderer, g_ogl_config.gl_version, infoLog); delete [] infoLog; } if (linkStatus != GL_TRUE) { // Compile failed ERROR_LOG(VIDEO, "Program linking failed; see info log"); // Don't try to use this shader glDeleteProgram(pid); return false; } shader.SetProgramVariables(); return true; }
OGLSurface* OGLSurface_Create( const FrameBuffer* const framebuffer) { const unsigned int sizeOfPixelBufferInBytes = framebuffer->Width * framebuffer->Height * 4; unsigned int numBuffer = 0; OGLSurface* surface = malloc( sizeof(OGLSurface)); memset( surface, 0, sizeof(OGLSurface)); // generate texture glGenTextures(NUM_BUFFERS, surface->TextureID); for (numBuffer; numBuffer < NUM_BUFFERS; ++numBuffer) { glBindTexture( GL_TEXTURE_2D, surface->TextureID[numBuffer]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); surface->Width = framebuffer->Width; surface->Height = framebuffer->Height; glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->Width, surface->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture( GL_TEXTURE_2D, 0); } // generate shader { // create shaders GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); GLuint shaderProgram = glCreateProgram(); GLint vertexShaderLength = strlen(vertexShaderSource); GLint fragmentShaderLength = strlen(fragmentShaderSource); const GLchar* vertexShaderSourcePtr = vertexShaderSource; const GLchar* fragmentShaderSourcePtr = fragmentShaderSource; // vertex shader load and compile glShaderSource(vertexShader, 1, &vertexShaderSourcePtr, &vertexShaderLength); glCompileShader(vertexShader); OGL_HasShaderCompilationError(vertexShader); // fragment shader load and compile glShaderSource(fragmentShader, 1, &fragmentShaderSourcePtr, &fragmentShaderLength); glCompileShader(fragmentShader); OGL_HasShaderCompilationError(fragmentShader); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); OGL_HasShaderLinkError(shaderProgram); // delete shader objects glDetachShader(shaderProgram, vertexShader); glDetachShader(shaderProgram, fragmentShader); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); surface->ShaderProgram = shaderProgram; } // generate dummy vao, is required to use glDrawArrays with no data { glGenVertexArrays(1, &surface->VaoDummy); } surface->SizeInBytes = sizeOfPixelBufferInBytes; // generate pixel buffer glGenBuffers(NUM_BUFFERS, surface->PixelBufferID); for (unsigned int i = 0; i < NUM_BUFFERS; ++i) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->PixelBufferID[i]); glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->SizeInBytes, NULL, GL_STREAM_DRAW); } glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); // we start with mapping the first buffer to the pixel data address space glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->PixelBufferID[0]); surface->PixelData[0] = (unsigned int*)glMapBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB ); memset(surface->PixelData[0], 0, surface->SizeInBytes); return surface; }
GLuint CompileShader(const DKString& implement, DKShader::Type t, DKString& err) { if (implement.Length() == 0) { err = L"No implementation."; return 0; } if (t != DKShader::TypeFragmentShader && t != DKShader::TypeGeometryShader && t != DKShader::TypeVertexShader) { err = L"Unknown shader type"; return 0; } DKStringU8 source(implement); if (source.Bytes() == 0) { err = L"Failed to convert source encoding (UTF-8)"; return 0; } GLuint hShader = 0; if (t == DKShader::TypeVertexShader) // vertex shader { hShader = glCreateShader(GL_VERTEX_SHADER); } else if (t == DKShader::TypeFragmentShader) // fragment shader (pixel shader) { hShader = glCreateShader(GL_FRAGMENT_SHADER); } else { #ifdef GL_GEOMETRY_SHADER hShader = glCreateShader(GL_GEOMETRY_SHADER); #else err = L"Geometry shader not supported in this implementation."; DKLog("Error: Geometry shader not supported in this implementation.\n"); return 0; #endif } if (hShader == 0) { err = L"Failed to create shader object"; return 0; } const char* src = (const char*)source; glShaderSource(hShader, 1, &src, NULL); glCompileShader(hShader); // retrieve compiler log int nLogLen = 0; glGetShaderiv(hShader, GL_INFO_LOG_LENGTH, &nLogLen); if (nLogLen > 1) { char *pLog = (char*)DKMemoryHeapAlloc(nLogLen); int nCharsWritten = 0; glGetShaderInfoLog(hShader, nLogLen, &nCharsWritten, pLog); err = pLog; DKMemoryHeapFree(pLog); } //////////////////////////////////////////////////////////////////////////////// // get compilation result. int result = 0; glGetShaderiv(hShader, GL_COMPILE_STATUS, &result); glFlush(); if (result) { return hShader; } // compile error. if (err.Length() == 0) err = L"Failed to compile shader."; glDeleteShader(hShader); return 0; }
Frustum::~Frustum() { glDeleteShader(shader_program_); }
bool initProgram() { bool Validated = true; GLint Success = 0; glGenProgramPipelines(1, &PipelineName); glBindProgramPipeline(PipelineName); glBindProgramPipeline(0); ProgramName[program::VERT] = glCreateProgram(); glProgramParameteri(ProgramName[program::VERT], GL_PROGRAM_SEPARABLE, GL_TRUE); glProgramParameteri(ProgramName[program::VERT], GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); { GLenum Format = 0; GLint Size = 0; std::vector<glm::byte> Data; if(glf::loadBinary(VERT_PROGRAM_BINARY, Format, Data, Size)) { glProgramBinary(ProgramName[program::VERT], Format, &Data[0], Size); glGetProgramiv(ProgramName[program::VERT], GL_LINK_STATUS, &Success); } } // Create program if(Validated && !Success) { GLuint VertShaderName = glf::createShader(GL_VERTEX_SHADER, VERT_SHADER_SOURCE); glAttachShader(ProgramName[program::VERT], VertShaderName); glDeleteShader(VertShaderName); glLinkProgram(ProgramName[program::VERT]); Validated = Validated && glf::checkProgram(ProgramName[program::VERT]); } ProgramName[program::FRAG] = glCreateProgram(); glProgramParameteri(ProgramName[program::FRAG], GL_PROGRAM_SEPARABLE, GL_TRUE); glProgramParameteri(ProgramName[program::FRAG], GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); { GLenum Format = 0; GLint Size = 0; std::vector<glm::byte> Data; if(glf::loadBinary(FRAG_PROGRAM_BINARY, Format, Data, Size)) { glProgramBinary(ProgramName[program::FRAG], Format, &Data[0], Size); glGetProgramiv(ProgramName[program::FRAG], GL_LINK_STATUS, &Success); } } // Create program if(Validated && !Success) { GLuint FragShaderName = glf::createShader(GL_FRAGMENT_SHADER, FRAG_SHADER_SOURCE); glAttachShader(ProgramName[program::FRAG], FragShaderName); glDeleteShader(FragShaderName); glLinkProgram(ProgramName[program::FRAG]); Validated = Validated && glf::checkProgram(ProgramName[program::FRAG]); } if(Validated) { glUseProgramStages(PipelineName, GL_VERTEX_SHADER_BIT, ProgramName[program::VERT]); glUseProgramStages(PipelineName, GL_FRAGMENT_SHADER_BIT, ProgramName[program::FRAG]); Validated = Validated && glf::checkError("initProgram - stage"); } // Get variables locations if(Validated) { UniformMVP = glGetUniformLocation(ProgramName[program::VERT], "MVP"); UniformDiffuse = glGetUniformLocation(ProgramName[program::FRAG], "Diffuse"); } return Validated && glf::checkError("initProgram"); }
GLuint Shader::LoadShaders(const char * vertex_file_path, const char * fragment_file_path){ // Create the shaders GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); // Read the Vertex Shader code from the file std::string VertexShaderCode; std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); if (VertexShaderStream.is_open()){ std::string Line = ""; while (getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } else{ printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path); getchar(); return 0; } // Read the Fragment Shader code from the file std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); if (FragmentShaderStream.is_open()){ std::string Line = ""; while (getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader printf("Compiling shader : %s\n", vertex_file_path); char const * VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); glCompileShader(VertexShaderID); // Check Vertex Shader glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0){ std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); printf("%s\n", &VertexShaderErrorMessage[0]); } // Compile Fragment Shader printf("Compiling shader : %s\n", fragment_file_path); char const * FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); glCompileShader(FragmentShaderID); // Check Fragment Shader glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0){ std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); printf("%s\n", &FragmentShaderErrorMessage[0]); } // Link the program printf("Linking program\n"); GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID, VertexShaderID); glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID); // Check the program glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0){ std::vector<char> ProgramErrorMessage(InfoLogLength + 1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); printf("%s\n", &ProgramErrorMessage[0]); } glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; }
Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath) { string vertexCode; string fragmentCode; ifstream vShaderFile; ifstream fShaderFile; vShaderFile.exceptions(ifstream::badbit); fShaderFile.exceptions(ifstream::badbit); try { vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); stringstream vShaderStream; stringstream fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); vShaderFile.close(); fShaderFile.close(); vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (ifstream::failure e) { cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << endl; } const GLchar* vShaderCode = vertexCode.c_str(); const GLchar* fShaderCode = fragmentCode.c_str(); GLuint vertex; GLuint fragment; GLint success; GLchar infoLog[512]; vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << endl; } fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << endl; } m_program = glCreateProgram(); glAttachShader(m_program, vertex); glAttachShader(m_program, fragment); glLinkProgram(m_program); glGetProgramiv(m_program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(m_program, 512, NULL, infoLog); cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << endl; } glDeleteShader(vertex); glDeleteShader(fragment); }
value deleteShader( value shader ) { glDeleteShader( (GLuint)val_int( shader ) ); return alloc_null( ); }
// call this to reset the ShaderObject (it can then be repurposed if you so desire) inline void ShaderObject::Cleanup() { shaderType = GLInvalidShader; if(shaderID) { glDeleteShader(shaderID); shaderID = 0; } hasCompiled = false; };
void ShaderManipulator::createShader(std::string path, GLuint *shaderProgram){ std::string vertexCode; std::string fragmentCode; std::string tcsCode; std::string tesCode; try { // Open files std::ifstream vShaderFile("C:/martinka/libs/vertex.vs"); std::ifstream fShaderFile("C:/martinka/libs/fragment.fs"); std::ifstream tcsShaderFile("C:/martinka/libs/tesselation_shader.tcs"); std::ifstream tesShaderFile("C:/martinka/libs/tesselation_shader.tes"); std::stringstream vShaderStream, fShaderStream,tcsShaderStream,tesShaderStream; // Read file's buffer contents into streams vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); tcsShaderStream << tcsShaderFile.rdbuf(); tesShaderStream << tesShaderFile.rdbuf(); // close file handlers vShaderFile.close(); fShaderFile.close(); tcsShaderFile.close(); tesShaderFile.close(); // Convert stream into GLchar array vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); tcsCode = tcsShaderStream.str(); tesCode = tesShaderStream.str(); } catch (std::exception e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; } const GLchar *vShaderCode = vertexCode.c_str(); const GLchar *fShaderCode = fragmentCode.c_str(); const GLchar *tcsShaderCode = tcsCode.c_str(); const GLchar *tesShaderCode = tesCode.c_str(); GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vShaderCode, NULL); glCompileShader(vertexShader); // Check for compile time errors GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } GLuint tcsShader = glCreateShader(GL_TESS_CONTROL_SHADER); glShaderSource(tcsShader, 1, &tcsShaderCode, NULL); glCompileShader(tcsShader); // Check for compile time errors glGetShaderiv(tcsShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(tcsShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } GLuint tesShader = glCreateShader(GL_TESS_EVALUATION_SHADER); glShaderSource(tesShader, 1, &tesShaderCode, NULL); glCompileShader(tesShader); // Check for compile time errors glGetShaderiv(tesShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(tesShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::TESS::EVALUATION::COMPILATION_FAILED\n" << infoLog << std::endl; } GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fShaderCode, NULL); glCompileShader(fragmentShader); // Check for compile time errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders *shaderProgram = glCreateProgram(); glAttachShader(*shaderProgram, vertexShader); glAttachShader(*shaderProgram, tcsShader); glAttachShader(*shaderProgram, tesShader); glAttachShader(*shaderProgram, fragmentShader); glLinkProgram(*shaderProgram); // Check for linking errors glGetProgramiv(*shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(*shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glDeleteShader(tcsShader); glDeleteShader(tesShader); }
bool PlatformContextGL2D::compileShaderInternal(GLuint* compiledShader, const GLchar* vertexShaderSource, const GLchar* fragmentShaderSource, ShaderVariable* variables) { GLuint shaderProgram = 0; GLuint vertexShader = 0; GLuint fragmentShader = 0; GLint intValue; ASSERT(!*compiledShader); // Shader programs are zero terminated vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &intValue); if (intValue != GL_TRUE) goto error; fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &intValue); if (intValue != GL_TRUE) goto error; shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &intValue); if (intValue != GL_TRUE) goto error; // According to the specification, the shaders are kept // around until the program object is freed (reference counted). glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glUseProgram(shaderProgram); while (variables->name) { ASSERT((variables->name[0] == 'u' || variables->name[0] == 'a') && variables->name[1] == '_'); if (variables->name[0] == 'u') { variables->location = glGetUniformLocation(shaderProgram, variables->name); } else { variables->location = glGetAttribLocation(shaderProgram, variables->name); glEnableVertexAttribArray(variables->location); } variables++; } glUseProgram(0); *compiledShader = shaderProgram; return true; error: if (vertexShader) glDeleteShader(vertexShader); if (fragmentShader) glDeleteShader(fragmentShader); if (shaderProgram) glDeleteProgram(shaderProgram); return false; }
void IconShader::DeleteShader(std::string name) { glDeleteShader(shaders[name]); shaders.erase(name); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL20_nglDeleteShader(JNIEnv *env, jclass clazz, jint shader, jlong function_pointer) { glDeleteShaderPROC glDeleteShader = (glDeleteShaderPROC)((intptr_t)function_pointer); glDeleteShader(shader); }