globjects, C++ 库严格封装OpenGL对象

分享于 

22分钟阅读

GitHub

  繁體 雙語
Strict OpenGL Objects Wrapper Library.
  • 源代码名称:globjects
  • 源代码网址:http://www.github.com/cginternals/globjects
  • globjects源代码文档
  • globjects源代码下载
  • Git URL:
    git://www.github.com/cginternals/globjects.git
    Git Clone代码到本地:
    git clone http://www.github.com/cginternals/globjects
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/cginternals/globjects
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    

    globjects Logo

    是一个授权的,跨平台 C++ 包装器,适用于对象。

    查看 globjects-1.0.0 中新增的内容。

    globjects 为 OpenGL API ( 3.0和更高版本) 提供面向对象的接口。 它减少了渲染需要的OpenGL代码,并通过一个额外的抽象层( 即 glbindingGLM ) 来简化OpenGL使用。 常见的渲染任务和过程是自动化的,特定OpenGL驱动程序的缺少特性部分模拟或者模拟。

    what-is-globjects

    下面的代码段演示了 OpenGL API的范例用法:

    // OpenGL APIauto program = glCreateProgram();auto vertexShader = glCreateShader(GL_VERTEX_SHADER);auto fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);glCompileShader(vertexShader);glCompileShader(fragmentShader);glAttachShader(program, vertexShader);glAttachShader(program, fragmentShader);glLinkProgram(program);glUseProgram(program);glUniform2f(glGetUniformLocation(program, "extent"), 1.0f, 0.5f);

    使用 globjects,可以将它的简化为以下代码:

    // globjects APIauto program = new Program();
    program->attach(
     Shader::fromString(GL_VERTEX_SHADER, vertexShaderSource), 
     Shader::fromString(GL_FRAGMENT_SHADER, fragmentShaderSource)
    );
    program->setUniform("extent", glm::vec2(1.0f, 0.5f)));

    如果启用,这里代码在每次调用后检查( 1 ) 错误的( glGetError ),( 2 ) 着色器用于编译错误,以及( 3 ) 用于链接器错误的程序。

    专业支持

    CG内部提供计算机图形 r&,以及可靠的技术和创新的概念,支持你的计算机图形视觉。 我们提供培训,可以帮助你在下一个项目中集成和定制 globjects。

    访问专业支持和服务服务,了解更多详情。

    资源

    安装和开发基于的上下文管理封装的OpenGL对象和代码段附加功能文档和代码段

    项目健康

    服务系统编译器状态
    travis ci。14.04GCC 4.8,Clang 3.5Build Status
    travis ci。OS XClang?即将来
    14.04GCC 5.4Coverity Status
    Jenkins



    14.04



    GCC 4.8
    GCC 4.9
    GCC 5.4
    Clang 3.8
    Build Status
    Build Status
    Build Status
    Build Status
    Jenkins

    Windows 10

    MSVC 2013更新 5
    MSVC 2015更新 1
    Build Status
    Build Status

    安装说明

    globjects 可以用于不同的平台使用不同的分销渠道。 你可以下载源代码并手动编译编译它或者使用该存储库的预先编译的版本。 对于提供包管理器的系统,我们通常在这些包管理器。

    Windows

    通过下载安装程序,比如,最新x64安装程序插件,或者下载并提取一个预编译归档文件,比如运行时,示例dev,可以安装各种globjects软件包。 或者,下载源代码并从源代码开始构建。

    globjects 是在Ubuntu上使用PPAs提供的。 对于 Ubuntu,15.10和 15.04使用当前的PPA,对于 Ubuntu 14.04 ( 信任信) 使用backports PPA。 使用当前的PPA作为示例,以下几行安装 globjects,包括GLFW示例:

    > sudo apt-add repository ppa:cginternals/ppa> sudo apt-get update> sudo apt-get install libglobjects-examples-glfw># start example>/usr/share/globjects/computeshader

    要使用globjects作为依赖项,请安装开发软件包:

    > sudo apt-get install libglobjects-dev libglobjects-dbg

    或者,下载源代码并从源代码开始构建。

    OS X

    我们依赖 OS X的软件包管理器是 Homebrew。 这个包被称为 globjects。 要使用 Homebrew 安装 globjects,请执行以下行:

    > brew install globjects

    或者,下载源代码并从源代码开始构建。

    基于的debian系统

    目前未维护预编译软件包。 请下载源代码并从源代码开始构建。

    生成指令

    先决条件和依赖项

    globjects唯一的强制运行时依赖性是使用的编译器,glbinding和一个与应用程序动态链接的OpenGL驱动程序库。 但是,编译 globjects 需要以下必需和可选的依赖项:

    • 从源( 强制从源生成)的CMake 或者更高版本building生成
    • 用于版本控制和脚本支持任务的 git
    • glbinding 作为 OpenGL API绑定
    • 用于OpenGL数学和数据结构( 0.9.7 或者上)的GLM
    • GLFW 3.0或者更高的示例
    • cpplocate 示例
    • 基于qt的Qt5 5.0或者更高版本
    • Doxygen 1.8或者更高版本,用于在你的系统上生成文档
      • 用于生成图表的 ( 可选)
    编译指令

    编译时,符合C++11的编译器,比如,GCC 4.8,Clang 3.3,MSVC 2013更新 3,需要。

    首先,下载源代码作为归档文件,或者通过 git:

    > git clone https://github.com/cginternals/globjects.git>cd globjects

    然后,根据要构建的globjects版本,为 1.0.0版本选择适当的标记或者分支 比如:

    > git fetch --tags> git checkout v1.0.0

    实际编译可以使用你喜欢的编译器和IDE来完成。

    例如通过 命令行 可以使用( 应该在所有系统上工作) 来构建 globjects:

    首先创建一个生成目录( 我们不建议在源代码生成中使用):

    > mkdir build>cd build

    使用首选或者默认生成器( 比如 ),在x64使用中为 Visual Studio 2015配置 globjects,请注意: 一些ide集成了对插件项目,比如,Qt创建者的支持,并允许你跳过手动项目配置:

    > cmake.. -G "Visual Studio 14 2015 Win64"

    要编译该项目,请使用已经创建的项目或者使用 CMake ide你喜欢的编辑器/ide,或者使用以下方法:

    > cmake --build .

    的链接提示

    我们建议使用globjects的构建系统进行平滑集成: CMake

    对于它,提供了一个find配置脚本that应该安装到系统中,或者至少可以通过CMake访问。 在项目 CMakeLists.txt, 中,添加以下行之一:

    
    find_package(globjects QUIET) # if you want to check for existance
    
    
    find_package(globjects REQUIRED) # if it is really required in your project
    
    
    
    

    最后,只需将globjects链接到你自己的库或者可执行文件:

    
    target_link_libraries(${target}.. . PUBLIC globjects::globjects)
    
    
    
    

    初始化上下文

    globjects可以处理多个OpenGL上下文。 对于每个上下文,你都必须初始化globjects状态。 此外,你必须告诉globjects每个线程的上下文是活动的。

    #include<globjects/globjects.h>// manage contextsinit();// set explicit context activesetContext(contextID);// set current context activesetCurrentContext();

    你还可以使用glbinding自动同步OpenGL活动上下文及其glbinding和globjects对应项:

    glbinding::Binding::addContextSwitchCallback([](glbinding::ContextHandle handle) {
     setContext(handle);
    }

    唯一要做的事情是在上下文切换为( 每线程) 时告诉 glbinding。

    glbinding::Binding::useContext(handle);

    封装的OpenGL对象

    全局函数

    一些常用的函数被包装以简化API所提出的接口。

    // somehow similar to glbindingstd::string extensions = getString(GL_EXTENSIONS);int numExtensions = getInteger(GL_NUM_EXTENSIONS);if (isCoreProfile())
    {
     returnrenderer(); // returns the GL_RENDERER string}
    缓冲区

    可以用OpenGL来表示顶点属性。索引。统一数据。原子计数器。纹理数据和着色器存储数据。

    auto buffer = new Buffer();// Using buffer databuffer->setData({{ 0, 1, 2, 3, 4}}, GL_STATIC_DRAW);// Using buffer storagebuffer->setStorage({{ 0, 1, 2, 3, 4}}, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
    buffer->setSubData({{ 4, 3, 2 }}, 0);
    buffer->bindBase(GL_SHADER_STORAGE_BUFFER, 0);
    纹理

    纹理支持传统接口和bindless支持。

    auto texture1 = new Texture(GL_TEXTURE_2D); // type has to be fix during lifetimetexture1->setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    texture1->setParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    texture1->setParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    texture1->setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    texture1->image2D(0, GL_RGBA8, glm::ivec2(512), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    texture1->clearImage(0, GL_RGBA, GL_UNSIGNED_BYTE, glm::ivec4(255, 255, 255, 255));
    texture1->generateMipMap();auto texture2 = Texture::createDefault(); // creates a default-configured 2D textureauto handle = texture2->textureHandle(); // for bindless texturingtexture2->bindActive(0); // For traditional texturing
    状态

    OpenGL状态封装为状态,StateSettings和功能,后者主要在内部使用。

    auto currentState = State::currentState(); // full current state; usable for resettingauto state1 = new State(State::ImmediateMode); // all changes are applied immediatelystate1->enable(GL_RASTERIZER_DISCARD); // Configuring a Capabilitystate1->primitiveRestartIndex(static_cast<GLuint>(-1)); // Configuring a StateSettingauto state2 = new State(State::DeferredMode); // changes has to be applied explicitlystate2->pointSize(10.0f);
    state2->apply();
    currentState->apply(); // Reset manipulated state
    错误
    auto error = Error::get();if (error)
    {
     std::cout <<"Error " <<std::hex <<error.code() <<": " <<error.name() <<std::endl;
    }
    调试消息

    启用DebugMessages从你的OpenGL驱动程序中获取性能提示,警告和错误。

    DebugMessage::enable(); // enable automatic messages if KHR_debug is availableDebugMessage::setCallback([](const DebugMessage & message) {
     std::cout <<message.message() <<std::endl;
    }); // if you want to handle messages by yourself
    缓冲器

    将带有多个渲染目标的画布包装在一起。

    auto fbo = new Framebuffer();
    fbo->attachTexture(GL_COLOR_ATTACHMENT0, texture1);
    fbo->attachTexture(GL_COLOR_ATTACHMENT1, texture2);
    fbo->attachRenderbuffer(GL_DEPTH_ATTACHMENT, depthRenderbuffer);
    fbo->setDrawBuffers({ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_NONE });
    fbo->printStatus(true); // Print errors if fbo is not completefbo->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    fbo->clearBuffer(GL_COLOR, 0, glm::vec4(1.0f, 1.0f, 1.0f, 0.0f));
    fbo->blit(GL_COLOR_ATTACHMENT0, {{ 0, 0, width, height }}, Framebuffer::defaultFBO(),
     GL_BACK_LEFT, {{ 0, 0, width, height }}, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    命名字符串

    register 编译时间明暗器替换包括。

    // typically the only function call you'll needauto namedString1 = new NamedString("/upNormal.glsl", "const vec3 up = vec3(0.0, 1.0, 0.0);");// or reference an actual source fileauto namedString2 = new NamedString("/phong.glsl", new File("data/shaders/phong.glsl"));
    程序

    程序对象可以同时表示渲染程序和计算程序。 以前使用它自动在明暗器更改上进行更改。

    auto renderProgram = new Program();
    renderProgram->attach(vertexShader, fragmentShader);
    renderProgram->addUniform("viewProjection", glm::mat4(1.0));
    renderProgram->use(); // compiles shaders, links and uses programauto computeProgram = new Program();
    computeProgram->attach(computeShader);
    computeProgram->dispatchCompute(128, 1, 1);
    程序管道
    auto pipeline = new ProgramPipeline();
    pipeline->useStages(vertexProgram, gl::GL_VERTEX_SHADER_BIT);
    pipeline->useStages(fragmentProgram, gl::GL_FRAGMENT_SHADER_BIT);
    pipeline->use(); // as Program interface
    查询

    查询和测量时间并通过传递的示例执行条件呈现。

    auto query = new Query();
    query->begin(GL_TIME_ELAPSED);// callsquery->end(GL_TIME_ELAPSED);if (!query->resultsAvailable())
    {
     query->wait();
    }auto elapsed = query->get(GL_QUERY_RESULT);
    auto renderBuffer = new Renderbuffer();
    renderBuffer->storage(GL_RGBA32F, 512, 512);
    采样器

    用于纹理参数的临时替代。 注:新创建的采样器默认没有配置,因此无效。

    auto sampler = new Sampler();
    sampler->setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    sampler->setParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    sampler->setParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    sampler->setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    sampler->bind(0); // override sampler state for texture at binding point 0
    明暗器
    auto shader1 = new Shader::fromFile(GL_VERTEX_SHADER, filename);auto shader2 = new Shader::fromString(GL_FRAGMENT_SHADER, shaderSource);Shader::globalReplace("#version 140", "#version 150"); // e.g., useful for OS Xshader1->setIncludePaths({ std::string("/data") });
    shader2->compile();
    std::cout <<shader2->infoLog() <<std::endl; // acess compile info log, although it's done automatically if there is a compile error
    同步
    auto sync = Sync::fence(GL_SYNC_GPU_COMMANDS_COMPLETE);
    sync->clientWait(GL_SYNC_FLUSH_COMMANDS_BIT, 2000000000); // wait on GPU; 2 secssync->waitSync(1000000); // wait on CPU; 1 millisecond
    变换反馈

    将着色器输出连接到缓冲区并重新启动图形。

    auto tf = new TransformFeedback();
    tf->setVaryings(program, { { "next_position" } }, GL_INTERLEAVED_ATTRIBS);
    tf->bind();glEnable(GL_RASTERIZER_DISCARD);
    program->use();
    tf->begin(GL_TRIANGLES);
    vao->drawArrays(GL_TRIANGLES, 0, 3);
    tf->end();glDisable(GL_RASTERIZER_DISCARD);
    tf->draw(GL_TRIANGLE_STRIP);
    均匀

    连接到程序的制服会自动更新,即使重新连接后也会自动更新。

    auto uniform1 = new Uniform<glm::vec3>("lightPos", glm::vec3(10.0f, 5.0f, 0.0f)); // name-based uniform bindingauto uniform2 = new Uniform<glm::mat4>(0, glm::mat4(1.0f)); // location-based uniform bindingprogram->addUniform(uniform1);
    program->addUniform(uniform2);
    program->use(); // uniform values are updated if required
    统一块

    对于大型。经常交换的制服块使用统一块。

    auto block = program->uniformBlock("uniforms");
    block->setBinding(0);
    buffer->bindBase(GL_UNIFORM_BUFFER, 0);
    顶点 array

    用于配置顶点着色器输入和触发器渲染管道进程。

    auto vao = new VertexArray();// configure bindings (see next section)vao->enable(0);
    vao->enable(1);
    vao->drawArrays(GL_POINTS, 0, 10);
    顶点属性绑定
    // For attribute pointersauto binding1 = vao->binding(0);
    binding1->setBuffer(vertexBuffer, 0, sizeof(glm::vec3));
    binding1->setFormat(3, GL_FLOAT, GL_FALSE, 0);// For static attributes for each vertexauto binding2 = vao->binding(0);
    binding2->setValue<float>(1.0f);

    附加功能

    参考指针

    globjects使用 RAII ( 资源分配是初始化) 原理,这意味着创建对象也是在GPU上创建的。 为了有效地管理双分配内存,我们使用引用指针。 我们建议每个 globjects Object 指针都存储在 ref_ptr 中。

    {
     ref_ptr<Query> query = newQuery(); // allocate on CPU and GPU// query is destructed and freed on GPU at the end of the block.}

    由于globjects中的对象使用 ref_ptr 存储引用,而不使用引用计数可能导致意外的释放的对象 。 如果你不想使用智能指针,则必须使用手动引用计数接口:

    program->ref(); // increase reference countprogram->unref(); // decreare reference count; potentially free program pointer and GPU program
    明暗器模板

    Shaders ( ShaderSource )的源可以配置和模板化。

    autotemplate = new StringTemplate(new File("fragmentShader.frag"));template->replace("REPLACE", "WITH THIS");auto shader = new Shader(template);
    策略替代

    尽管globjects尝试使用最新的OpenGL api,但你可以覆盖这个自动过程。

    // Enable CPU shader includes (although supported, some drivers have problems, so disable it)globjects::init(Shader::IncludeImplementation::Fallback);// Update strategy at run-timeBuffer::hintBindlessImplementation(Buffer::BindlessImplementation::Legacy);
    日志记录

    globjects为它的对象和glm对象提供日志接口。

    std::cout <<Framebuffer::defaultFBO();
    std::cout <<glm::vec4(1.0, 0.0, 0.0, 1.0);warning() <<shader;

    str  对象  WRAP  Opengl  Wrapping  严格  
    相关文章