GLEW (OpenGL Extension Wrangler Library) solves a fundamental problem: modern OpenGL features (shaders, VBOs, framebuffers, instancing) are exposed as _extensions_ whose function pointers must be discovered at runtime. GLEW handles this automatically — one call to glewInit() after context creation makes all supported extensions available.
NanoLang's modules/glew/glew.nano exposes GLEW alongside a rich set of core OpenGL functions and the nl_gl3_* helpers that make the modern shader/VBO pipeline accessible from NanoLang.
Overview
The GLEW module provides:
glewInit()— loads all available OpenGL extensionsglewIsSupported()— query extension availability- Core OpenGL state functions:
glClear,glEnable,glViewport,glBlendFunc, etc. - The matrix stack:
glMatrixMode,glLoadIdentity,glOrtho,glPushMatrix, etc. - Lighting:
nl_glLightfv4,nl_glMaterialfv4 - Modern pipeline helpers:
nl_gl3_*for shaders, VBOs, textures, framebuffers
Why GLEW Is Needed
OpenGL ships with a minimal set of functions linked at build time (OpenGL 1.1 on Windows, OpenGL 2.1 on macOS). Everything beyond that — GLSL shaders, vertex buffer objects, uniform variables, framebuffer objects — lives in extensions. On each platform, the driver exposes these through function pointers that must be loaded with glXGetProcAddress (Linux), wglGetProcAddress (Windows), or NSGLGetProcAddress (macOS).
GLEW hides this complexity. After glewInit(), you can call any extension function the driver supports as if it were a regular function.
Initialization
Call glewInit() **after** making an OpenGL context current (via GLFW or SDL):
from "modules/glfw/glfw.nano" import glfwMakeContextCurrent
from "modules/glew/glew.nano" import glewInit, glewGetErrorString, GLEW_OK
(glfwMakeContextCurrent window)
let err: int = (glewInit)
if (!= err GLEW_OK) {
let msg: string = (glewGetErrorString err)
(print msg)
return
}
GLEW_OK is 0 — a non-zero return indicates an error.
Checking Extension Support
Before using a feature, verify the driver supports it:
from "modules/glew/glew.nano" import glewIsSupported
let has_vbo: int = (glewIsSupported "GL_ARB_vertex_buffer_object")
let has_fbo: int = (glewIsSupported "GL_ARB_framebuffer_object")
let has_instancing: int = (glewIsSupported "GL_ARB_instanced_arrays")
if (== has_vbo 0) {
(print "VBOs not supported — need a newer driver")
}
Querying Renderer Information
from "modules/glew/glew.nano" import glGetString, glewGetString
# OpenGL version string (e.g. "4.6.0 NVIDIA 535.183.01")
let version: string = (glGetString 0x1F02) # GL_VERSION
# Renderer name (e.g. "NVIDIA GeForce RTX 3080")
let renderer: string = (glGetString 0x1F01) # GL_RENDERER
# GLEW version string
let glew_ver: string = (glewGetString 0x0001) # GLEW_VERSION
Error Checking
from "modules/glew/glew.nano" import glGetError, GL_NO_ERROR
let e: int = (glGetError)
if (!= e GL_NO_ERROR) {
(print "OpenGL error detected")
}
Call glGetError after suspicious operations during development. In production, remove error checks from the inner render loop for performance.
Core OpenGL State Functions
These core functions are part of the GLEW module in NanoLang:
Clear
from "modules/glew/glew.nano" import glClear, nlg_glClearColor,
GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT
(nlg_glClearColor 0.1 0.1 0.2 1.0)
(glClear GL_COLOR_BUFFER_BIT)
(glClear (+ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
Viewport
from "modules/glew/glew.nano" import glViewport
(glViewport 0 0 800 600) # x, y, width, height
Enable / Disable
from "modules/glew/glew.nano" import glEnable, glDisable,
GL_DEPTH_TEST, GL_BLEND, GL_CULL_FACE, GL_LIGHTING, GL_NORMALIZE
(glEnable GL_DEPTH_TEST)
(glEnable GL_BLEND)
(glDisable GL_CULL_FACE)
Blending
from "modules/glew/glew.nano" import glBlendFunc, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
(glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA)
Depth
from "modules/glew/glew.nano" import glDepthFunc, GL_LESS
(glDepthFunc GL_LESS)
Cull Face
from "modules/glew/glew.nano" import glCullFace, GL_BACK
(glCullFace GL_BACK)
Matrix Stack
from "modules/glew/glew.nano" import
glMatrixMode, glLoadIdentity, glOrtho, glFrustum,
glPushMatrix, glPopMatrix,
nlg_glTranslatef, nlg_glRotatef, nlg_glScalef,
GL_MODELVIEW, GL_PROJECTION
# Orthographic (2D) projection
(glMatrixMode GL_PROJECTION)
(glLoadIdentity)
(glOrtho 0.0 800.0 0.0 600.0 -1.0 1.0)
# Perspective projection
(glMatrixMode GL_PROJECTION)
(glLoadIdentity)
(glFrustum -1.0 1.0 -0.75 0.75 0.1 100.0)
# Object transforms
(glMatrixMode GL_MODELVIEW)
(glLoadIdentity)
(glPushMatrix)
(nlg_glTranslatef 0.5 0.0 -2.0)
(nlg_glRotatef 30.0 0.0 1.0 0.0)
(nlg_glScalef 0.5 0.5 0.5)
# draw object here
(glPopMatrix)
Lighting
from "modules/glew/glew.nano" import
glEnable, glShadeModel, glColorMaterial,
nl_glLightfv4, nl_glMaterialfv4, nlg_glMaterialf,
GL_LIGHTING, GL_LIGHT0, GL_COLOR_MATERIAL,
GL_POSITION, GL_DIFFUSE, GL_AMBIENT, GL_SPECULAR,
GL_FRONT, GL_SHININESS, GL_SMOOTH
(glEnable GL_LIGHTING)
(glEnable GL_LIGHT0)
(glShadeModel GL_SMOOTH)
# Point light at (3, 5, 3)
(nl_glLightfv4 GL_LIGHT0 GL_POSITION 3.0 5.0 3.0 1.0)
(nl_glLightfv4 GL_LIGHT0 GL_DIFFUSE 1.0 0.95 0.85 1.0)
(nl_glLightfv4 GL_LIGHT0 GL_AMBIENT 0.15 0.15 0.2 1.0)
# Shiny material
(nl_glMaterialfv4 GL_FRONT GL_SPECULAR 1.0 1.0 1.0 1.0)
(nlg_glMaterialf GL_FRONT GL_SHININESS 64.0)
# Allow glColor3f to drive material color
(glEnable GL_COLOR_MATERIAL)
(glColorMaterial GL_FRONT GL_AMBIENT_AND_DIFFUSE)
Modern Pipeline: Shaders and VBOs (nl_gl3_*)
The nl_gl3_* helpers bridge NanoLang's type system to the modern OpenGL 3+ pipeline.
Compiling Shaders
from "modules/glew/glew.nano" import
nl_gl3_create_program_from_sources,
nl_gl3_use_program, nl_gl3_delete_program
let vert: string = "
#version 330 core
layout(location = 0) in vec2 pos;
layout(location = 1) in vec3 col;
out vec3 vColor;
void main() {
gl_Position = vec4(pos, 0.0, 1.0);
vColor = col;
}
"
let frag: string = "
#version 330 core
in vec3 vColor;
out vec4 fragColor;
void main() {
fragColor = vec4(vColor, 1.0);
}
"
let prog: int = (nl_gl3_create_program_from_sources vert frag)
# Activate the program for drawing
(nl_gl3_use_program prog)
# Cleanup when done
(nl_gl3_delete_program prog)
Uniform Variables
from "modules/glew/glew.nano" import
nl_gl3_get_uniform_location,
nl_gl3_uniform1f, nl_gl3_uniform2f, nl_gl3_uniform1i
let loc_time: int = (nl_gl3_get_uniform_location prog "uTime")
let loc_res: int = (nl_gl3_get_uniform_location prog "uResolution")
(nl_gl3_uniform1f loc_time 1.23)
(nl_gl3_uniform2f loc_res 800.0 600.0)
(nl_gl3_uniform1i (nl_gl3_get_uniform_location prog "uTexture") 0)
Vertex Buffers (VBOs) and Vertex Arrays (VAOs)
from "modules/glew/glew.nano" import
nl_gl3_gen_vertex_array, nl_gl3_bind_vertex_array,
nl_gl3_gen_buffer, nl_gl3_bind_buffer, nl_gl3_buffer_data_f32,
nl_gl3_enable_vertex_attrib_array, nl_gl3_vertex_attrib_pointer_f32,
nl_gl3_draw_arrays,
GL_ARRAY_BUFFER, GL_STATIC_DRAW, GL_TRIANGLES
# Interleaved: [x, y, r, g, b] per vertex
let data: array<float> = [
0.0, 0.5, 1.0, 0.0, 0.0, # top, red
-0.5, -0.5, 0.0, 1.0, 0.0, # bottom-left, green
0.5, -0.5, 0.0, 0.0, 1.0 # bottom-right, blue
]
let vao: int = (nl_gl3_gen_vertex_array)
let vbo: int = (nl_gl3_gen_buffer)
(nl_gl3_bind_vertex_array vao)
(nl_gl3_bind_buffer GL_ARRAY_BUFFER vbo)
(nl_gl3_buffer_data_f32 GL_ARRAY_BUFFER data GL_STATIC_DRAW)
# Attribute 0: position (2 floats, stride 20 bytes, offset 0)
(nl_gl3_enable_vertex_attrib_array 0)
(nl_gl3_vertex_attrib_pointer_f32 0 2 0 20 0)
# Attribute 1: color (3 floats, stride 20 bytes, offset 8 bytes)
(nl_gl3_enable_vertex_attrib_array 1)
(nl_gl3_vertex_attrib_pointer_f32 1 3 0 20 8)
# Draw in render loop:
(nl_gl3_use_program prog)
(nl_gl3_bind_vertex_array vao)
(nl_gl3_draw_arrays GL_TRIANGLES 0 3)
Index Buffers (EBOs)
from "modules/glew/glew.nano" import
nl_gl3_gen_buffer, nl_gl3_bind_buffer, nl_gl3_buffer_data_u32,
GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW
let indices: array<int> = [0, 1, 2, 0, 2, 3] # two triangles = quad
let ebo: int = (nl_gl3_gen_buffer)
(nl_gl3_bind_buffer GL_ELEMENT_ARRAY_BUFFER ebo)
(nl_gl3_buffer_data_u32 GL_ELEMENT_ARRAY_BUFFER indices GL_STATIC_DRAW)
Instanced Drawing
from "modules/glew/glew.nano" import
nl_gl3_vertex_attrib_divisor, nl_gl3_draw_arrays_instanced, GL_TRIANGLES
# divisor=1 means this attribute advances once per instance, not per vertex
(nl_gl3_vertex_attrib_divisor 2 1)
# Draw 1000 instances of a 3-vertex triangle
(nl_gl3_draw_arrays_instanced GL_TRIANGLES 0 3 1000)
Textures
from "modules/glew/glew.nano" import
nl_gl3_gen_texture, nl_gl3_bind_texture, nl_gl3_active_texture,
nl_gl3_tex_parami, nl_gl3_tex_image_2d_checker_rgba8,
GL_TEXTURE_2D, GL_TEXTURE0,
GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER,
GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T,
GL_LINEAR, GL_NEAREST, GL_REPEAT
let tex: int = (nl_gl3_gen_texture)
(nl_gl3_bind_texture GL_TEXTURE_2D tex)
(nl_gl3_tex_parami GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR)
(nl_gl3_tex_parami GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST)
(nl_gl3_tex_parami GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEAT)
(nl_gl3_tex_parami GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEAT)
# Fill with a procedural checkerboard for testing
(nl_gl3_tex_image_2d_checker_rgba8 GL_TEXTURE_2D 256 256 8)
# Bind to texture unit 0 when rendering
(nl_gl3_active_texture GL_TEXTURE0)
(nl_gl3_bind_texture GL_TEXTURE_2D tex)
Framebuffer Objects (FBOs)
from "modules/glew/glew.nano" import
nl_gl3_gen_framebuffer, nl_gl3_bind_framebuffer,
nl_gl3_framebuffer_texture_2d, nl_gl3_check_framebuffer_status,
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, GL_FRAMEBUFFER_COMPLETE
let fbo: int = (nl_gl3_gen_framebuffer)
(nl_gl3_bind_framebuffer GL_FRAMEBUFFER fbo)
# Attach a texture as the color buffer
(nl_gl3_framebuffer_texture_2d GL_FRAMEBUFFER GL_COLOR_ATTACHMENT0 GL_TEXTURE_2D render_tex 0)
let status: int = (nl_gl3_check_framebuffer_status GL_FRAMEBUFFER)
if (!= status GL_FRAMEBUFFER_COMPLETE) {
(print "Framebuffer not complete")
}
# Render to texture here, then unbind:
(nl_gl3_bind_framebuffer GL_FRAMEBUFFER 0) # 0 = default framebuffer (screen)
Flush and Finish
from "modules/glew/glew.nano" import glFlush, glFinish
(glFlush) # flush commands to GPU (non-blocking)
(glFinish) # wait until GPU has finished all pending commands (blocking)
glFlush is rarely needed explicitly; glfwSwapBuffers flushes automatically. glFinish is useful for benchmarking GPU work.
API Summary
| Function | Description |
|---|---|
glewInit() | Initialize GLEW, load extensions |
glewIsSupported(name) | 1 if extension is available |
glewGetString(name) | GLEW info string |
glewGetErrorString(error) | Error description |
glGetError() | Get last GL error code |
glGetString(name) | GL info string |
glClear(mask) | Clear buffers |
nlg_glClearColor(r, g, b, a) | Set clear color |
glViewport(x, y, w, h) | Set viewport rectangle |
glEnable(cap) / glDisable(cap) | Toggle GL capability |
glBlendFunc(src, dst) | Set blend equation |
glDepthFunc(func) | Set depth test function |
glCullFace(mode) | Set cull face |
glMatrixMode(mode) | Select active matrix |
glLoadIdentity() | Reset to identity matrix |
glOrtho(...) | Set orthographic projection |
glFrustum(...) | Set perspective projection |
glPushMatrix() / glPopMatrix() | Save/restore matrix |
nlg_glTranslatef(x, y, z) | Translate matrix |
nlg_glRotatef(angle, x, y, z) | Rotate matrix |
nlg_glScalef(x, y, z) | Scale matrix |
glShadeModel(mode) | Set smooth/flat shading |
glColorMaterial(face, mode) | Track material from glColor |
nl_glLightfv4(light, pname, ...) | Set light parameter (4 floats) |
nl_glMaterialfv4(face, pname, ...) | Set material parameter (4 floats) |
nl_gl3_create_program_from_sources(vert, frag) | Compile GLSL shader program |
nl_gl3_use_program(prog) | Activate shader program |
nl_gl3_delete_program(prog) | Free shader program |
nl_gl3_get_uniform_location(prog, name) | Get uniform location |
nl_gl3_uniform1f(loc, v) | Set float uniform |
nl_gl3_uniform2f(loc, x, y) | Set vec2 uniform |
nl_gl3_uniform1i(loc, v) | Set int/sampler uniform |
nl_gl3_gen_vertex_array() | Create VAO |
nl_gl3_bind_vertex_array(vao) | Bind VAO |
nl_gl3_gen_buffer() | Create VBO/EBO |
nl_gl3_bind_buffer(target, buf) | Bind buffer |
nl_gl3_buffer_data_f32(target, data, usage) | Upload float array to GPU |
nl_gl3_buffer_data_u32(target, data, usage) | Upload int array to GPU |
nl_gl3_enable_vertex_attrib_array(idx) | Enable vertex attribute |
nl_gl3_vertex_attrib_pointer_f32(idx, size, norm, stride, offset) | Describe attribute layout |
nl_gl3_draw_arrays(mode, first, count) | Draw vertices |
nl_gl3_draw_arrays_instanced(mode, first, count, instances) | Draw instanced |
nl_gl3_gen_texture() | Create texture object |
nl_gl3_bind_texture(target, tex) | Bind texture |
nl_gl3_active_texture(unit) | Select texture unit |
nl_gl3_tex_parami(target, pname, param) | Set texture parameter |
nl_gl3_gen_framebuffer() | Create FBO |
nl_gl3_bind_framebuffer(target, fbo) | Bind FBO |
nl_gl3_framebuffer_texture_2d(...) | Attach texture to FBO |
nl_gl3_check_framebuffer_status(target) | Verify FBO completeness |
---
**Previous:** 17.2 GLFW
**Next:** 17.4 GLUT