<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Phil Peron</title>
    <description>The latest articles on DEV Community by Phil Peron (@pperon).</description>
    <link>https://dev.to/pperon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F141787%2F4546e36a-843f-43af-8bed-8d8db1afb080.jpg</url>
      <title>DEV Community: Phil Peron</title>
      <link>https://dev.to/pperon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pperon"/>
    <language>en</language>
    <item>
      <title>Hello, bgfx!</title>
      <dc:creator>Phil Peron</dc:creator>
      <pubDate>Wed, 06 Mar 2019 01:16:05 +0000</pubDate>
      <link>https://dev.to/pperon/hello-bgfx-4dka</link>
      <guid>https://dev.to/pperon/hello-bgfx-4dka</guid>
      <description>&lt;p&gt;Bgfx is a rendering library that supports Direct3D, Metal and OpenGL variants across 11 platforms and counting. It's easy to build and there are many examples available to help submerse you in the details. Understanding the line of separation between bgfx and the example code was relatively easy but took me more time than I would have thought. If you're interested in a quick example on how to use bgfx with your own project, read on.&lt;/p&gt;

&lt;p&gt;I assume you have some prior graphics programming experience and that you've already followed the build instructions &lt;a href="https://bkaradzic.github.io/bgfx/build.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I'll be borrowing from the &lt;em&gt;example-01-cubes&lt;/em&gt; project so make sure you build using the &lt;strong&gt;--with-examples&lt;/strong&gt; option if you'd like to follow along.&lt;/p&gt;

&lt;p&gt;You'll find the debug and release libraries in a folder named something like &lt;em&gt;winXX_vs20XX&lt;/em&gt; located inside the .build directory (making sure you link bgfx*.lib, bimg*.lib and bx*.lib). To test if all is well, call the &lt;a href="https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx4initERK4Init" rel="noopener noreferrer"&gt;bgfx::init&lt;/a&gt; function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "bgfx/bgfx.h"

int main(void)
{
    bgfx::init();
    return 0;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With all this in place, you should be able to initialize the system without error.&lt;/p&gt;

&lt;p&gt;We'll need a window to render to. I use &lt;a href="https://www.glfw.org/docs/latest/quick_guide.html" rel="noopener noreferrer"&gt;GLFW&lt;/a&gt; but &lt;a href="http://wiki.libsdl.org/Introduction" rel="noopener noreferrer"&gt;SDL&lt;/a&gt; or anything else will be fine.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#include "bgfx/bgfx.h"
#include "GLFW/glfw3.h"

#define WNDW_WIDTH 1600
#define WNDW_HEIGHT 900

int main(void)
{
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(WNDW_WIDTH, WNDW_HEIGHT, "Hello, bgfx!", NULL, NULL);
    bgfx::init();
    return 0;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have to make sure bgfx has a handle to the native window. This is done via the &lt;a href="https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx12PlatformDataE" rel="noopener noreferrer"&gt;bgfx::PlatformData&lt;/a&gt; struct and the 'nwh' member. If you're using GLFW, make sure you define GLFW_EXPOSE_NATIVE_WIN32 and include the glfw3native header. Now is also a good time to properly define a &lt;a href="https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx4InitE" rel="noopener noreferrer"&gt;bgfx::Init&lt;/a&gt; object.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3native.h"
...
    bgfx::PlatformData pd;
    pd.nwh = glfwGetWin32Window(window);
    bgfx::setPlatformData(pd);

    bgfx::Init bgfxInit;
    bgfxInit.type = bgfx::RendererType::Count; // Automatically choose a renderer.
    bgfxInit.resolution.width = WNDW_WIDTH;
    bgfxInit.resolution.height = WNDW_HEIGHT;
    bgfxInit.resolution.reset = BGFX_RESET_VSYNC;
    bgfx::init(bgfxInit);
...


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's render something. We'll set the view clear flags and create a simple render loop.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
    bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x443355FF, 1.0f, 0);
    bgfx::setViewRect(0, 0, 0, WNDW_WIDTH, WNDW_HEIGHT);

    unsigned int counter = 0;
    while(true) {   
        bgfx::frame();
        counter++;
    }
...


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should see a window with a purple background. Soak in the awesome. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xfxcbmma0ynn5h2zd8j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xfxcbmma0ynn5h2zd8j.jpg"&gt;&lt;/a&gt;&lt;br&gt;
At this point, we're ready to take on something more interesting. We'll steal a cube mesh from one of the example files.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

struct PosColorVertex
{
    float x;
    float y;
    float z;
    uint32_t abgr;
};

static PosColorVertex cubeVertices[] =
{
    {-1.0f,  1.0f,  1.0f, 0xff000000 },
    { 1.0f,  1.0f,  1.0f, 0xff0000ff },
    {-1.0f, -1.0f,  1.0f, 0xff00ff00 },
    { 1.0f, -1.0f,  1.0f, 0xff00ffff },
    {-1.0f,  1.0f, -1.0f, 0xffff0000 },
    { 1.0f,  1.0f, -1.0f, 0xffff00ff },
    {-1.0f, -1.0f, -1.0f, 0xffffff00 },
    { 1.0f, -1.0f, -1.0f, 0xffffffff },
};

static const uint16_t cubeTriList[] =
{
    0, 1, 2,
    1, 3, 2,
    4, 6, 5,
    5, 6, 7,
    0, 2, 4,
    4, 2, 6,
    1, 5, 3,
    5, 7, 3,
    0, 4, 1,
    4, 5, 1,
    2, 3, 6,
    6, 3, 7,
};


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we need to describe the mesh in terms of the vertex declaration, &lt;a href="https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx10VertexDeclE" rel="noopener noreferrer"&gt;bgfx::VertexDecl&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
    bgfx::setViewRect(0, 0, 0, WNDW_WIDTH, WNDW_HEIGHT);

    bgfx::VertexDecl pcvDecl;
    pcvDecl.begin()
        .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
        .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
    .end();
    bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(bgfx::makeRef(cubeVertices, sizeof(cubeVertices)), pcvDecl);
    bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(bgfx::makeRef(cubeTriList, sizeof(cubeTriList)));

    unsigned int counter = 0;
...


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We're almost there. We just need to load a bgfx shader which we'll borrow from the example files in the examples/runtime/shaders directory. To do that we need to load the shader file contents inside a &lt;a href="https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx6MemoryE" rel="noopener noreferrer"&gt;bgfx::Memory&lt;/a&gt; object before passing that to &lt;a href="https://bkaradzic.github.io/bgfx/bgfx.html#_CPPv2N4bgfx12createShaderEPK6Memory" rel="noopener noreferrer"&gt;bgfx::createShader&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

bgfx::ShaderHandle loadShader(const char *FILENAME)
{
    const char* shaderPath = "???";

    switch(bgfx::getRendererType()) {
        case bgfx::RendererType::Noop:
        case bgfx::RendererType::Direct3D9:  shaderPath = "shaders/dx9/";   break;
        case bgfx::RendererType::Direct3D11:
        case bgfx::RendererType::Direct3D12: shaderPath = "shaders/dx11/";  break;
        case bgfx::RendererType::Gnm:        shaderPath = "shaders/pssl/";  break;
        case bgfx::RendererType::Metal:      shaderPath = "shaders/metal/"; break;
        case bgfx::RendererType::OpenGL:     shaderPath = "shaders/glsl/";  break;
        case bgfx::RendererType::OpenGLES:   shaderPath = "shaders/essl/";  break;
        case bgfx::RendererType::Vulkan:     shaderPath = "shaders/spirv/"; break;
    }

    size_t shaderLen = strlen(shaderPath);
    size_t fileLen = strlen(FILENAME);
    char *filePath = (char *)malloc(shaderLen + fileLen);
    memcpy(filePath, shaderPath, shaderLen);
    memcpy(&amp;amp;filePath[shaderLen], FILENAME, fileLen);

    FILE *file = fopen(FILENAME, "rb");
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    fseek(file, 0, SEEK_SET);

    const bgfx::Memory *mem = bgfx::alloc(fileSize + 1);
    fread(mem-&amp;gt;data, 1, fileSize, file);
    mem-&amp;gt;data[mem-&amp;gt;size - 1] = '\0';
    fclose(file);

    return bgfx::createShader(mem);
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we can create a shader program and wrap up rendering our cube. The &lt;a href="https://github.com/bkaradzic/bx" rel="noopener noreferrer"&gt;bx library&lt;/a&gt; has matrix helper methods or use your own. Either way, building the projection matrix and setting the view transform should look familiar. Don't forget to set the vertex and index buffers and submit the program we just created before advancing the next frame.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
    bgfx::ShaderHandle vsh = loadShader("vs_cubes.bin");
    bgfx::ShaderHandle fsh = loadShader("fs_cubes.bin");
    bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh, true);

    unsigned int counter = 0;
    while(true) {
        const bx::Vec3 at = {0.0f, 0.0f,  0.0f};
        const bx::Vec3 eye = {0.0f, 0.0f, -5.0f};
        float view[16];
        bx::mtxLookAt(view, eye, at);
        float proj[16];
        bx::mtxProj(proj, 60.0f, float(WNDW_WIDTH) / float(WNDW_HEIGHT), 0.1f, 100.0f, bgfx::getCaps()-&amp;gt;homogeneousDepth);
        bgfx::setViewTransform(0, view, proj);

        bgfx::setVertexBuffer(0, vbh);
        bgfx::setIndexBuffer(ibh);

        bgfx::submit(0, program);
        bgfx::frame();
        counter++;
    }
...


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqchyjayhqkrvl8wqlyz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqchyjayhqkrvl8wqlyz.jpg"&gt;&lt;/a&gt;&lt;br&gt;
Behold! A cube. Let's make it move.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

...
    bgfx::setViewTransform(0, view, proj);
    float mtx[16];
    bx::mtxRotateXY(mtx, counter * 0.01f, counter * 0.01f);
    bgfx::setTransform(mtx);        

    bgfx::submit(0, program);
...


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And we're done!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclqyf36ntuo30jwpsks8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclqyf36ntuo30jwpsks8.jpg"&gt;&lt;/a&gt;&lt;br&gt;
You can check out the completed example &lt;a href="https://gist.github.com/pperon/5df815df55d6c39db004f46f6cb9837b" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Note that I kept error handling and callbacks out to better highlight how bgfx is used. Hopefully this will give you a basic idea of how things work and enable you to layer in more advanced techniques. Be sure to take some time to scan through the &lt;a href="https://bkaradzic.github.io/bgfx/examples.html" rel="noopener noreferrer"&gt;example code&lt;/a&gt; and &lt;a href="https://bkaradzic.github.io/bgfx/index.html" rel="noopener noreferrer"&gt;API documentation&lt;/a&gt;. Good luck and happy rendering!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Спасибо &lt;a href="https://twitter.com/bkaradzic" rel="noopener noreferrer"&gt;Бранимир Караџић!&lt;/a&gt;&lt;/em&gt;  &lt;/p&gt;

</description>
      <category>cpp</category>
      <category>gamedev</category>
      <category>graphics</category>
    </item>
  </channel>
</rss>
