Advanced OpenGL Demo: Physically Based Rendering (PBR) Showcase

Beginner-Friendly OpenGL Demo: Rendering a Rotating 3D Cube

Overview

This tutorial walks you through creating a simple, beginner-friendly OpenGL demo that renders a rotating 3D cube. You’ll learn how to set up an OpenGL context, compile shaders, create vertex buffers, apply basic transformations, and animate rotation. Assumes basic C/C++ knowledge and a development environment configured for OpenGL.

Requirements

  • C or C++ compiler (GCC, Clang, MSVC)
  • GLFW for window/context creation
  • GLAD or GLEW for loading OpenGL functions
  • GLM for math (matrices, vectors)
  • Basic familiarity with shader syntax (GLSL)

Project Structure

  • src/
    • main.cpp
    • shader.h
  • shaders/
    • vertex.glsl
    • fragment.glsl

Vertex Shader (vertex.glsl)

Code

#version 330 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec3 aColor;out vec3 vColor;

uniform mat4 model; uniform mat4 view; uniform mat4 projection;

void main() {

vColor = aColor; gl_Position = projection * view * model * vec4(aPos, 1.0); 

}

Fragment Shader (fragment.glsl)

Code

#version 330 core in vec3 vColor; out vec4 FragColor; void main() {

FragColor = vec4(vColor, 1.0); 

}

Key Steps (high level)

  1. Initialize GLFW and create a window with OpenGL 3.3 core profile.
  2. Load OpenGL functions with GLAD (or GLEW).
  3. Configure global OpenGL state (enable depth testing).
  4. Define cube vertex positions and per-vertex colors, and upload to a VBO with a VAO.
  5. Create shader program from the GLSL files.
  6. In the render loop: compute model, view, projection matrices (use GLM), send uniforms, draw the cube, and swap buffers.
  7. Clean up resources on exit.

Important Code Snippets

main.cpp (essential parts)

Code

#include #include #include #include #include “shader.h”

// … initialize GLFW, create window, load GLAD …

glEnable(GL_DEPTH_TEST);

// cube vertices: positions and colors float vertices[] = {

// positions         // colors -0.5f,-0.5f,-0.5f,   1.0f,0.0f,0.0f,  0.5f,-0.5f,-0.5f,   0.0f,1.0f,0.0f,  0.5f, 0.5f,-0.5f,   0.0f,0.0f,1.0f, // ... remaining vertices ... 

};

unsigned int VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1);

// shader Shader shader(“shaders/vertex.glsl”, “shaders/fragment.glsl”);

// render loop while(!glfwWindowShouldClose(window)) {

float time = glfwGetTime(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 model = glm::rotate(glm::mat4(1.0f), time, glm::vec3(0.5f, 1.0f, 0.0f)); glm::mat4 view  = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -3.0f)); glm::mat4 proj  = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f); shader.use(); shader.setMat4("model", model); shader.setMat4("view", view); shader.setMat4("projection", proj); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 36); glfwSwapBuffers(window); glfwPollEvents(); 

}

// cleanup…

Tips and Troubleshooting

  • If nothing appears, ensure depth testing is enabled and the clear color isn’t the same as cube colors.
  • Check shader compile/link logs when shaders fail.
  • Use glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) to debug geometry wireframe.
  • For portability, request core profile and check GL version.

Next Steps

  • Add keyboard controls to pause/adjust rotation.
  • Apply textures and lighting (normals) for realism.
  • Port to WebGL via Emscripten or use a higher-level engine.

This demo gives a compact, working foundation for learning OpenGL rendering and transforms.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *