bool Shader::compile() { char buffer[1024]; // Vertex shader vertShaderHandle = glCreateShader(GL_VERTEX_SHADER); const GLchar* vs = vertSource.c_str(); const GLint vsLen = vertSource.length(); glShaderSource(vertShaderHandle, 1, &vs, &vsLen); glCompileShader(vertShaderHandle); // check vertex shader compile status if (!isShaderStatusGood(vertShaderHandle, GL_COMPILE_STATUS, buffer)) { anyErrors = true; return false; } // geometry shader geomShaderHandle = glCreateShader(GL_GEOMETRY_SHADER); const GLchar* gs = geomSource.c_str(); const GLint gsLen = geomSource.length(); glShaderSource(geomShaderHandle, 1, &gs, &gsLen); glCompileShader(geomShaderHandle); // check geometry shader compile status if (!isShaderStatusGood(geomShaderHandle, GL_COMPILE_STATUS, buffer)) { anyErrors = true; return false; } // fragment shader fragShaderHandle = glCreateShader(GL_FRAGMENT_SHADER); const GLchar* fs = fragSource.c_str(); const GLint fsLen = fragSource.length(); glShaderSource(fragShaderHandle, 1, &fs, &fsLen); glCompileShader(fragShaderHandle); // check vertex shader compile status if (!isShaderStatusGood(fragShaderHandle, GL_COMPILE_STATUS, buffer)) { anyErrors = true; return false; } // create and link full pipeline shaderProgHandle = glCreateProgram(); glAttachShader(shaderProgHandle, vertShaderHandle); if (typeFlags & GEOM_SHADER) { glAttachShader(shaderProgHandle, geomShaderHandle); } glAttachShader(shaderProgHandle, fragShaderHandle); glLinkProgram(shaderProgHandle); // remember that a call to glUseProgram will still need to be done // check program link status GLint status; glGetProgramiv(shaderProgHandle, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLint length; glGetProgramiv(shaderProgHandle, GL_INFO_LOG_LENGTH, &length); GLchar *info = new GLchar[length]; glGetProgramInfoLog(shaderProgHandle, length, NULL, info); std::cout << "glLinkProgram failed: \n" << info << std::endl; delete [] info; } //glDetachShader(shaderProgHandle, vertShaderHandle); //glDetachShader(shaderProgHandle, fragShaderHandle); //glDeleteShader(vertShaderHandle); //glDeleteShader(fragShaderHandle); compiled = true; return true; }
// Create a GLSL program object from vertex and fragment shader files GLuint Painter::init_shader(const char* vShaderFile, const char* fShaderFile, const char* outputAttributeName, const char* gShaderFile) { struct Shader { const char* filename; GLenum type; GLchar* source; }; std::vector<Shader> shaders = { { vShaderFile, GL_VERTEX_SHADER, NULL }, { fShaderFile, GL_FRAGMENT_SHADER, NULL } }; if(gShaderFile) { shaders.push_back({ gShaderFile, GL_GEOMETRY_SHADER, NULL }); } GLuint program = glCreateProgram(); for ( int i = 0; i < shaders.size(); ++i ) { Shader& s = shaders[i]; s.source = readShaderSource( s.filename ); if ( shaders[i].source == NULL ) { std::cerr << "Failed to read " << s.filename << std::endl; exit( EXIT_FAILURE ); } GLuint shader = glCreateShader( s.type ); glShaderSource( shader, 1, (const GLchar**) &s.source, NULL ); glCompileShader( shader ); GLint compiled; glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); if ( !compiled ) { std::cerr << s.filename << " failed to compile:" << std::endl; GLint logSize; glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize ); char* logMsg = new char[logSize]; glGetShaderInfoLog( shader, logSize, NULL, logMsg ); std::cerr << logMsg << std::endl; delete [] logMsg; exit( EXIT_FAILURE ); } delete [] s.source; glAttachShader( program, shader ); } /* Link output */ glBindFragDataLocation(program, 0, outputAttributeName); /* link and error check */ glLinkProgram(program); GLint linked; glGetProgramiv( program, GL_LINK_STATUS, &linked ); if ( !linked ) { std::cerr << "Shader program failed to link" << std::endl; GLint logSize; glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize); char* logMsg = new char[logSize]; glGetProgramInfoLog( program, logSize, NULL, logMsg ); std::cerr << logMsg << std::endl; delete [] logMsg; exit( EXIT_FAILURE ); } /* use program object */ glUseProgram(program); return program; }
//--------------------------------------------------------------------- void GLSLESProgramManagerCommon::extractUniforms(GLuint programObject, const GpuConstantDefinitionMap* vertexConstantDefs, const GpuConstantDefinitionMap* fragmentConstantDefs, GLUniformReferenceList& list, GLUniformBufferList& sharedList) { // Scan through the active uniforms and add them to the reference list GLint uniformCount = 0; GLint maxLength = 0; char* uniformName = NULL; #define uniformLength 200 OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength)); // If the max length of active uniforms is 0, then there are 0 active. // There won't be any to extract so we can return. if(maxLength == 0) return; uniformName = new char[maxLength + 1]; GLUniformReference newGLUniformReference; // Get the number of active uniforms OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &uniformCount)); // Loop over each of the active uniforms, and add them to the reference container // only do this for user defined uniforms, ignore built in gl state uniforms for (GLuint index = 0; index < (GLuint)uniformCount; index++) { GLint arraySize = 0; GLenum glType = GL_NONE; OGRE_CHECK_GL_ERROR(glGetActiveUniform(programObject, index, maxLength, NULL, &arraySize, &glType, uniformName)); // Don't add built in uniforms newGLUniformReference.mLocation = glGetUniformLocation(programObject, uniformName); if (newGLUniformReference.mLocation >= 0) { // User defined uniform found, add it to the reference list String paramName = String( uniformName ); // If the uniform name has a "[" in it then its an array element uniform. String::size_type arrayStart = paramName.find("["); if (arrayStart != String::npos) { // If not the first array element then skip it and continue to the next uniform if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; paramName = paramName.substr(0, arrayStart); } // Find out which params object this comes from bool foundSource = completeParamSource(paramName, vertexConstantDefs, fragmentConstantDefs, newGLUniformReference); // Only add this parameter if we found the source if (foundSource) { assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize && "GL doesn't agree with our array size!"); list.push_back(newGLUniformReference); } // Don't bother adding individual array params, they will be // picked up in the 'parent' parameter can copied all at once // anyway, individual indexes are only needed for lookup from // user params } // end if } // end for if( uniformName != NULL ) { delete[] uniformName; } #if OGRE_NO_GLES3_SUPPORT == 0 // Now deal with uniform blocks GLint blockCount = 0; OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_BLOCKS, &blockCount)); for (int index = 0; index < blockCount; index++) { OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockName(programObject, index, uniformLength, NULL, uniformName)); GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); GLint blockSize, blockBinding; OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize)); OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_BINDING, &blockBinding)); HardwareUniformBufferSharedPtr newUniformBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false, uniformName); GLES2HardwareUniformBuffer* hwGlBuffer = static_cast<GLES2HardwareUniformBuffer*>(newUniformBuffer.get()); hwGlBuffer->setGLBufferBinding(blockBinding); sharedList.push_back(newUniformBuffer); } #endif }
GLuint LoadShaders(const std::string &vertex_file_path,const std::string &fragment_file_path){ //std::cout << "load shaders" << std::endl; // 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.c_str(), std::ios::in); if (VertexShaderStream.is_open()){ std::string Line = ""; while(getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } else { std::cerr << "ERROR: cannot open " << vertex_file_path << std::endl; exit(0); } // Read the Fragment Shader code from the file std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path.c_str(), std::ios::in); if(FragmentShaderStream.is_open()){ std::string Line = ""; while(getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } else { std::cerr << "ERROR: cannot open " << vertex_file_path << std::endl; exit(0); } GLint Result = GL_FALSE; int InfoLogLength; // Compile Vertex Shader //std::cout << "Compiling shader : " << vertex_file_path << std::endl; 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]); std::cerr << "VERTEX SHADER ERROR: " << std::string(VertexShaderErrorMessage.begin(), VertexShaderErrorMessage.end()) << std::endl; } // Compile Fragment Shader //std::cout << "Compiling shader : " << fragment_file_path << std::endl; 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]); std::cerr << "FRAGMENT SHADER ERROR: " << std::string(FragmentShaderErrorMessage.begin(), FragmentShaderErrorMessage.end()) << std::endl; } // Link the program //std::cout << "Linking program" << std::endl; 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]); std::cerr << "SHADER PROGRAM ERROR: " << std::string(ProgramErrorMessage.begin(), ProgramErrorMessage.end()) << std::endl; } glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; }
int main(int argc, char *argv[]) { // testing GLint tempInt; GLboolean tempBool; void *tempPtr; SDL_Surface *screen; if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { printf("Unable to initialize SDL: %s\n", SDL_GetError()); return 1; } SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL ); if ( !screen ) { printf("Unable to set video mode: %s\n", SDL_GetError()); return 1; } glClearColor( 0, 0, 0, 0 ); glClear( GL_COLOR_BUFFER_BIT ); // Create a texture GLuint texture; glGenTextures( 1, &texture ); glBindTexture( GL_TEXTURE_2D, texture ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); GLubyte textureData[16*16*4]; for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8); } } glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData ); // Create a second texture GLuint texture2; glGenTextures( 1, &texture2 ); glBindTexture( GL_TEXTURE_2D, texture2 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); GLubyte texture2Data[] = { 0xff, 0, 0, 0xff, 0, 0xff, 0, 0xaa, 0, 0, 0xff, 0x55, 0x80, 0x90, 0x70, 0 }; glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2Data ); // BEGIN glewInit(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048); glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048); glRotatef(-30, 1, 1, 1); //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 }; //glLoadMatrixf(pm); glMatrixMode(GL_MODELVIEW); GLfloat matrixData[] = { -1, 0, 0, 0, 0, 0,-1, 0, 0, 1, 0, 0, 0, 0, 0, 1 }; glLoadMatrixf(matrixData); //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glActiveTexture(GL_TEXTURE0); glGetBooleanv(GL_VERTEX_ARRAY, &tempBool); assert(!tempBool); glEnableClientState(GL_VERTEX_ARRAY); glGetBooleanv(GL_VERTEX_ARRAY, &tempBool); assert(tempBool); GLuint arrayBuffer, elementBuffer; glGenBuffers(1, &arrayBuffer); glGenBuffers(1, &elementBuffer); GLubyte arrayData[] = { /* [0, 0, 0, 67] ==> 128 float [0, 0, 128, 67] ==> 256 float [0, 0, 0, 68] ==> 512 float [0, 0, 128, 68] ==> 1024 float [vertex x ] [vertex y ] [vertex z ] [nr] [texture u ] [texture v ] [lm u ] [lm v ] [color r,g,b,a ] */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 0 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 1 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 2 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 3 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 4 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, // 5 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 6 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 7 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 8 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 9 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 10 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 11 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 12 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 0, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 13 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 14 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 128, 67, 0, 0, 0, 0, 128, 128, 128, 128, // 15 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 128, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 0, 0, 128, 68, 0, 0, 128, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128 }; assert(sizeof(arrayData) == 1408); glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(arrayData), arrayData, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); GLushort elementData[] = { 1, 2, 0, 2, 3, 0, 5, 6, 4, 6, 7, 4, 9, 10, 8, 10, 11, 8, 13, 14, 12, 14, 15, 12 }; assert(sizeof(elementData) == 48); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elementData), elementData, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); // sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound glTexCoordPointer(2, GL_FLOAT, 32, (void*)16); glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build glTexCoordPointer(2, GL_SHORT, 32, (void*)24); glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup glNormalPointer(GL_BYTE, 32, (void*)12); glColorPointer(4, GL_UNSIGNED_BYTE, 32, (void*)28); glGetPointerv(GL_VERTEX_ARRAY_POINTER, &tempPtr); assert(tempPtr == (void *)0); glGetPointerv(GL_COLOR_ARRAY_POINTER, &tempPtr); assert(tempPtr == (void *)28); glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &tempPtr); assert(tempPtr == (void *)16); glGetIntegerv(GL_VERTEX_ARRAY_SIZE, &tempInt); assert(tempInt == 3); glGetIntegerv(GL_VERTEX_ARRAY_TYPE, &tempInt); assert(tempInt == GL_FLOAT); glGetIntegerv(GL_VERTEX_ARRAY_STRIDE, &tempInt); assert(tempInt == 32); glGetIntegerv(GL_COLOR_ARRAY_SIZE, &tempInt); assert(tempInt == 4); glGetIntegerv(GL_COLOR_ARRAY_TYPE, &tempInt); assert(tempInt == GL_UNSIGNED_BYTE); glGetIntegerv(GL_COLOR_ARRAY_STRIDE, &tempInt); assert(tempInt == 32); glGetIntegerv(GL_TEXTURE_COORD_ARRAY_SIZE, &tempInt); assert(tempInt == 2); glGetIntegerv(GL_TEXTURE_COORD_ARRAY_TYPE, &tempInt); assert(tempInt == GL_FLOAT); glGetIntegerv(GL_TEXTURE_COORD_ARRAY_STRIDE, &tempInt); assert(tempInt == 32); glGetBooleanv(GL_VERTEX_ARRAY, &tempBool); assert(tempBool); glBindTexture(GL_TEXTURE_2D, texture); // diffuse? glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); // lightmap? glActiveTexture(GL_TEXTURE0); GLint ok; const char *vertexShader = "uniform vec4 texgenscroll;\n" "void main(void)\n" "{\n" " gl_Position = ftransform();\n" " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n" "}\n"; const char *fragmentShader = "uniform vec4 colorparams;\n" "uniform sampler2D diffusemap, lightmap;\n" "void main(void)\n" "{\n" " vec4 diffuse = texture2D(diffusemap, gl_TexCoord[0].xy);\n" " vec4 lm = texture2D(lightmap, gl_TexCoord[1].xy);\n" " diffuse *= colorparams;\n" " gl_FragColor = diffuse * lm;\n" "}\n"; GLuint vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, &vertexShader, NULL); glCompileShader(vs); glGetShaderiv(vs, GL_COMPILE_STATUS, &ok); assert(ok); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, &fragmentShader, NULL); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &ok); assert(ok); GLuint program = glCreateProgram(); glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &ok); assert(ok); glUseProgram(program); GLint lightmapLocation = glGetUniformLocation(program, "lightmap"); assert(lightmapLocation >= 0); assert(lightmapLocation == glGetUniformLocation(program, "lightmap")); // must get identical ids glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &ok); assert(ok); assert(lightmapLocation != glGetUniformLocation(program, "lightmap")); // must NOT get identical ids, we re-linked! lightmapLocation = glGetUniformLocation(program, "lightmap"); assert(lightmapLocation == glGetUniformLocation(program, "lightmap")); // must get identical ids glUniform1i(lightmapLocation, 1); // sampler2D? Is it the texture unit? GLint diffusemapLocation = glGetUniformLocation(program, "diffusemap"); assert(diffusemapLocation >= 0); glUniform1i(diffusemapLocation, 0); GLint texgenscrollLocation = glGetUniformLocation(program, "texgenscroll"); assert(texgenscrollLocation >= 0); GLint colorparamsLocation = glGetUniformLocation(program, "colorparams"); assert(colorparamsLocation >= 0); GLfloat texgenscrollData[] = { 0, 0, 0, 0 }; glUniform4fv(texgenscrollLocation, 1, texgenscrollData); GLfloat colorparamsData[] = { 2, 2, 2, 1 }; glUniform4fv(colorparamsLocation, 1, colorparamsData); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)12); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*) 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)24); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)36); // END SDL_GL_SwapBuffers(); #if !EMSCRIPTEN SDL_Delay(1500); #endif SDL_Quit(); return 0; }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // source text for each shader. After the shader names, specify the number // of attributes, followed by the index and attribute name of each attribute GLuint gltLoadShaderPairWithAttributes(const char *szVertexProg, const char *szFragmentProg, ...) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Load them. If fail clean up and return null // Vertex Program if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); fprintf(stderr, "The shader at %s could ot be found.\n", szVertexProg); return (GLuint)NULL; } // Fragment Program if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); fprintf(stderr,"The shader at %s could not be found.\n", szFragmentProg); return (GLuint)NULL; } // Compile them both glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors in vertex shader glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetShaderInfoLog(hVertexShader, 1024, NULL, infoLog); fprintf(stderr, "The shader at %s failed to compile with the following error:\n%s\n", szVertexProg, infoLog); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Check for errors in fragment shader glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetShaderInfoLog(hFragmentShader, 1024, NULL, infoLog); fprintf(stderr, "The shader at %s failed to compile with the following error:\n%s\n", szFragmentProg, infoLog); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Create the final program object, and attach the shaders hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); // Now, we need to bind the attribute names to their specific locations // List of attributes va_list attributeList; va_start(attributeList, szFragmentProg); // Iterate over this argument list char *szNextArg; int iArgCount = va_arg(attributeList, int); // Number of attributes for(int i = 0; i < iArgCount; i++) { int index = va_arg(attributeList, int); szNextArg = va_arg(attributeList, char*); glBindAttribLocation(hReturn, index, szNextArg); } va_end(attributeList); // Attempt to link glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetProgramInfoLog(hReturn, 1024, NULL, infoLog); fprintf(stderr,"The programs %s and %s failed to link with the following errors:\n%s\n", szVertexProg, szFragmentProg, infoLog); glDeleteProgram(hReturn); return (GLuint)NULL; } // All done, return our ready to use shader program return hReturn; }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // source code text for each shader. Note, there is no support for // just loading say a vertex program... you have to do both. GLuint gltLoadShaderPairSrcWithAttributes(const char *szVertexSrc, const char *szFragmentSrc, ...) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Load them. gltLoadShaderSrc(szVertexSrc, hVertexShader); gltLoadShaderSrc(szFragmentSrc, hFragmentShader); // Compile them glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Link them - assuming it works... hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); // List of attributes va_list attributeList; va_start(attributeList, szFragmentSrc); char *szNextArg; int iArgCount = va_arg(attributeList, int); // Number of attributes for(int i = 0; i < iArgCount; i++) { int index = va_arg(attributeList, int); szNextArg = va_arg(attributeList, char*); glBindAttribLocation(hReturn, index, szNextArg); } va_end(attributeList); glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteProgram(hReturn); return (GLuint)NULL; } return hReturn; }
void InitializeOpenGL(int i, int p, GLuint pro) { #ifdef __APPLE__ printf("Testing the init \n"); #endif //LOGD("Initialization Started"); GLuint vertexShader; GLuint fragmentShader; #ifdef __APPLE__ printf("Test %d\n", GL_VERTEX_SHADER); #endif vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr); if(pro == 0){ programObject = glCreateProgram(); if(programObject == 0){ #ifdef __APPLE__ printf("Invalid program returned \n"); #else LOGD("Invalid program returned"); #endif } } else{ programObject = pro; } glAttachShader(programObject, vertexShader); glAttachShader(programObject, fragmentShader); glEnable(GL_DEPTH_TEST); glBindAttribLocation(programObject, 0, "vPosition"); glLinkProgram(programObject); glUseProgram(programObject); textCoordLoc = glGetAttribLocation (programObject, "texPosition" ); sampler = glGetUniformLocation(programObject, "s_texture" ); GLint linked; glGetProgramiv(programObject, GL_LINK_STATUS, &linked); if (!linked) { // printf("Error linking program:\n"); GLint infoLen = 0; glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { #ifdef __APPLE__ char* infoLog = (char*)malloc(sizeof(char)*infoLen); glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); printf("%s\n",infoLog); free(infoLog); #endif } glDeleteProgram(programObject); } else{ // printf("No linker error \n"); } glClearColor(1.0f, 1.0f, 0.0f, 1.0f); #ifdef __APPLE__ printf("Initialization Complete \n"); #else LOGD("Initialization Complete"); #endif }
int main () { GLFWwindow* window = NULL; const GLubyte* renderer; const GLubyte* version; GLuint shader_programme; GLuint vao; // // Start OpenGL using helper libraries // -------------------------------------------------------------------------- if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // change to 3.2 if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint (GLFW_SAMPLES, msaa); window = glfwCreateWindow (gl_width, gl_height, "Textured Mesh", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: opening OS window\n"); return 1; } glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); /* get version info */ renderer = glGetString (GL_RENDERER); /* get renderer string */ version = glGetString (GL_VERSION); /* version as a string */ printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); int point_count = 0; // // Set up vertex buffers and vertex array object // -------------------------------------------------------------------------- { GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals (we haven't used these yet) GLfloat* vt = NULL; // array of texture coordinates (or these) //assert (load_obj_file ("cube.obj", vp, vt, vn, point_count)); assert (load_obj_file ("monkey.obj", vp, vt, vn, point_count)); GLuint points_vbo, texcoord_vbo, normal_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vp, GL_STATIC_DRAW); glGenBuffers (1, &texcoord_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 2 * point_count, vt, GL_STATIC_DRAW); glGenBuffers (1, &normal_vbo); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 3 * point_count, vn, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (1); glBindBuffer (GL_ARRAY_BUFFER, texcoord_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (2); glBindBuffer (GL_ARRAY_BUFFER, normal_vbo); glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, NULL); free (vp); free (vn); free (vt); } // // Load shaders from files // -------------------------------------------------------------------------- { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("teapot.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("teapot.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (teapot.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glBindAttribLocation (shader_programme, 0, "vp"); glBindAttribLocation (shader_programme, 1, "vt"); glBindAttribLocation (shader_programme, 2, "vn"); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", shader_programme); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (shader_programme, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", shader_programme, log); } /* TODO NOTE: you should check for errors and print logs after compiling and also linking shaders */ } // // Create some matrices // -------------------------------------------------------------------------- mat4 M, V, P; M = identity_mat4 ();//scale (identity_mat4 (), vec3 (0.05, 0.05, 0.05)); vec3 cam_pos (0.0, 5.0, 5.0); vec3 targ_pos (0.0, 0.0, 0.0); vec3 up = normalise (vec3 (0.0, 1.0, -1.0)); V = look_at (cam_pos, targ_pos, up); P = perspective (67.0f, (float)gl_width / (float)gl_height, 0.1, 10.0); int M_loc = glGetUniformLocation (shader_programme, "M"); int V_loc = glGetUniformLocation (shader_programme, "V"); int P_loc = glGetUniformLocation (shader_programme, "P"); int ol_loc = glGetUniformLocation (shader_programme, "ol_mode"); int sm_loc = glGetUniformLocation (shader_programme, "sm_shaded"); // send matrix values to shader immediately glUseProgram (shader_programme); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniformMatrix4fv (V_loc, 1, GL_FALSE, V.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, P.m); glUniform1f (ol_loc, 0.0f); glUniform1f (sm_loc, 0.0f); // // Start rendering // -------------------------------------------------------------------------- // tell GL to only draw onto a pixel if the fragment is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glDepthFunc (GL_LESS); // depth-testing is to use a "less than" function glEnable (GL_CULL_FACE); // enable culling of faces glCullFace (GL_BACK); glFrontFace (GL_CCW); glClearColor (0.04, 0.04, 0.75, 1.0); bool multi_pass = true; GLuint fb, c_tex, d_tex;; { // fb glGenFramebuffers (1, &fb); glBindFramebuffer (GL_FRAMEBUFFER, fb); glGenTextures (1, &c_tex); glGenTextures (1, &d_tex); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, c_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, c_tex, 0); glBindTexture (GL_TEXTURE_2D, d_tex); glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gl_width, gl_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, d_tex, 0); glBindFramebuffer (GL_FRAMEBUFFER, 0); } GLuint quad_vao; { float quad_pts[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; GLuint quad_vbo; glGenBuffers (1, &quad_vbo); glGenVertexArrays (1, &quad_vao); glBindVertexArray (quad_vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, quad_vbo); glBufferData (GL_ARRAY_BUFFER, 8 * sizeof (float), quad_pts, GL_STATIC_DRAW); glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, NULL); } GLuint post_sp; { char* vertex_shader_str; char* fragment_shader_str; // allocate some memory to store shader strings vertex_shader_str = (char*)malloc (81920); fragment_shader_str = (char*)malloc (81920); // load shader strings from text files assert (parse_file_into_str ("post.vert", vertex_shader_str, 81920)); assert (parse_file_into_str ("post.frag", fragment_shader_str, 81920)); GLuint vs, fs; vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vertex_shader_str, NULL); glShaderSource (fs, 1, (const char**)&fragment_shader_str, NULL); // free memory free (vertex_shader_str); free (fragment_shader_str); int params = -1; glCompileShader (vs); glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.vert) did not compile\n", vs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (vs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } glCompileShader (fs); glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: GL shader index %i (post.frag) did not compile\n", fs); int max_length = 2048; int actual_length = 0; char log[2048]; glGetShaderInfoLog (fs, max_length, &actual_length, log); printf ("shader info log for GL index %u\n%s\n", vs, log); } post_sp = glCreateProgram (); glAttachShader (post_sp, fs); glAttachShader (post_sp, vs); glBindAttribLocation (post_sp, 0, "vp"); glLinkProgram (post_sp); glGetProgramiv (post_sp, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { printf ("ERROR: could not link shader programme GL index %u\n", post_sp); int max_length = 2048; int actual_length = 0; char log[2048]; glGetProgramInfoLog (post_sp, max_length, &actual_length, log); printf ("program info log for GL index %u\n%s\n", post_sp, log); } } double a = 0.0f; double prev = glfwGetTime (); while (!glfwWindowShouldClose (window)) { if (multi_pass) { glBindFramebuffer (GL_FRAMEBUFFER, fb); } glViewport (0, 0, gl_width, gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, 0); double curr = glfwGetTime (); double elapsed = curr - prev; prev = curr; glUseProgram (shader_programme); glBindVertexArray (vao); a += elapsed * 50.0f; //float ang = (float)sin (a); M = rotate_y_deg (identity_mat4 (), a); glUniformMatrix4fv (M_loc, 1, GL_FALSE, M.m); glUniform1f (sm_loc, 1.0f); // smooth shaded or not (exception is flat-shaded, they might not be great // if non-cube anyway due to scaling) if (!multi_pass) { glFrontFace (GL_CW); glUniform1f (ol_loc, 1.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); } glFrontFace (GL_CCW); glUniform1f (ol_loc, 0.0f); glDrawArrays (GL_TRIANGLES, 0, point_count); /* this just updates window events and keyboard input events (not used yet) */ if (multi_pass) { glFlush (); glFinish (); glBindFramebuffer (GL_FRAMEBUFFER, 0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, gl_width, gl_height); glUseProgram (post_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, d_tex); glBindVertexArray (quad_vao); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); } glfwPollEvents (); glfwSwapBuffers (window); } return 0; }
// The MAIN function, from here we start the application and run the game loop int main4() { // 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_CORE_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[] = { // Positions 0.5f, -0.5f, 0.0f, // Bottom Right -0.5f, -0.5f, 0.0f, // Bottom Left 0.0f, 0.5f, 0.0f // Top }; GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // 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); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); // Unbind VAO // 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); // Be sure to activate the shader glUseProgram(shaderProgram); // Update the uniform color GLfloat timeValue = glfwGetTime(); GLfloat greenValue = (sin(timeValue) / 2) + 0.5; GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor"); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); // Draw the triangle glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3); 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); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
////////////////////////////////////////////////////////////////////////// // loads only a vertex and pixel shader from text files unsigned int AIE::LoadShader(unsigned int a_uiInputAttributeCount, const char** a_aszInputAttributes, unsigned int a_uiOutputAttributeCount, const char** a_aszOutputAttributes, const char* a_szVertexShader, const char* a_szPixelShader, const char* a_szGeometryShader /* = nullptr */, const char* a_szTessellationControlShader /* = nullptr */, const char* a_szTessellationEvaluationShader /* = nullptr */) { GLint iSuccess; GLchar acLog[256]; // load files into char buffers char* vsSource = FileToBuffer(a_szVertexShader); char* fsSource = FileToBuffer(a_szPixelShader); char* gsSource = a_szGeometryShader == nullptr ? nullptr : FileToBuffer(a_szGeometryShader); char* tcsSource = a_szTessellationControlShader == nullptr ? nullptr : FileToBuffer(a_szTessellationControlShader); char* tesSource = a_szTessellationEvaluationShader == nullptr ? nullptr : FileToBuffer(a_szTessellationEvaluationShader); // must have vertex and pixel if (vsSource == nullptr || fsSource == nullptr) { return 0; } // create 2 shader handles GLuint vsHandle = glCreateShader(GL_VERTEX_SHADER); GLuint fsHandle = glCreateShader(GL_FRAGMENT_SHADER); GLuint gsHandle = 0; GLuint tcsHandle = 0; GLuint tesHandle = 0; // compile vertex shader and log errors glShaderSource(vsHandle, 1, (const char**)&vsSource, 0); glCompileShader(vsHandle); glGetShaderiv(vsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(vsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile vertex shader!\n"); printf(acLog); printf("\n"); return 0; } // compile pixel shader and log errors glShaderSource(fsHandle, 1, (const char**)&fsSource, 0); glCompileShader(fsHandle); glGetShaderiv(fsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(fsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile pixel shader!\n"); printf(acLog); printf("\n"); return 0; } if (gsSource != nullptr) { gsHandle = glCreateShader(GL_GEOMETRY_SHADER); // compile geometry shader and log errors glShaderSource(gsHandle, 1, (const char**)&gsSource, 0); glCompileShader(gsHandle); glGetShaderiv(gsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(gsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile geometry shader!\n"); printf(acLog); printf("\n"); return 0; } } if (tesSource != nullptr && tcsSource != nullptr) { tesHandle = glCreateShader(GL_TESS_EVALUATION_SHADER); tcsHandle = glCreateShader(GL_TESS_CONTROL_SHADER); // compile tessellation control shader and log errors glShaderSource(tcsHandle, 1, (const char**)&tcsSource, 0); glCompileShader(tcsHandle); glGetShaderiv(tcsHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(tcsHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile tessellation control shader!\n"); printf(acLog); printf("\n"); return 0; } // compile tessellation evaluation shader and log errors glShaderSource(tesHandle, 1, (const char**)&tesSource, 0); glCompileShader(tesHandle); glGetShaderiv(tesHandle, GL_COMPILE_STATUS, &iSuccess); glGetShaderInfoLog(tesHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to compile tessellation evaluation shader!\n"); printf(acLog); printf("\n"); return 0; } } // create a shader program and attach the shaders to it GLuint uiProgramHandle = glCreateProgram(); glAttachShader(uiProgramHandle, vsHandle); glAttachShader(uiProgramHandle, fsHandle); if (gsHandle != 0) glAttachShader(uiProgramHandle, gsHandle); if (tcsHandle != 0) glAttachShader(uiProgramHandle, tcsHandle); if (tesHandle != 0) glAttachShader(uiProgramHandle, tesHandle); // specify vertex input attributes for ( unsigned int i = 0 ; i < a_uiInputAttributeCount ; ++i ) glBindAttribLocation(uiProgramHandle, i, a_aszInputAttributes[i]); // specify pixel shader outputs for ( unsigned int i = 0 ; i < a_uiOutputAttributeCount ; ++i ) glBindFragDataLocation(uiProgramHandle, i, a_aszOutputAttributes[i]); // link the program together and log errors glLinkProgram(uiProgramHandle); glGetProgramiv(uiProgramHandle, GL_LINK_STATUS, &iSuccess); glGetProgramInfoLog(uiProgramHandle, sizeof(acLog), 0, acLog); if (iSuccess == GL_FALSE) { printf("Error: Failed to link shader program!\n"); printf(acLog); printf("\n"); return 0; } glUseProgram(uiProgramHandle); delete vsSource; delete fsSource; if (gsSource != nullptr) delete gsSource; if (tcsSource != nullptr) delete tcsSource; if (tesSource != nullptr) delete tesSource; return uiProgramHandle; }
// The MAIN function, from here we start the application and run the game loop int main() { std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl; // 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_CORE_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); std::string vertexshader = getFileContent("test_vs.glsl"); vertexShaderSource = (GLchar *) vertexshader.c_str(); std::string fragmentshader = getFileContent("test_fs.glsl"); fragmentShaderSource = (GLchar *) fragmentshader.c_str(); // Build and compile our shader program // Vertex shader GLint 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 GLint 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 GLint 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[] = { // // First triangle // 0.5f, 0.5f, // Top Right // 0.5f, -0.5f, // Bottom Right // -0.5f, 0.5f, // Top Left // // Second triangle // 0.5f, -0.5f, // Bottom Right // -0.5f, -0.5f, // Bottom Left // -0.5f, 0.5f // Top Left //}; GLfloat vertices[] = { 0.5f, 0.5f, 0.0f, // Top Right 0.5f, -0.5f, 0.0f, // Bottom Right -0.5f, -0.5f, 0.0f, // Bottom Left -0.5f, 0.5f, 0.0f, // Top Left -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; GLuint indices[] = { // Note that we start from 0! 0, 1, 3, // First Triangle 1, 2, 3, // Second Triangle 4, 5, 6 }; 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), remember: do NOT unbind the EBO, keep it bound to this VAO // Uncommenting this call will result in wireframe polygons. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //other option //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 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); glDrawArrays(GL_TRIANGLES, 0, 9); //glDrawElements(GL_TRIANGLES, 9, 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; }
/** * Create program and store shader handle in SdkEnv * Return: * 0 OK * -1 ERROR */ static int createProgram(SdkEnv *env, const char* vertexSource, const char* fragSource) { VALIDATE_NOT_NULL3(env, vertexSource, fragSource); // Make sure to reset them env->handle.program = 0; env->handle.vertShader = 0; env->handle.fragShader = 0; int program = 0; int vertShader = 0; int fragShader = 0; do { vertShader = loadShader(GL_VERTEX_SHADER, vertexSource); if (!vertShader) { LogE("Failed load vertex shader\n"); break; } fragShader = loadShader(GL_FRAGMENT_SHADER, fragSource); if (!fragShader) { LogE("Failed load fragment sahder\n"); break; } // Mark to delete, fre automaticlly when do not use any longer //glDeleteShader(vertShader); //glDeleteShader(fragShader); program = glCreateProgram(); if (!program) { LogE("Failed create program\n"); break; } glAttachShader(program, vertShader); glAttachShader(program, fragShader); glLinkProgram(program); GLint linkStatus = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); GLint len; if (!linkStatus) { memset(sLogBuff, 0, LOG_BUFF_SIZE); glGetProgramInfoLog(program, LOG_BUFF_SIZE, &len, sLogBuff); if (len > 0) { Log("link error log:%s\n", sLogBuff); } else { LogE("Failed get link log\n"); } break; } glValidateProgram (program); GLint success; glGetProgramiv (program, GL_VALIDATE_STATUS, &success); if (!success) { memset (sLogBuff, 0, LOG_BUFF_SIZE); glGetProgramInfoLog (program, LOG_BUFF_SIZE, &len, sLogBuff); if (len > 0) { Log("program is invalidate:%s\n", sLogBuff); } else { LogE("Failed get program status\n"); } break; } env->handle.program = program; env->handle.vertShader = vertShader; env->handle.fragShader = fragShader; return 0; } while (0); if (program) { glDeleteProgram(program); } if (vertShader) { glDeleteShader(vertShader); } if (fragShader) { glDeleteShader(fragShader); } return -1; }
Shader::Shader(const GLchar *vertexSourcePath, const GLchar * fragmentSourcePath){ std::string vertexCode; std::string fragmentCode; try { std::ifstream vShaderFile(vertexSourcePath); std::ifstream fShaderFile(fragmentSourcePath); std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); vShaderFile.close(); fShaderFile.close(); vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::exception e) { std::cout << "ERROR: READ SHADER FILE FAILED." << std::endl; } const GLchar *vShaderCode = vertexCode.c_str(); const GLchar *fShaderCode = fragmentCode.c_str(); GLuint vertex, 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); std::cout << "ERROR :SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::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); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } this->Program = glCreateProgram(); glAttachShader(this->Program, vertex); glAttachShader(this->Program, fragment); glLinkProgram(this->Program); 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; } glDeleteShader(vertex); glDeleteShader(fragment); }
CShader_GBuffer::CShader_GBuffer(std::string vs_path, std::string ps_path) { GLuint vsID = glCreateShader(GL_VERTEX_SHADER); GLuint psID = glCreateShader(GL_FRAGMENT_SHADER); std::string vsCode; std::ifstream vsStream(vs_path.c_str(), std::ios::in); if (vsStream.is_open()) { std::string line = ""; while (getline(vsStream, line)) { vsCode += "\n" + line; } vsStream.close(); } std::string psCode; std::ifstream psStream(ps_path.c_str(), std::ios::in); if (psStream.is_open()) { std::string line = ""; while (getline(psStream, line)) { psCode += "\n" + line; } psStream.close(); } GLint result = GL_FALSE; int logLength; // Compile vertex shader log(LOG_TYPE_DEFAULT, "Compiling Shader: " + vs_path + ".."); const char* vsPointer = vsCode.c_str(); glShaderSource(vsID, 1, &vsPointer, NULL); glCompileShader(vsID); // Check shader status glGetShaderiv(vsID, GL_COMPILE_STATUS, &result); if (!result) { glGetShaderiv(vsID, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> vsError(logLength); glGetShaderInfoLog(vsID, logLength, NULL, &vsError[0]); if (vsError.size() - 1 >= 0) { vsError[vsError.size() - 1] = '\0'; } log(LOG_TYPE_ERROR, std::string((char*)&vsError[0])); } // Compile pixel shader log(LOG_TYPE_DEFAULT, "Compiling Shader: " + ps_path + ".."); const char* psPointer = psCode.c_str(); glShaderSource(psID, 1, &psPointer, NULL); glCompileShader(psID); // Check shader status glGetShaderiv(psID, GL_COMPILE_STATUS, &result); if (!result) { glGetShaderiv(psID, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> psError(logLength); glGetShaderInfoLog(psID, logLength, NULL, &psError[0]); if (psError.size() - 1 >= 0) { psError[psError.size() - 1] = '\0'; } log(LOG_TYPE_ERROR, std::string((char*)&psError[0])); } // Link shader log(LOG_TYPE_DEFAULT, "Linking shader .."); GLuint shaderID = glCreateProgram(); glAttachShader(shaderID, vsID); glAttachShader(shaderID, psID); glLinkProgram(shaderID); // Check final shader glGetProgramiv(shaderID, GL_LINK_STATUS, &result); if (!result) { glGetProgramiv(shaderID, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> shaderError(logLength); glGetProgramInfoLog(shaderID, logLength, NULL, &shaderError[0]); if (shaderError.size() - 1 >= 0) { shaderError[shaderError.size() - 1] = '\0'; } log(LOG_TYPE_ERROR, std::string((char*)&shaderError[0])); } // Clean up glDeleteShader(vsID); glDeleteShader(psID); // Save the ID m_Id = shaderID; }
PIGLIT_GL_TEST_CONFIG_END void piglit_init(int argc, char **argv) { int i; GLuint prog; const char *source = "#extension GL_ARB_uniform_buffer_object : enable\n" "uniform a { float u1; };\n" "uniform b { float u2; };\n" "void main() {\n" " gl_FragColor = vec4(u1 + u2);\n" "}\n"; int blocks; int binding, max_bindings; bool pass = true; piglit_require_extension("GL_ARB_uniform_buffer_object"); prog = piglit_build_simple_program(NULL, source); glGetProgramiv(prog, GL_ACTIVE_UNIFORM_BLOCKS, &blocks); assert(blocks == 2); for (i = 0; i < blocks; i++) { glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_BINDING, &binding); if (binding != 0) { fprintf(stderr, "Linked program should have binding[%d] = %d, " "saw %d\n", i, 0, binding); pass = false; } } for (i = 0; i < blocks; i++) { glUniformBlockBinding(prog, i, blocks - i); } for (i = 0; i < blocks; i++) { glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_BINDING, &binding); if (binding != blocks - i) { fprintf(stderr, "Updated binding[%d] to %d, but got %d\n", i, blocks - i, binding); pass = false; } } glLinkProgram(prog); for (i = 0; i < blocks; i++) { glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_BINDING, &binding); if (binding != 0) { fprintf(stderr, "Relinked program should have binding[%d] = %d, " "saw %d\n", i, 0, binding); pass = false; } } glUniformBlockBinding(prog, blocks, 0); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_bindings); glUniformBlockBinding(prog, 0, max_bindings); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glUniformBlockBinding(0xd0d0, 0, 0); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glDeleteProgram(prog); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
Shader::Shader(const std::string &filepath, glm::vec2 viewport, GLenum culling, GLboolean colormask0, GLboolean colormask1, GLboolean colormask2, GLboolean colormask3, GLboolean depthmask, GLbitfield clear) { registred.push_back(this); this->culling = culling; this->colormask[0] = colormask0; this->colormask[1] = colormask1; this->colormask[2] = colormask2; this->colormask[3] = colormask3; this->depthmask = depthmask; this->clear = clear; this->viewport = viewport; std::string firstpath = g_System()->GetDataFile(filepath); std::string vertexsource, fragmentsource, geometrysource, libraries = "\n"; GLuint vertexshader, fragmentshader, geometryshader; int IsCompiled_VS, IsCompiled_FS, IsCompiled_GS; int IsLinked; vertexsource = filetobuf(firstpath + ".vert"); fragmentsource = filetobuf(firstpath + ".frag"); geometrysource = filetobuf(firstpath + ".geom"); std::vector<std::string> libs; g_System()->GetFilesInDirectory(libs, g_System()->GetDataFile("shaders")); for (auto &s : libs) { s = "shaders/" + s; if (endsWith(s, ".slib")) { std::string libsource = filetobuf(g_System()->GetDataFile(s)); if (libsource.length() == 0) continue; g_Console()->Info("Shader library loaded " + s); libraries += libsource + "\n"; } } vertexsource = libraries + vertexsource; fragmentsource = libraries + fragmentsource; if (geometrysource.length() > 0) geometrysource = libraries + geometrysource; vertexshader = glCreateShader(GL_VERTEX_SHADER); const GLchar* ptr = vertexsource.c_str(); glShaderSource(vertexshader, 1, (const GLchar **)&ptr, 0); glCompileShader(vertexshader); glGetShaderiv(vertexshader, GL_COMPILE_STATUS, &IsCompiled_VS); if (IsCompiled_VS == GL_FALSE) { logShader(vertexshader); return; } fragmentshader = glCreateShader(GL_FRAGMENT_SHADER); ptr = fragmentsource.c_str(); glShaderSource(fragmentshader, 1, (const GLchar **)&ptr, 0); glCompileShader(fragmentshader); glGetShaderiv(fragmentshader, GL_COMPILE_STATUS, &IsCompiled_FS); if (IsCompiled_FS == GL_FALSE) { logShader(fragmentshader); return; } if (geometrysource.length() > 0) { geometryshader = glCreateShader(GL_GEOMETRY_SHADER); ptr = geometrysource.c_str(); glShaderSource(geometryshader, 1, (const GLchar **)&ptr, 0); glCompileShader(geometryshader); glGetShaderiv(geometryshader, GL_COMPILE_STATUS, &IsCompiled_GS); if (IsCompiled_GS == GL_FALSE) { logShader(geometryshader); return; } } id = glCreateProgram(); glAttachShader(id, vertexshader); glAttachShader(id, fragmentshader); if (geometrysource.length() > 0) glAttachShader(id, geometryshader); glLinkProgram(id); glGetProgramiv(id, GL_LINK_STATUS, (int *)&IsLinked); if (IsLinked == GL_FALSE) { logProgram(id); id = 0; return; } g_Console()->Info("Shader loaded " + filepath); }
void openglCompute(){ //Note: Compute shaders are only OpenGL 4.3+ so my laptop can't run this, since //it's on 4.0 Window::init(); Window window("OpenGL Compute - Nothing will be drawn"); //This shader declares local group size to be 16x16 then does nothing const char *doNothingSrc = "#version 430 core \n \ //Input layout qualifier declaring a 16x16 local workgroup size \n \ //It looks like a big bonus for Opencl is being able to set this at runtime \ //Whereas in OpenGL compute shader it must be in the shader, although I suppose we could \ //change that somehow? hm \ layout (local_size_x = 16, local_size_y = 1) in; \n \ void main() { }"; std::string src = Util::readFile("../res/helloCompute.glsl"); const char *shaderSrc = src.c_str(); GLuint shader = glCreateShader(GL_COMPUTE_SHADER); glShaderSource(shader, 1, &shaderSrc, NULL); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE){ std::cout << "Compile failed" << std::endl; //Get the log length and then get the log GLint logLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); std::vector<char> log(logLength); glGetShaderInfoLog(shader, logLength, NULL, &log[0]); //Construct and return log message std::string errorMsg(log.begin(), log.end()); std::cout << errorMsg << std::endl; } GLuint program = glCreateProgram(); glAttachShader(program, shader); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if (status != GL_TRUE) std::cout << "Link failed" << std::endl; glDeleteShader(shader); glUseProgram(program); //Setup the data buffer GLuint dataBuf; glGenBuffers(1, &dataBuf); glBindBuffer(GL_SHADER_STORAGE_BUFFER, dataBuf); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 16, NULL, GL_DYNAMIC_COPY); //Bind it as the 0th shader storage buffer binding pt glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, dataBuf); GLuint globalDim[] = { 16, 1, 1 }; GLuint dispatchBuf; glGenBuffers(1, &dispatchBuf); glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, dispatchBuf); glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(globalDim), globalDim, GL_STATIC_DRAW); glDispatchComputeIndirect(0); Util::checkError("Dispatched compute"); int *outData = (int*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); std::cout << "Data read: "; for (int i = 0; i < 16; ++i) std::cout << outData[i] << ", "; std::cout << std::endl; glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); outData = nullptr; //cleanup glDeleteBuffers(1, &dataBuf); glDeleteBuffers(1, &dispatchBuf); glDeleteProgram(program); }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // file path for each shader. Note, there is no support for // just loading say a vertex program... you have to do both. GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Load them. If fail clean up and return null if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Compile them glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Link them - assuming it works... hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteProgram(hReturn); return (GLuint)NULL; } return hReturn; }
GLint ShadedObject::getProgramParam(GLint param) { GLint ret; glGetProgramiv(_programID, param, &ret); return ret; }
///////////////////////////////////////////////////////////////// // Check for any GL errors that may affect rendering // Check the framebuffer, the shader, and general errors bool gltCheckErrors(GLuint progName) { bool bFoundError = false; GLenum error = glGetError(); if (error != GL_NO_ERROR) { fprintf(stderr, "A GL Error has occured\n"); bFoundError = true; } #ifndef OPENGL_ES GLenum fboStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if(fboStatus != GL_FRAMEBUFFER_COMPLETE) { bFoundError = true; fprintf(stderr,"The framebuffer is not complete - "); switch (fboStatus) { case GL_FRAMEBUFFER_UNDEFINED: // Oops, no window exists? fprintf(stderr, "GL_FRAMEBUFFER_UNDEFINED\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: // Check the status of each attachment fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: // Attach at least one buffer to the FBO fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: // Check that all attachments enabled via // glDrawBuffers exist in FBO fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: // Check that the buffer specified via // glReadBuffer exists in FBO fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n"); break; case GL_FRAMEBUFFER_UNSUPPORTED: // Reconsider formats used for attached buffers fprintf(stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: // Make sure the number of samples for each // attachment is the same fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: // Make sure the number of layers for each // attachment is the same fprintf(stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n"); break; } } #endif if (progName != 0) { glValidateProgram(progName); int iIsProgValid = 0; glGetProgramiv(progName, GL_VALIDATE_STATUS, &iIsProgValid); if(iIsProgValid == 0) { bFoundError = true; fprintf(stderr, "The current program(%d) is not valid\n", progName); } } return bFoundError; }
bool Model::init(const char* fileName, const aiScene* scene){ //save our number of vertices so we know how many to draw later numVertices = vertices.size(); //set up where geometry lives for GL to draw glGenBuffers(1, &vbo_geometry); glBindBuffer(GL_ARRAY_BUFFER, vbo_geometry); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); // --Geometry Done //setup textures initMaterials(fileName, scene); //mesh if our file name, scene is our aiScene //set up our shaders GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); //Shader Sources // --Shader loader completed, returns string with the shader file // Note the added uniform! std::string tempString1 = shaderLoader("assets/shaders/vertex-shader"); const char *vs = tempString1.c_str(); std::string tempString2 = shaderLoader("assets/shaders/fragment-shader"); const char *fs = tempString2.c_str(); //compile the shaders GLint shader_status; // Vertex shader first glShaderSource(vertex_shader, 1, &vs, NULL); glCompileShader(vertex_shader); //check the compile status glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_status); if(!shader_status) { std::cerr << "[F] FAILED TO COMPILE VERTEX SHADER!" << std::endl; return false; } // Now the Fragment shader glShaderSource(fragment_shader, 1, &fs, NULL); glCompileShader(fragment_shader); //check the compile status glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status); if(!shader_status) { std::cerr << "[F] FAILED TO COMPILE FRAGMENT SHADER!" << std::endl; return false; } //Now we link the 2 shader objects into a program //This program is what is run on the GPU program = glCreateProgram(); glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glLinkProgram(program); //check if everything linked ok glGetProgramiv(program, GL_LINK_STATUS, &shader_status); if(!shader_status) { std::cerr << "[F] THE SHADER PROGRAM FAILED TO LINK" << std::endl; return false; } //Now we set the locations of the attributes and uniforms //this allows us to access them easily while rendering loc_position = glGetAttribLocation(program, const_cast<const char*>("v_position")); if(loc_position == -1) { std::cerr << "[F] POSITION NOT FOUND" << std::endl; return false; } loc_color = glGetAttribLocation(program, const_cast<const char*>("v_color")); if(loc_color == -1) { std::cerr << "[F] V_COLOR NOT FOUND" << std::endl; return false; } //add textures loc_texture = glGetAttribLocation(program, const_cast<const char*>("texcoord")); if(loc_texture == -1) { std::cerr << "[F] texcoord NOT FOUND" << std::endl; return false; } loc_mvpmat = glGetUniformLocation(program, const_cast<const char*>("mvpMatrix")); if(loc_mvpmat == -1) { std::cerr << "[F] MVPMATRIX NOT FOUND" << std::endl; return false; } return true; }
int JNICALL Java_com_gomdev_gles_GLESShader_nRetrieveProgramBinary (JNIEnv * env, jobject obj, jint program, jstring str) { GLint binaryLength; GLvoid* binary; FILE* outfile; GLenum binaryFormat; const char* fileName = env->GetStringUTFChars(str, NULL); if(fileName != NULL) { glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &binaryLength); checkGLError("retrieve() glGetProgramiv"); #ifdef DEBUG LOGI("retrieve() binaryLength=%d", binaryLength); #endif binary = (GLvoid*)malloc(binaryLength); if(binary == NULL) { LOGE("nRetrieveProgramBinary() malloc fail"); } // if (glGetProgramBinaryOES == NULL) { // glGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) eglGetProcAddress("glGetProgramBinaryOES"); // } glGetProgramBinary(program, binaryLength, NULL, &binaryFormat, binary); checkGLError("retrieve() glGetProgramBinaryOES"); outfile = fopen(fileName, "wb"); if(outfile == NULL) { LOGE("nRetrieveProgramBinary() fileName=%s", fileName); LOGE("nRetrieveProgramBinary() fopen error"); free(binary); return 0; } fwrite(binary, binaryLength, 1, outfile); fclose(outfile); // if binary is already cached, remove cached binary char* name = copyFileName(fileName); BinaryInfo* info = find(name); if (info != NULL) { removeBinaryFromList(info, true); } BinaryInfo* binaryInfo = (BinaryInfo*)malloc(sizeof(BinaryInfo)); if (binaryInfo != NULL ) { binaryInfo->name = name; binaryInfo->length = binaryLength; binaryInfo->binary = binary; add(binaryInfo); } env->ReleaseStringUTFChars(str, fileName); } sBinaryFormat = binaryFormat; return binaryFormat; }
GLuint shaderSetup( const char *vert, const char *frag ) { GLchar *vsrc = NULL, *fsrc = NULL; GLuint vs, fs, prog; GLint flag; // Assume that everything will work shaderErrorCode = E_NO_ERROR; // Create the shader handles vs = glCreateShader( GL_VERTEX_SHADER ); fs = glCreateShader( GL_FRAGMENT_SHADER ); // Read in shader source vsrc = read_text_file( vert ); if( vsrc == NULL ) { fprintf( stderr, "Error reading vertex shader file %s\n", vert); shaderErrorCode = E_VS_LOAD; return( 0 ); } fsrc = read_text_file( frag ); if( fsrc == NULL ) { fprintf( stderr, "Error reading fragment shader file %s\n", frag); shaderErrorCode = E_FS_LOAD; #ifdef __cplusplus delete [] vsrc; #else free( vsrc ); #endif return( 0 ); } // Attach the source to the shaders glShaderSource( vs, 1, (const GLchar **) &vsrc, NULL ); glShaderSource( fs, 1, (const GLchar **) &fsrc, NULL ); // We're done with the source code now #ifdef __cplusplus delete [] vsrc; delete [] fsrc; #else free(vsrc); free(fsrc); #endif // Compile the shaders, and print any relevant message logs glCompileShader( vs ); glGetShaderiv( vs, GL_COMPILE_STATUS, &flag ); print_shader_info_log( vs ); if( flag == GL_FALSE ) { shaderErrorCode = E_VS_COMPILE; return( 0 ); } glCompileShader( fs ); glGetShaderiv( fs, GL_COMPILE_STATUS, &flag ); print_shader_info_log( fs ); if( flag == GL_FALSE ) { shaderErrorCode = E_FS_COMPILE; return( 0 ); } // Create the program and attach the shaders prog = glCreateProgram(); glAttachShader( prog, vs ); glAttachShader( prog, fs ); // Report any message log information print_program_info_log( prog ); // Link the program, and print any message log information glLinkProgram( prog ); glGetProgramiv( prog, GL_LINK_STATUS, &flag ); print_program_info_log( prog ); if( flag == GL_FALSE ) { shaderErrorCode = E_SHADER_LINK; return( 0 ); } return( prog ); }
// Reads, compiles, links and returns a shader from the given paths GLuint loadShader(const std::string &vertexPath, const std::string &fragmentPath) { cout << "Loading shader program with shaders:" << endl; cout << " Vertex: " << std::filesystem::canonical(vertexPath) << endl; cout << " Fragment: " << std::filesystem::canonical(fragmentPath) << endl; // Read our shaders into the appropriate buffers std::ifstream vs_file(vertexPath); std::string vertexSource{ std::istreambuf_iterator<char>(vs_file), std::istreambuf_iterator<char>() }; std::ifstream fs_file(fragmentPath); std::string fragmentSource{ std::istreambuf_iterator<char>(fs_file), std::istreambuf_iterator<char>() }; #if 0 DIR* vertFile = opendir(vertexPath.c_str()); if (vertFile == nullptr) { glutil::fatal_error("Vertex file not found."); } DIR* fragFile = opendir(fragmentPath.c_str()); if (fragFile == nullptr) { glutil::fatal_error("Fragment file not found."); } #endif // 0 #if 1 const char *vs = vertexSource.c_str(); const char *fs = fragmentSource.c_str(); cout << "Vertex shader:" << endl << vs << endl << endl << "Fragment shader:" << endl << fs << endl; #endif // 0 // Create an empty vertex shader handle GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); // Send the vertex shader source code to GL // Note that std::string's .c_str is NULL character terminated. const GLchar *source = (const GLchar *)vertexSource.c_str(); glShaderSource(vertexShader, 1, &source, NULL); // Compile the vertex shader glCompileShader(vertexShader); GLint isCompiled = 0; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); if (isCompiled == GL_FALSE) { GLint maxLength = 0; glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); // We don't need the shader anymore. glDeleteShader(vertexShader); // Time to use the infoLog. for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; // In this simple program, we'll just leave return -1; } // Create an empty fragment shader handle GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Send the fragment shader source code to GL // Note that std::string's .c_str is NULL character terminated. source = (const GLchar *)fragmentSource.c_str(); glShaderSource(fragmentShader, 1, &source, NULL); // Compile the fragment shader glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); if (isCompiled == GL_FALSE) { GLint maxLength = 0; glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); // We don't need the shader anymore. glDeleteShader(fragmentShader); // Either of them. Don't leak shaders. glDeleteShader(vertexShader); // Time to use the infoLog. for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; // In this simple program, we'll just leave return -1; } // Vertex and fragment shaders are successfully compiled. // Now time to link them together into a program. // Get a program object. GLuint program = glCreateProgram(); // Attach our shaders to our program glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); // Link our program glLinkProgram(program); // Note the different functions here: glGetProgram* instead of glGetShader*. GLint isLinked = 0; glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked); if (isLinked == GL_FALSE) { GLint maxLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); // We don't need the program anymore. glDeleteProgram(program); // Don't leak shaders either. glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Time to use the infoLog. for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; // In this simple program, we'll just leave return -1; } GLint maxLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); if (maxLength > 0) { // The maxLength includes the NULL character std::vector<GLchar> infoLog(maxLength); glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); for (unsigned int i = 0; i < infoLog.size(); i++) { std::cerr << infoLog[i]; } std::cerr << endl; } // Detach shaders after a successful link. glDetachShader(program, vertexShader); glDetachShader(program, fragmentShader); cout << "Shader loaded." << endl; return program; }
bool COGLES2SLMaterialRenderer::linkProgram() { glLinkProgram( Program ); int status = 0; glGetProgramiv( Program, GL_LINK_STATUS, &status ); if ( !status ) { os::Printer::log( "GLSL shader program failed to link", ELL_ERROR ); // check error message and log it int maxLength = 0; GLsizei length; glGetProgramiv( Program, GL_INFO_LOG_LENGTH, &maxLength ); char *pInfoLog = new char[maxLength]; glGetProgramInfoLog( Program, maxLength, &length, pInfoLog ); os::Printer::log( reinterpret_cast<const c8*>( pInfoLog ), ELL_ERROR ); delete [] pInfoLog; return false; } // get uniforms information int num = 0; glGetProgramiv( Program, GL_ACTIVE_UNIFORMS, &num ); int maxlen = 0; glGetProgramiv( Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen ); if ( maxlen == 0 && num != 0 ) { os::Printer::log( "GLSL: failed to retrieve uniform information", ELL_ERROR ); return false; } c8 *buf = new c8[maxlen]; UniformInfo.clear(); UniformInfo.reallocate( num ); core::array<core::stringc> names( num ); core::array<SUniformInfo> uni( num ); for ( int i = 0; i < num; ++i ) { memset( buf, 0, maxlen ); GLint size; SUniformInfo ui; glGetActiveUniform( Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<char*>( buf ) ); ui.location = glGetUniformLocation( Program, buf ); uni.push_back( ui ); names.push_back( buf ); } delete [] buf; for ( int i = 0; i < UniformCount; ++i ) { int j; for ( j = 0; j < num; ++j ) { if ( names[j] == UniformStringTable[i] ) break; } if ( j < num ) { UniformInfo.push_back( uni[j] ); } else { wchar_t buf[512]; swprintf( buf, 512, L"Unable to find uniform : %S", UniformStringTable[i] ); os::Printer::log( buf, ELL_WARNING ); SUniformInfo blank; blank.location = -1; blank.type = GL_INVALID_ENUM; UniformInfo.push_back( blank ); } } return true; }
static unsigned int setup_shader(const char *vertex_shader, const char *fragment_shader) { GLuint vs=glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, (const GLchar**)&vertex_shader, nullptr); glCompileShader(vs); int status, maxLength; char *infoLog=nullptr; glGetShaderiv(vs, GL_COMPILE_STATUS, &status); if(status==GL_FALSE) { glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength); /* The maxLength includes the NULL character */ infoLog = new char[maxLength]; glGetShaderInfoLog(vs, maxLength, &maxLength, infoLog); fprintf(stderr, "Vertex Shader Error: %s\n", infoLog); /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ /* In this simple program, we'll just leave */ delete [] infoLog; return 0; } GLuint fs=glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, (const GLchar**)&fragment_shader, nullptr); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &status); if(status==GL_FALSE) { glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength); /* The maxLength includes the NULL character */ infoLog = new char[maxLength]; glGetShaderInfoLog(fs, maxLength, &maxLength, infoLog); fprintf(stderr, "Fragment Shader Error: %s\n", infoLog); /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ /* In this simple program, we'll just leave */ delete [] infoLog; return 0; } unsigned int program=glCreateProgram(); // Attach our shaders to our program glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); if(status==GL_FALSE) { glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); /* The maxLength includes the NULL character */ infoLog = new char[maxLength]; glGetProgramInfoLog(program, maxLength, NULL, infoLog); glGetProgramInfoLog(program, maxLength, &maxLength, infoLog); fprintf(stderr, "Link Error: %s\n", infoLog); /* Handle the error in an appropriate way such as displaying a message or writing to a log file. */ /* In this simple program, we'll just leave */ delete [] infoLog; return 0; } return program; }
GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShader) { // generate objects GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); GLuint programID = glCreateProgram(); // compile vertex shader glShaderSource(vertexShaderID, 1, &vertexShader, NULL); glCompileShader(vertexShaderID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) GLint Result = GL_FALSE; char stringBuffer[1024]; GLsizei stringBufferUsage = 0; glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderInfoLog(vertexShaderID, 1024, &stringBufferUsage, stringBuffer); if(Result && stringBufferUsage) { // not nice } else if(!Result) { // not nice } else { // not nice } bool shader_errors = !Result; #endif // compile fragment shader glShaderSource(fragmentShaderID, 1, &fragmentShader, NULL); glCompileShader(fragmentShaderID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderInfoLog(fragmentShaderID, 1024, &stringBufferUsage, stringBuffer); if(Result && stringBufferUsage) { // not nice } else if(!Result) { // not nice } else { // not nice } shader_errors |= !Result; #endif // link them glAttachShader(programID, vertexShaderID); glAttachShader(programID, fragmentShaderID); glLinkProgram(programID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) glGetProgramiv(programID, GL_LINK_STATUS, &Result); glGetProgramInfoLog(programID, 1024, &stringBufferUsage, stringBuffer); if(Result && stringBufferUsage) { // not nice } else if(!Result && !shader_errors) { // not nice } #endif // cleanup glDeleteShader(vertexShaderID); glDeleteShader(fragmentShaderID); return programID; }
// // Initialise les shader & program object // bool EsgiShader::Create() { // Cree le program object m_ProgramObject = glCreateProgram(); if (m_ProgramObject == 0) { return false; } if (m_VertexShader) { glAttachShader(m_ProgramObject, m_VertexShader); } if (m_FragmentShader) { glAttachShader(m_ProgramObject, m_FragmentShader); } #ifdef GL_GEOMETRY_SHADER if (m_GeometryShader) { glAttachShader(m_ProgramObject, m_GeometryShader); } #endif // callback permettant d'effectuer des operations avant le linkage if (m_PreLinkCallback) { m_PreLinkCallback(); } // Liage des shaders dans le programme glLinkProgram(m_ProgramObject); GLint linked = 0; GLint infoLen = 0; // verification du statut du linkage glGetProgramiv(m_ProgramObject, GL_LINK_STATUS, &linked); if (!linked) { glGetProgramiv(m_ProgramObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen); glGetProgramInfoLog(m_ProgramObject, infoLen, NULL, infoLog); GL_PRINT("Erreur de lien du programme:\n%s\n", infoLog); free(infoLog); } glDeleteProgram(m_ProgramObject); return false; } #if defined(_DEBUG) || defined(DEBUG) // ne pas utiliser glValidateProgram() au runtime. // techniquement il faudrait appeler glValidateProgram() dans le contexte // d'utilisation du shader et non a sa creation pour verifier que toutes les // conditions d'execution sont bien remplies glValidateProgram(m_ProgramObject); glGetProgramiv(m_ProgramObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char* infoLog = (char *)malloc(sizeof(char) * infoLen); glGetProgramInfoLog(m_ProgramObject, infoLen, NULL, infoLog); GL_PRINT("Resultat de la validation du programme:\n%s\n", infoLog); free(infoLog); } #endif return true; }
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_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Assignment1", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to created GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, key_callback); glewExperimental = GL_TRUE; glewInit(); if (glewInit() != GLEW_OK) { std::cout << "Failed to initialized GLEW" << std::endl; return -1; } int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); glEnable(GL_DEPTH_TEST); GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); 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); GLfloat vertices[] = { 0.5f, 0.5f, 0.5f, //0 0.5f, -0.5f, 0.5f, //1 -0.5f, 0.5f, 0.5f, //2 -0.5f, -0.5f, 0.5f, //3 0.5f, 0.5f, -0.5f, //4 0.5f, -0.5f, -0.5f, //5 -0.5f, 0.5f, -0.5f,//6 -0.5f, -0.5f, -0.5f,//7 }; GLuint indices[] = { 0, 1, 2, //front 2, 1, 3, 0, 4, 5, //right 1, 0, 5, 4, 5, 7, //back 4, 7, 6, 2, 3, 6, //left 3, 6, 7, 0, 2, 4, //top 2, 4, 6, 1, 5, 7, //bottom 1, 7, 3, }; 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), remember: do NOT unbind the EBO, keep it bound to this VAO projection = glm::perspective(45.0f, 1.0f, 0.1f, 20.0f); view = glm::lookAt(glm::vec3(0, 10, zoom), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); //model2 = glm::translate(model2, glm::vec3(3, 0, 4)); //model2 = glm::mat4(); // Uncommenting this call will result in wireframe polygons. //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Game loop // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); while (!glfwWindowShouldClose(window)) { // Render glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glBindVertexArray(VAO); // Draw our first triangle glUseProgram(shaderProgram); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &(projection)[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, &(view)[0][0]); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &(model1)[0][0]); //blue glUniform4fv(glGetUniformLocation(shaderProgram, "myColor"), 1, &(glm::vec4(0, 0, 1, 1))[0]); //glDrawArrays(GL_TRIANGLES, 0, 6); if (!points) { glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); } if (points) { glDrawElements(GL_POINTS, 36, GL_UNSIGNED_INT,0); glEnable(GL_PROGRAM_POINT_SIZE); glPointSize(5.0); } glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &(model2)[0][0]); //red glUniform4fv(glGetUniformLocation(shaderProgram, "myColor"), 1, &(glm::vec4(1, 0, 0, 1))[0]); if (!points) { glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); } if (points) { glDrawElements(GL_POINTS, 36, GL_UNSIGNED_INT, 0); glEnable(GL_PROGRAM_POINT_SIZE); glPointSize(5.0); } glBindVertexArray(0); if(lines){ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } if (fill) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // Swap the screen buffers glfwSwapBuffers(window); // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); model1 = glm::rotate(model1, 0.001f, glm::vec3(0, 1, 0)); glm::mat3 conv; ang -= 0.001f; conv[0] = glm::vec3(cos(ang), 0 , sin(ang)); conv[1] = glm::vec3(0,1,0); conv[2] = glm::vec3(-sin(ang), 0, cos(ang)); glm::vec3 rotVec = glm::vec3(3, 0, 4); rotVec = conv * rotVec; //model2 = glm::translate(glm::scale(glm::mat4(), model2[0][0] * glm::vec3(1,1,1)), rotVec); model2 = glm::scale(glm::translate(glm::mat4() , rotVec), glm::vec3(redB, redB, redB)); //model2 = glm::translate(model2); view = glm::lookAt(glm::vec3(0, zoom, 10), glm::vec3(0, 0, 0), glm::vec3(0, up, 0)); //model2 = glm::scale(glm::translate(glm::mat4(), glm::vec3(-sin(ang), 0, cos(ang))),glm::vec3(redB,redB,redB)); //model2 = glm::rotate(model2, 0.001f, glm::vec3(0, 1, 0)); //model1 = glm::rotate(model1, 0.001f, glm::vec3(0, 1, 0)); //model2 = glm::translate(model2, rotVec); //model2 = glm::rotate(model2, 0.001f, glm::vec3(0, 1, 0)); //model2 = glm::translate(model2, glm::vec3(3, 0, 4)); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glfwTerminate(); return 0; }