Opengl 20
MRT allowed a fragment shader to output color to several different buffers simultaneously. This enabled advanced techniques like deferred shading—a game-changer for real-time lighting with dozens of dynamic lights.
To appreciate OpenGL 2.0, you must understand its predecessor. OpenGL 1.0 (1992) through 1.5 (2003) used a fixed-function pipeline. Imagine an assembly line:
This pipeline was fast and predictable, but it was also a straightjacket. Want a toon-shaded character? A heat-haze distortion? Water that ripples with sine waves? You had to trick the fixed pipeline or fall back to software CPU rendering.
Platforms like Shadertoy (though requiring OGL 3.0+ features) owe their existence to the programmable pipeline that OGL 2.0 democratized. Artists learned to "code art" because GLSL was approachable and well-documented.
Yes—but with caveats.
The golden rule: Teach OpenGL 2.0 to understand the concepts of GPUs. Then move to OpenGL 4.6+ for real-world shipping code.
The year was 2001, and the graphics programming world was a kingdom divided. On one side stood the wizards of Direct3D, armed with a powerful, if capricious, new magic called shaders. On the other side knelt the followers of OpenGL, the ancient and noble order of the Fixed-Function Pipeline.
Mark Kilgard, a principal engineer at NVIDIA and a knight of the OpenGL Architectural Review Board (ARB), stared at the glowing runes on his monitor. For a decade, the OpenGL way had been pure: glBegin(), glVertex(), glEnd(). A state machine of immutable laws. You told the hardware the light was a point source, the material was shiny bronze, and the transformation was a perspective projection. The hardware obeyed, predictably, beautifully. But it was rigid.
Then came the whispers from the valley of Redmond. Microsoft’s DirectX 8 had introduced programmable shaders. Developers could now write tiny, custom programs that ran directly on the graphics hardware, bending the very concept of a "vertex" or a "pixel." A triangle was no longer just a triangle; it could be a wave, a field of grass, a piece of a melting dream.
"We are losing the ecosystem," Barthold Lichtenbelt, a senior manager at NVIDIA and another ARB member, said during a tense conference call. The line crackled with the ghosts of SGI, ATI, and 3Dlabs. "Game developers are defecting. They say OpenGL is a dinosaur. A beautiful, reliable dinosaur. But a dinosaur nonetheless."
The ARB was a peculiar body. It was a committee of rivals: engineers from competing hardware companies, software architects from middleware firms, and academics who cared only about mathematical purity. Reaching a consensus was like herding cats that all believed they were lions.
The problem was profound. OpenGL’s soul was its stability. Adding a full programmable shader model would be like grafting jet engines onto a steam locomotive. But the alternative was irrelevance.
The flashpoint came in the summer of 2002. A young, fiery developer from ATI (who would later become a legend in the field) released a white paper showing a stunning ocean scene. It was rendered in real-time, with waves that refracted light based on their height and angle. The demo was written in DirectX 9’s HLSL. The footnote was a dagger: "Impossible to achieve efficiently in OpenGL 1.4."
Kilgard slammed his fist on his desk in Austin, Texas. "That's a lie," he muttered. "It's not impossible. It's just… excruciating."
And there was the rub. OpenGL could do shaders, using a clunky, assembly-like language called ARB_vertex_program and ARB_fragment_program. You had to write raw GPU assembly, manage registers manually, and there was no compiler to help you. It was powerful, but it was also a punishment. opengl 20
The ARB convened at the Siggraph conference in San Antonio. The air in the cramped hotel conference room smelled of stale coffee and desperation. The debate raged for two days.
"Ideally, we should extend the assembly model," argued a purist from SGI. "It’s low-level, it’s honest, it maps directly to the metal."
"It maps directly to the metal of today," retorted an engineer from 3Dlabs. "What about tomorrow? Hardware evolves faster than this committee breathes. We need an abstraction."
Kilgard had an epiphany in the middle of the second night. He was doodling on a napkin, sketching the classic OpenGL pipeline: vertices to transformed vertices to fragments to pixels. He drew a box over the old transform/lighting stage and labeled it "Vertex Processor." He drew a box over the texture/fog stage and labeled it "Fragment Processor."
He realized they didn't need to replace the fixed-function pipeline. They needed to subsume it. The old way would become just one special, pre-written program among infinite possibilities.
The next morning, he pitched a radical compromise: OpenGL 2.0 would not remove a single feature. Every call to glBegin(), glLight(), and glTexEnv() would still work. But the underlying machinery would be reimagined.
They would create a new shading language. Not assembly. Not a derivative of C++ (which would be too political). But a new, clean, C-like language specifically for graphics. They would call it GLSL – the OpenGL Shading Language.
And crucially, they would build a compiler right into the OpenGL driver. The application would send the shader source code as strings, and the driver would compile it at runtime into the hardware’s native assembly. This was insane. Compilers are hard. Real-time compilers in a graphics driver were unheard of. But it was the only way to keep OpenGL both high-level and hardware-agnostic.
The committee fell silent. It was risky. It was ambitious. It was… brilliant.
Over the next 18 months, the war was fought in code. ATI and NVIDIA, bitter rivals, had to agree on a single shading language specification. Every comma, every keyword like uniform and varying, was a battleground. Kilgard wrote the first compiler for NVIDIA’s hardware. His counterparts at ATI did the same.
There were dark days. The first prototype was slow. Compiling a shader took seconds, not milliseconds. The first attempts to run the old fixed-function pipeline on top of the new shader system were laughably broken – triangles disappeared, lights shone through solid walls.
But gradually, the magic happened. In the fall of 2003, a developer at NVIDIA wrote a simple GLSL shader:
varying vec3 color;
void main()
color = gl_Normal * 0.5 + 0.5;
gl_Position = ftransform();
And when they ran it, a simple cube rendered, its colors mapping to its vertex normals. It was a trivial shader. But it was the first breath of a new life.
On the 7th of July, 2004, the ARB finally ratified OpenGL 2.0. The press release was dry, full of language about "programmable shading" and "backward compatibility." But for those who knew, it was a declaration of war won. MRT allowed a fragment shader to output color
The reaction was mixed. Traditionalists scoffed. "GLSL is verbose," they said. "The compiler is a black box. I liked my assembly." And for a while, they were right. The early drivers were buggy. Shader compilation would stutter in the middle of a game.
But then, something beautiful happened. Small tools began to appear. A developer in Germany wrote a real-time shader editor. A student in Japan wrote a library to convert RenderMan shaders to GLSL. The community, which OpenGL had almost lost, came roaring back.
Suddenly, the ocean waves from that ATI demo were being recreated in OpenGL, not just matched, but exceeded. People wrote shaders to paint with watercolors, to simulate fur, to create entire alien planets from a handful of vertices.
And deep in the heart of the driver, the old, rigid pipeline didn't die. It simply put on a new cloak. A call to glBegin(GL_TRIANGLES) was now secretly translated into a short, efficient GLSL shader behind the scenes. The dinosaur had not been replaced. It had learned to code.
OpenGL 2.0 didn't just save the API. It transformed its very nature. It turned every graphics programmer from a mere draftsman into a conjurer of laws. The fixed function was a memory. The programmable pipeline was the future. And it began, as these things often do, not with a thunderclap, but with a single, elegant compromise scrawled on a napkin in a hotel room in Texas.
The year was 2004, and the Silicon Knights were restless. For years, the world of 3D graphics had been a rigid place—a "Fixed-Function Pipeline" where light and shadow followed strict, hard-coded rules. If you wanted a pixel to look like chrome, you had to trick the machine. You couldn’t teach it. Then came OpenGL 2.0.
It wasn't just an update; it was a coup. At the heart of this revolution was GLSL—the OpenGL Shading Language. For the first time, developers weren't just toggling switches; they were writing poetry in C-style code that ran directly on the GPU.
In a dimly lit studio, a lone programmer named Elias sat before a flickering CRT monitor. He tired of the plastic-looking worlds of the past. He opened a text editor and began to write a "Fragment Shader." void main() ...
With a few lines of code, he defined the way light scattered across a digital pond. He didn't use the old glBegin and glEnd commands of his ancestors. He utilized Vertex Buffer Objects (VBOs), streaming thousands of points of data into the card's memory like a high-speed river.
When he hit "Run," the screen didn't just show a blue polygon. It showed a surface that rippled with heat haze, a metallic sheen that reflected a virtual sun, and shadows that softened at the edges. "It's alive," he whispered.
OpenGL 2.0 had broken the chains. It turned the graphics card from a calculator into a canvas, ushering in the era of programmable shaders that would eventually define the look of every modern game we play today. The fixed world was dead; the programmable world had begun.
Should we look into the specific code for a basic 2.0 shader, or
OpenGL 2.0 marked a revolutionary shift in the world of computer graphics, transitioning from a rigid, fixed-function model to a flexible, programmable one. Released on September 7, 2004, it introduced the OpenGL Shading Language (GLSL), allowing developers to write custom code for the graphics processor (GPU). The Evolution to Programmability
Before version 2.0, OpenGL relied on a fixed-function pipeline. This meant the mathematical operations for lighting and geometry were hard-coded into the drivers. If a developer wanted a unique visual effect, they were limited to toggling pre-defined switches. This pipeline was fast and predictable, but it
OpenGL 2.0 changed this by making the following core features standard:
GLSL 1.10: A C-style language used to write "shaders"—small programs that run directly on the GPU to handle vertex and fragment processing.
Multiple Render Targets (MRT): The ability to render to several buffers simultaneously, which is essential for advanced techniques like deferred shading.
Non-Power-of-Two (NPOT) Textures: Lifting the restriction that textures must have dimensions like , allowing for more flexible asset creation.
Point Sprites: Screen-aligned textured quadrilaterals that simplified the rendering of particles and effects. Impact on Industry and Development
The shift to version 2.0 democratized high-end graphics. It enabled real-time effects—such as bump mapping and complex HDR lighting—that were previously only possible on specialized workstations.
Its influence also extended to mobile devices through OpenGL ES 2.0, which was heavily based on the desktop 2.0 specification. This mobile standard eliminated most fixed-function features entirely, forcing a "shader-only" approach that defined a decade of mobile gaming on Android and iOS. Common Modern Issues: "OpenGL 2.0 Required"
Despite being decades old, OpenGL 2.0 remains a baseline for many modern lightweight applications. Users often encounter errors stating "OpenGL 2.0 required" when:
Before OpenGL 2.0, texture dimensions had to be powers of two (64, 128, 256). This wasted video memory and complicated asset pipelines. OpenGL 2.0 relaxed this restriction, allowing any size texture (with some performance caveats).
Crucially, OpenGL 2.0 introduced GLSL (OpenGL Shading Language) — a C-like language compiled at runtime. No more writing GPU assembly (like NVidia's Cg or ARB assembly). A simple GLSL vertex shader:
#version 110 attribute vec4 a_position; attribute vec3 a_color; varying vec3 v_color; uniform mat4 u_mvpMatrix;
void main() v_color = a_color; gl_Position = u_mvpMatrix * a_position;
And a matching fragment shader:
#version 110 varying vec3 v_color;
void main() gl_FragColor = vec4(v_color, 1.0);
This replaced hundreds of lines of glBegin()/glEnd() and glLightfv() calls.