Introduction
This site walks through modern real-time rendering one small program at a time, from an empty window to image based physically based rendering. It is LearnOpenGL, the tutorial series by Joey de Vries, retold for ml64, with the macros of the MASM64 SDK. The chapters keep LearnOpenGL's order, its structure and much of its route through each subject, because that route works. The prose is rewritten, every program is new, and wherever Direct3D does something differently from OpenGL, or assembly does something differently from C, the chapter stops to say so.
It has a twin: Learn D3D11 in rin tells the same story in a small C-like language, and the programs here follow those lesson for lesson, down to the shaders, which are shared unchanged. If you already know LearnOpenGL, you can read this as a translation guide: every chapter links its original, and the maths and techniques carry over unchanged. If you don't, you can read it on its own; nothing here assumes you have seen OpenGL.
Prerequisites
Direct3D is an API, not a language, so we need one to call it from. Ours is assembly, with no C runtime underneath: the window is Win32, images are decoded by Windows' own codecs, shaders are compiled by
- the
Win64 calling convention : the first four arguments inrcx,rdx,r8andr9, floats in thexmmregister of their position, results inraxorxmm0 invoke , the SDK's macro that loads the arguments and makes the call:invoke CreateWindowExA, 0, ADDR window_class_name, ...vcall , this project's macro for calling a COM method:vcall device, ID3D11Device_CreateBuffer, ADDR desc, ADDR init, ADDR buffer
Direct3D's own interfaces are COM objects: a pointer to a table of functions, called with the object as the hidden first argument. The next chapter says more, and the repository's notes on the assembly collect every convention and trap in one place.
We also use some mathematics along the way: vectors, matrices, a little trigonometry, and for PBR a few integrals. Each is introduced when it is needed and explained as far as the chapter needs it, with pointers to fuller treatments. Here the vector and matrix code is SSE, four floats to a register, which turns out to suit it well.
Structure
The menu on the left lists the chapters in order, grouped into sections, the same sections LearnOpenGL has with "Advanced OpenGL" renamed. Read them top to bottom: each one builds on the program and the ideas of the one before. Every chapter explains the theory first, then builds it up in code, ending with a link to the complete program, some exercises, and further reading.
Each chapter is one .asm file, assembled on its own, with its HLSL shaders in the same folder. The first two lessons write absolutely everything out; after that, what has been explained once moves into includes/, which play the parts LearnOpenGL gives its libraries (GLFW, GLAD, GLM, stb_image) and its helper headers for shaders, the camera and models. All of the source can be read here in the code viewer, linked from each chapter, or on GitHub.
Where LearnOpenGL splits a lesson into several programs (an indexed triangle next to the plain one, a textured PBR scene next to the plain spheres), ours keeps them in one program and switches between them with Tab or the number keys. The chapter says which key does what.
To keep the text easy to scan, a few conventions are used throughout.
Boxes
Code
Code appears in boxes with an amber edge, highlighted, assembly for the programs and HLSL for the shaders. In the assembly, instructions, registers, assembler directives and the project's macros each have their own colour:
; rcx: bind flags, rdx: data, r8: size -> rax: ID3D11Buffer
;
; An immutable buffer: filled once at creation, never written by the CPU again.
align 16
create_buffer proc bind:qword, data:qword, data_size:qword
The snippets are copied from the real programs, so they always match what you will find in the full source. The button at the top right switches the page between light and dark.
Colour hints
Some words are coloured to show what kind of thing they are:
Definition : green words mark a term being defined, one you will meet again.Program structure : these are functions, procedures and macros, such asD3D11CreateDeviceAndSwapChain .- Variables: these are variables, fields and constants, such as D3D11_USAGE_IMMUTABLE.
Building the lessons
You will need Windows, Visual Studio with the C++ x64 tools (for ml64 and link), the Windows SDK, and the MASM64 SDK from masm32.com, installed into C:\masm64 or pointed at by MASM64_HOME. With those in place, one script builds all 38 programs, each a single ml64 and a single link:
git clone https://github.com/IbrahimHindawi/masm64-dx11
cd masm64-dx11
scripts\build.bat
build\hello_triangle.exe
Creating a window goes through the setup in detail. Every lesson uses the same controls once there is a camera to move: W, A, S and D with Space and Shift to fly, the right mouse button held down to look around, the mouse wheel to zoom, and Escape to quit.
Credit
The tutorial this follows is Joey de Vries' LearnOpenGL, also available as a book, with its code on GitHub. Its chapters, choice of examples and much of the way each subject is explained come from there, along with the textures, models and HDR environment the lessons load, and the diagrams marked as LearnOpenGL's. LearnOpenGL is licensed CC BY-NC 4.0, and so is everything here. Thank you, Joey: a great many of us learned graphics from your site.
Now that the layout is familiar, head on to Getting started.