FBO::FBO(const std::string& debug_name, Size size, const Params& params) : _debug_name(debug_name), _size(size), _params(params) , _color_tex(nullptr, size, params.color_format, TexParams::clamped_linear(), debug_name + "_color") { VLOG_SCOPE_F(1, "FBO %s", debug_name.c_str()); CHECK_FOR_GL_ERROR; glGenFramebuffers(1, &_fbo_id); CHECK_FOR_GL_ERROR; { FBO::Lock lock(this); CHECK_FOR_GL_ERROR; // glEnable(GL_TEXTURE_2D); { CHECK_FOR_GL_ERROR; _color_tex.bind(); if (!_color_tex.has_data()) { // We must init texture or we'll get a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: _color_tex.set_data(nullptr); } glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _color_tex.id(), 0); CHECK_FOR_GL_ERROR; } CHECK_FOR_GL_ERROR; #if !GLLIB_GLES if (params.with_depth) { CHECK_FOR_GL_ERROR; glGenRenderbuffers(1, &_depth_rbo_id); glBindRenderbuffer(GL_RENDERBUFFER, _depth_rbo_id); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width(), height()); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth_rbo_id); CHECK_FOR_GL_ERROR; } #endif // !GLLIB_GLES } CHECK_FOR_GL_ERROR; { FBO::Lock lock(this); auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER); CHECK_EQ_F(status, GL_FRAMEBUFFER_COMPLETE, "Framebuffer '%s' not complete after initialization: %s", debug_name.c_str(), framebuffer_completion_to_string(status)); } CHECK_FOR_GL_ERROR; }
void test_levels() { LOG_SCOPE_FUNCTION(INFO); { VLOG_SCOPE_F(1, "Scope with verbosity 1"); LOG_F(3, "Only visible with -v 3 or higher"); LOG_F(2, "Only visible with -v 2 or higher"); LOG_F(1, "Only visible with -v 1 or higher"); } LOG_F(0, "LOG_F(0)"); LOG_F(INFO, "This is some INFO"); LOG_F(WARNING, "This is a WARNING"); LOG_F(ERROR, "This is a serious ERROR"); }
Program::Program(const std::string& vs, const std::string& fs, const std::string& debug_name) : _debug_name(debug_name) { VLOG_SCOPE_F(1, "Compiling GLSL %s", debug_name.c_str()); CHECK_FOR_GL_ERROR; GLuint vs_id = load_shader(GL_VERTEX_SHADER, vs.c_str(), debug_name.c_str()); GLuint fs_id = load_shader(GL_FRAGMENT_SHADER, fs.c_str(), debug_name.c_str()); _program = glCreateProgram(); #if TARGET_OS_IPHONE // For debugger: glLabelObjectEXT(GL_PROGRAM_OBJECT_EXT, _program, 0, debug_name.c_str()); #endif glAttachShader(_program, vs_id); glAttachShader(_program, fs_id); //GLuint color_number = 0; //glBindFragDataLocation(_program, color_number, "out_frag_color"); link_program(_program, debug_name.c_str()); /* too early to validate: uniforms haven't been bound yet. Using two samplers of different type (sampler2D and sampler_cube) will break the validation. */ //validate(); CHECK_FOR_GL_ERROR; //debug_print(); #if 0 LOG_F(INFO, "Shader: %s", debug_name.c_str()); LOG_F(INFO, "-------------------------------------"); LOG_F(INFO, "%s", vs.c_str()); LOG_F(INFO, "-------------------------------------"); LOG_F(INFO, "%s", fs.c_str()); LOG_F(INFO, "-------------------------------------"); #endif GLint num_attribs; glGetProgramiv(_program, GL_ACTIVE_ATTRIBUTES, &num_attribs); for (int i=0; i<num_attribs; ++i) { GLint size; GLenum type; GLchar name[1024]; glGetActiveAttrib(_program, i, sizeof(name), NULL, &size, &type, name); int location = glGetAttribLocation(_program, name); CHECK_NE_F(location, -1, "Attribute '%s' not found in shader '%s'", name, _debug_name.c_str()); VLOG_F(1, "Attribute %d: %10s, %d x %s, location: %d", i, name, size, type_to_string(type), location); _attributes.emplace_back(Attribute{name, size, type, location}); } GLint num_uniforms; glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &num_uniforms); for (int i=0; i<num_uniforms; ++i) { GLint size; GLenum type; GLchar name[1024]; glGetActiveUniform(_program, i, sizeof(name), NULL, &size, &type, name); int location = glGetUniformLocation(_program, name); CHECK_NE_F(location, -1, "Uniform '%s' not found in shader '%s'", name, _debug_name.c_str()); VLOG_F(1, "Uniform %d: %10s, %d x %s, location: %d", i, name, size, type_to_string(type), location); _uniforms.emplace_back(Uniform{name, size, type, location}); } }