Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
3D Graphics Rendering Cookbook
3D Graphics Rendering Cookbook

3D Graphics Rendering Cookbook: A comprehensive guide to exploring rendering algorithms in modern OpenGL and Vulkan

Arrow left icon
Profile Icon Sergey Kosarevsky Profile Icon Viktor Latypov
Arrow right icon
€48.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4 (19 Ratings)
Paperback Aug 2021 670 pages 1st Edition
eBook
€34.99 €38.99
Paperback
€48.99
Subscription
Free Trial
Renews at €18.99p/m
Arrow left icon
Profile Icon Sergey Kosarevsky Profile Icon Viktor Latypov
Arrow right icon
€48.99
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4 (19 Ratings)
Paperback Aug 2021 670 pages 1st Edition
eBook
€34.99 €38.99
Paperback
€48.99
Subscription
Free Trial
Renews at €18.99p/m
eBook
€34.99 €38.99
Paperback
€48.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

3D Graphics Rendering Cookbook

Chapter 2: Using Essential Libraries

There are many production-quality open source C++ libraries and frameworks out there. One of the traits of an experienced graphics developer is their comprehensive knowledge of available open source libraries that are suitable for getting the job done.

In this chapter, we will learn about essential open source libraries and tools that can bring a great productivity boost for you as a developer of graphical applications.

In this chapter, we will cover the following recipes:

  • Using the GLFW library
  • Doing math with GLM
  • Loading images with STB
  • Rendering a basic UI with Dear ImGui
  • Integrating EasyProfiler 
  • Integrating Optick
  • Using the Assimp library
  • Getting started with Etc2Comp
  • Multithreading with Taskflow
  • Introducing MeshOptimizer

Technical requirements

You can find the code files present in this chapter on GitHub at https://github.com/PacktPublishing/3D-Graphics-Rendering-Cookbook/tree/master/Chapter2

Using the GLFW library

The GLFW library hides all the complexity of creating windows, graphics contexts, and surfaces, and getting input events from the operating system. In this recipe, we build a minimalistic application with GLFW and OpenGL to get some basic 3D graphics out onto the screen.

Getting ready

We are building our examples with GLFW 3.3.4. Here is a JSON snippet for the Bootstrap script so that you can download the proper library version:

{
  "name": "glfw",
  "source": {
    "type": "git",
    "url": "https://github.com/glfw/glfw.git",
    "revision": "3.3.4"
  }
}

The complete source code for this recipe can be found in the source code bundle under the name of Chapter2/01_GLFW.

How to do it...

Let's write a minimal application that creates a window and waits for an exit command from the user. Perform the following steps:

  1. First, we set the GLFW error callback via a simple lambda to catch potential errors:
    #include <GLFW/glfw3.h>
    ...
    int main() {
      glfwSetErrorCallback(
         []( int error, const char* description ) {
            fprintf( stderr, "Error: %s\n", description );
         });
  2. Now, we can go forward to try to initialize GLFW:
      if ( !glfwInit() )
         exit(EXIT_FAILURE);
  3. The next step is to tell GLFW which version of OpenGL we want to use. Throughout this book, we will use OpenGL 4.6 Core Profile. You can set it up as follows:
      glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
      glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
      glfwWindowHint(    GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
      GLFWwindow* window = glfwCreateWindow(    1024, 768, "Simple example", nullptr, nullptr);
      if (!window) {
        glfwTerminate();
        exit( EXIT_FAILURE );
      }
  4. There is one more thing we need to do before we can focus on the OpenGL initialization and the main loop. Let's set a callback for key events. Again, a simple lambda will do for now:
      glfwSetKeyCallback(window,
        [](GLFWwindow* window,       int key, int scancode, int action, int mods) {
          if ( key == GLFW_KEY_ESCAPE && action == 
              GLFW_PRESS )
                 glfwSetWindowShouldClose(               window, GLFW_TRUE );
        });
  5. We should prepare the OpenGL context. Here, we use the GLAD library to import all OpenGL entry points and extensions:
      glfwMakeContextCurrent( window );
      gladLoadGL( glfwGetProcAddress );
      glfwSwapInterval( 1 );

Now we are ready to use OpenGL to get some basic graphics out. Let's draw a colored triangle. To do that, we need a vertex shader and a fragment shader, which are both linked to a shader program, and a vertex array object (VAO). Follow these steps:

  1. First, let's create a VAO. For this example, we will use the vertex shader to generate all vertex data, so an empty VAO will be sufficient:
      GLuint VAO;
      glCreateVertexArrays( 1, &VAO );
      glBindVertexArray( VAO );
  2. To generate vertex data for a colored triangle, our vertex shader should look as follows. Those familiar with previous versions of OpenGL 2.x will notice the layout qualifier with the explicit location value for vec3 color. This value should match the corresponding location value in the fragment shader, as shown in the following code:
    static const char* shaderCodeVertex = R"(
    #version 460 core
    layout (location=0) out vec3 color;
    const vec2 pos[3] = vec2[3](
      vec2(-0.6, -0.4),
      vec2(0.6, -0.4),
      vec2(0.0, 0.6)
    );
    const vec3 col[3] = vec3[3](
      vec3(1.0, 0.0, 0.0),
      vec3(0.0, 1.0, 0.0),
      vec3(0.0, 0.0, 1.0)
    );
    void main() {
      gl_Position = vec4(pos[gl_VertexID], 0.0, 1.0);
      color = col[gl_VertexID];
    }
    )";

    Important note

    More details on OpenGL Shading Language (GLSL) layouts can be found in the official Khronos documentation at https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL).

    We use the GLSL built-in gl_VertexID input variable to index into the pos[] and col[] arrays to generate the vertex positions and colors programmatically. In this case, no user-defined inputs to the vertex shader are required.

  3. For the purpose of this recipe, the fragment shader is trivial. The location value of 0 of the vec3 color variable should match the corresponding location in the vertex shader:
    static const char* shaderCodeFragment = R"(
    #version 460 core
    layout (location=0) in vec3 color;
    layout (location=0) out vec4 out_FragColor;
    void main() {
      out_FragColor = vec4(color, 1.0);
    };
    )";
  4. Both shaders should be compiled and linked to a shader program. Here is how we do it:
      const GLuint shaderVertex =    glCreateShader(GL_VERTEX_SHADER);
      glShaderSource(    shaderVertex, 1, &shaderCodeVertex, nullptr);
      glCompileShader(shaderVertex);
      const GLuint shaderFragment =    glCreateShader(GL_FRAGMENT_SHADER);
      glShaderSource(shaderFragment, 1,    &shaderCodeFragment, nullptr);
      glCompileShader(shaderFragment);
      const GLuint program = glCreateProgram();
      glAttachShader(program, shaderVertex);
      glAttachShader(program, shaderFragment);
      glLinkProgram(program);
      glUseProgram(program);

    For the sake of brevity, all error checking is omitted in this chapter. We will come back to it in the next Chapter 3, Getting Started with OpenGL and Vulkan.

Now, when all of the preparations are complete, we can jump into the GLFW main loop and examine how our triangle is being rendered.

Let's explore how a typical GLFW application works. Perform the following steps:

  1. The main loop starts by checking whether the window should be closed:
      while ( !glfwWindowShouldClose(window) )  {
  2. Implement a resizable window by reading the current width and height from GLFW and updating the OpenGL viewport accordingly:
         int width, height;
         glfwGetFramebufferSize(
           window, &width, &height);
         glViewport(0, 0, width, height);

    Important note

    Another approach is to set a GLFW window resize callback via glfwSetWindowSizeCallback(). We will use this later on for more complicated examples.

  3. Clear the screen and render the triangle. The glDrawArrays() function can be invoked with the empty VAO that we bound earlier:
         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
         glClear(GL_COLOR_BUFFER_BIT);
         glDrawArrays(GL_TRIANGLES, 0, 3);
  4. The fragment shader output was rendered into the back buffer. Let's swap the front and back buffers to make the triangle visible. To conclude the main loop, do not forget to poll the events with glfwPollEvents():
         glfwSwapBuffers(window);
         glfwPollEvents();
      }
  5. To make things nice and clean at the end, let's delete the OpenGL objects that we created and terminate GLFW:
      glDeleteProgram(program);
      glDeleteShader(shaderFragment);
      glDeleteShader(shaderVertex);
      glDeleteVertexArrays(1, &VAO);
      glfwDestroyWindow(window);
      glfwTerminate();
      return 0;
    }

Here is a screenshot of our tiny application:

Figure 2.1 – Our first triangle is on the screen

Figure 2.1 – Our first triangle is on the screen

There's more...

The GLFW setup for macOS is quite similar to the Windows operating system. In the CMakeLists.txt file, you should add the following line to the list of used libraries: -framework OpenGL -framework Cocoa -framework CoreView -framework IOKit.

Further details about how to use GLFW can be found at https://www.glfw.org/documentation.html.

Doing math with GLM

Every 3D graphics application needs some sort of math utility functions, such as basic linear algebra or computational geometry. This book uses the OpenGL Mathematics (GLM) header-only C++ mathematics library for graphics, which is based on the GLSL specification. The official documentation (https://glm.g-truc.net) describes GLM as follows:

GLM provides classes and functions designed and implemented with the same naming conventions and functionalities as GLSL so that anyone who knows GLSL, can use GLM as well as C++.

Getting ready

Get the latest version of GLM using the Bootstrap script. We use version 0.9.9.8:

{
  "name": "glm",
  "source": {
    "type": "git",
    "url": "https://github.com/g-truc/glm.git",
    "revision": "0.9.9.8"
  }
}

Let's make use of some linear algebra and create a more complicated 3D graphics example. There are no lonely triangles this time. The full source code for this recipe can be found in Chapter2/02_GLM.

How to do it...

Let's augment the example from the previous recipe using a simple animation and a 3D cube. The model and projection matrices can be calculated inside the main loop based on the window aspect ratio, as follows:

  1. To rotate the cube, the model matrix is calculated as a rotation around the diagonal (1, 1, 1) axis, and the angle of rotation is based on the current system time returned by glfwGetTime():
    const float ratio = width / (float)height;
    const mat4 m = glm::rotate(  glm::translate(mat4(1.0f), vec3(0.0f, 0.0f, -3.5f)),  (float)glfwGetTime(), vec3(1.0f, 1.0f, 1.0f));
    const mat4 p = glm::perspective(  45.0f, ratio, 0.1f, 1000.0f);
  2. Now we should pass the matrices into shaders. We use a uniform buffer to do that. First, we need to declare a C++ structure to hold our data:
    struct PerFrameData {
      mat4 mvp;
      int isWireframe;
    };

    The first field, mvp, will store the premultiplied model-view-projection matrix. The isWireframe field will be used to set the color of the wireframe rendering to make the example more interesting.

  3. The buffer object to hold the data can be allocated as follows. We use the Direct-State-Access (DSA) functions from OpenGL 4.6 instead of the classic bind-to-edit approach:
    const GLsizeiptr kBufferSize = sizeof(PerFrameData);
    GLuint perFrameDataBuf;
    glCreateBuffers(1, &perFrameDataBuf);
    glNamedBufferStorage(perFrameDataBuf, kBufferSize,  nullptr, GL_DYNAMIC_STORAGE_BIT);
    glBindBufferRange(GL_UNIFORM_BUFFER, 0,  perFrameDataBuf, 0, kBufferSize);

    The GL_DYNAMIC_STORAGE_BIT parameter tells the OpenGL implementation that the content of the data store might be updated after creation through calls to glBufferSubData(). The glBindBufferRange() function binds a range within a buffer object to an indexed buffer target. The buffer is bound to the indexed target of 0. This value should be used in the shader code to read data from the buffer.

  4. In this recipe, we are going to render a 3D cube, so a depth test is required to render the image correctly. Before we jump into the shaders' code and our main loop, we need to enable the depth test and set the polygon offset parameters:
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_POLYGON_OFFSET_LINE);
    glPolygonOffset(-1.0f, -1.0f);

    Polygon offset is needed to render a wireframe image of the cube on top of the solid image without Z-fighting. The values of -1.0 will move the wireframe rendering slightly toward the camera.

Let's write the GLSL shaders that are needed for this recipe:

  1. The vertex shader for this recipe will generate cube vertices in a procedural way. This is similar to what we did in the previous triangle recipe. Notice how the PerFrameData input structure in the following vertex shader reflects the PerFrameData structure in the C++ code that was written earlier:
    static const char* shaderCodeVertex = R"(
    #version 460 core
    layout(std140, binding = 0) uniform PerFrameData {
      uniform mat4 MVP;
      uniform int isWireframe;
    };
    layout (location=0) out vec3 color;
  2. The positions and colors of cube vertices should be stored in two arrays. We do not use normal vectors here, which means we can perfectly share 8 vertices among all the 6 adjacent faces of the cube:
    const vec3 pos[8] = vec3[8](
      vec3(-1.0,-1.0, 1.0), vec3( 1.0,-1.0, 1.0),
      vec3(1.0, 1.0, 1.0), vec3(-1.0, 1.0, 1.0),
    
  vec3(-1.0,-1.0,-1.0), vec3(1.0,-1.0,-1.0),
      vec3( 1.0, 1.0,-1.0), vec3(-1.0, 1.0,-1.0)
    );
    const vec3 col[8] = vec3[8](
      vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0),
      vec3(0.0, 0.0, 1.0), vec3(1.0, 1.0, 0.0),
    
  vec3(1.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0),
      vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)
    );
  3. Let's use indices to construct the actual cube faces. Each face consists of two triangles:
    const int indices[36] = int[36](
      // front   0, 1, 2, 2, 3, 0,
      // right   1, 5, 6, 6, 2, 1,
      // back   7, 6, 5, 5, 4, 7,
      // left   4, 0, 3, 3, 7, 4,
      // bottom   4, 5, 1, 1, 0, 4,
      // top   3, 2, 6, 6, 7, 3
    );
  4. The main() function of the vertex shader looks similar to the following code block. The gl_VertexID input variable is used to retrieve an index from indices[], which is used to get corresponding values for the position and color. If we are rendering a wireframe pass, set the vertex color to black:
    void main() {
      int idx = indices[gl_VertexID];
      gl_Position = MVP * vec4(pos[idx], 1.0);
      color = isWireframe > 0 ? vec3(0.0) : col[idx];
    }
    )";
  5. The fragment shader is trivial and simply applies the interpolated color:
    static const char* shaderCodeFragment = R"(
    #version 460 core
    layout (location=0) in vec3 color;
    layout (location=0) out vec4 out_FragColor;
    void main()
    {
      out_FragColor = vec4(color, 1.0);
    };
    )";

The only thing we are missing now is how we update the uniform buffer and submit actual draw calls. We update the buffer twice per frame, that is, once per each draw call:

  1. First, we render the solid cube with the polygon mode set to GL_FILL:
    PerFrameData perFrameData = {  .mvp = p * m,  .isWireframe = false };
    glNamedBufferSubData(  perFrameDataBuf, 0, kBufferSize, &perFrameData);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDrawArrays(GL_TRIANGLES, 0, 36);
  2. Then, we update the buffer and render the wireframe cube using the GL_LINE polygon mode and the -1.0 polygon offset that we set up earlier with glPolygonOffset():
    perFrameData.isWireframe = true;
    glNamedBufferSubData(  perFrameDataBuf, 0, kBufferSize, &perFrameData);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glDrawArrays(GL_TRIANGLES, 0, 36);

The resulting image should look similar to the following screenshot:

Figure 2.2 – The rotating 3D cube with wireframe contours

Figure 2.2 – The rotating 3D cube with wireframe contours

There's more...

As you might have noticed in the preceding code, the glBindBufferRange() function takes an offset into the buffer as one of its input parameters. That means we can make the buffer twice as large and store two different copies of PerFrameData in it. One with isWireframe set to true and another one set to false. Then, we can update the entire buffer with just one call to glNamedBufferSubData(), instead of updating the buffer twice, and use the offset parameter of glBindBufferRange() to feed the correct instance of PerFrameData into the shader. This is the correct and most attractive approach, too.

The reason we decided not to use it in this recipe is that the OpenGL implementation might impose alignment restrictions on the value of offset. For example, many implementations require offset to be a multiple of 256. Then, the actual required alignment can be queued as follows:

GLint alignment;
glGetIntegerv(  GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment);

The alignment requirement would make the simple and straightforward code of this recipe more complicated and difficult to follow without providing any meaningful performance improvements. In more complicated real-world use cases, particularly as the number of different values in the buffer goes up, this approach becomes more useful.

Loading images with STB

Almost every graphics application requires texture images to be loaded from files in some image file formats. Let's take a look at the STB image loader and discuss how we can use it to support popular formats, such as .jpeg, .png, and a floating point format .hdr for high dynamic range texture data.

Getting ready

The STB project consists of multiple header-only libraries. The entire up-to-date package can be downloaded from https://github.com/nothings/stb:

{
  "name": "stb",
  "source": {
    "type": "git",
    "url": "https://github.com/nothings/stb.git",
    "revision": "c9064e317699d2e495f36ba4f9ac037e88ee371a"
  }
}

The demo source code for this recipe can be found in Chapter2/03_STB.

How to do it...

Let's add texture mapping to the previous recipe. Perform the following steps:

  1. The STB library has separate headers for loading and saving images. Both can be included within your project, as follows:
    #define STB_IMAGE_IMPLEMENTATION
    #include <stb/stb_image.h>
    #define STB_IMAGE_WRITE_IMPLEMENTATION
    #include <stb/stb_image_write.h>
  2. To load an image as a 3-channel RGB image from any supported graphics file format, use this short code snippet:
    int w, h, comp;
    const uint8_t* img = stbi_load(  "data/ch2_sample3_STB.jpg", &w, &h, &comp, 3);
  3. Besides that, we can save images into various image file formats. Here is a snippet that enables you to save a screenshot from an OpenGL GLFW application:
    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    uint8_t* ptr = (uint8_t*)malloc(width * height * 4);
    glReadPixels(0, 0, width, height, GL_RGBA,  GL_UNSIGNED_BYTE, ptr);
    stbi_write_png(  "screenshot.png", width, height, 4, ptr, 0);
    free(ptr);

    Please check stb_image.h and stb_image_write.h for a list of supported file formats.

  4. The loaded img image can be used as an OpenGL texture in a DSA fashion, as follows:
    GLuint texture;
    glCreateTextures(GL_TEXTURE_2D, 1, &texture);
    glTextureParameteri(texture, GL_TEXTURE_MAX_LEVEL, 0);
    glTextureParameteri(  texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTextureParameteri(  texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTextureStorage2D(texture, 1, GL_RGB8, w, h);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTextureSubImage2D(texture, 0, 0, 0, w, h, GL_RGB,  GL_UNSIGNED_BYTE, img);
    glBindTextures(0, 1, &texture);

Please refer to the source code in Chapter2/03_STB for a complete working example and the GLSL shader changes that are necessary to apply the texture to our cube.

There's more...

STB supports the loading of high-dynamic-range images in Radiance .HDR file format. Use the stbi_loadf() function to load files as floating-point images. This will preserve the full dynamic range of the image and will be useful to load high-dynamic-range light probes for physically-based lighting in the Chapter 6, Physically Based Rendering Using the glTF2 Shading Model.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Learn to integrate modern rendering techniques into a single performant 3D rendering engine
  • Leverage Vulkan to render 3D content, use AZDO in OpenGL applications, and understand modern real-time rendering methods
  • Implement a physically based rendering pipeline from scratch in Vulkan and OpenGL

Description

OpenGL is a popular cross-language, cross-platform application programming interface (API) used for rendering 2D and 3D graphics, while Vulkan is a low-overhead, cross-platform 3D graphics API that targets high-performance applications. 3D Graphics Rendering Cookbook helps you learn about modern graphics rendering algorithms and techniques using C++ programming along with OpenGL and Vulkan APIs. The book begins by setting up a development environment and takes you through the steps involved in building a 3D rendering engine with the help of basic, yet self-contained, recipes. Each recipe will enable you to incrementally add features to your codebase and show you how to integrate different 3D rendering techniques and algorithms into one large project. You'll also get to grips with core techniques such as physically based rendering, image-based rendering, and CPU/GPU geometry culling, to name a few. As you advance, you'll explore common techniques and solutions that will help you to work with large datasets for 2D and 3D rendering. Finally, you'll discover how to apply optimization techniques to build performant and feature-rich graphics applications. By the end of this 3D rendering book, you'll have gained an improved understanding of best practices used in modern graphics APIs and be able to create fast and versatile 3D rendering frameworks.

Who is this book for?

This book is for 3D graphics developers who are familiar with the mathematical fundamentals of 3D rendering and want to gain expertise in writing fast rendering engines with advanced techniques using C++ libraries and APIs. A solid understanding of C++ and basic linear algebra, as well as experience in creating custom 3D applications without using premade rendering engines is required.

What you will learn

  • Improve the performance of legacy OpenGL applications
  • Manage a substantial amount of content in real-time 3D rendering engines
  • Discover how to debug and profile graphics applications
  • Understand how to use the Approaching Zero Driver Overhead (AZDO) philosophy in OpenGL
  • Integrate various rendering techniques into a single application
  • Find out how to develop Vulkan applications
  • Implement a physically based rendering pipeline from scratch
  • Integrate a physics library with your rendering engine
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Aug 25, 2021
Length: 670 pages
Edition : 1st
Language : English
ISBN-13 : 9781838986193
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Aug 25, 2021
Length: 670 pages
Edition : 1st
Language : English
ISBN-13 : 9781838986193
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 135.97
3D Graphics Rendering Cookbook
€48.99
Software Architecture with C++
€41.99
C++ High Performance
€44.99
Total 135.97 Stars icon

Table of Contents

11 Chapters
Chapter 1: Establishing a Build Environment Chevron down icon Chevron up icon
Chapter 2: Using Essential Libraries Chevron down icon Chevron up icon
Chapter 3: Getting Started with OpenGL and Vulkan Chevron down icon Chevron up icon
Chapter 4: Adding User Interaction and Productivity Tools Chevron down icon Chevron up icon
Chapter 5: Working with Geometry Data Chevron down icon Chevron up icon
Chapter 6: Physically Based Rendering Using the glTF2 Shading Model Chevron down icon Chevron up icon
Chapter 7: Graphics Rendering Pipeline Chevron down icon Chevron up icon
Chapter 8: Image-Based Techniques Chevron down icon Chevron up icon
Chapter 9: Working with Scene Graphs Chevron down icon Chevron up icon
Chapter 10: Advanced Rendering Techniques and Optimizations Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.4
(19 Ratings)
5 star 78.9%
4 star 5.3%
3 star 5.3%
2 star 0%
1 star 10.5%
Filter icon Filter
Top Reviews

Filter reviews by




N/A Apr 04, 2024
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Feefo Verified review Feefo
jmac2050 Jan 15, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Alles super, weiter so...
Amazon Verified review Amazon
Nikita Juneja Oct 11, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book covers all the required topics for rendering 2D and 3D graphics from a basic level. It helped in setting up a development environment and consisted of various rendering algorithms in modern OpenGL and Vulkan.It is a must-have if you wish to build feature-rich graphic applications.
Amazon Verified review Amazon
Charles K Mar 10, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Got it for a reference for writing shaders and understanding GPU language. Not disappoint.
Amazon Verified review Amazon
JP Oct 13, 2021
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you know something about vulkan or opengl. However you are stuck at a phase where you would overthink about implementation and you would not make any progress? Then this book is for you.They explain every concept in a step by step manner with code examples that evolve as you make progress. The project gets bigger at every chapter and in the end you will have a working engine which you can expand upon.In my case I have already implemented all those basics in my engine, I had a working engine with IBL, Shadows and PBR implemented when I bought the book. So if you are like me there are still few concepts that are explained well and worth the purchase.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela