Initial Query

Draw an image of a triangle using WebGL in a single HTML file. Make the canvas take the full page.

LLM Generation

Query

Draw an image of a triangle using WebGL in a single HTML file. Make the canvas take the full page.

Output

Okay, here is a single HTML file that uses WebGL to draw a simple colored triangle. The canvas is styled with CSS to take up the full browser window.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL Full Page Triangle</title>
    <style>
        /* Remove default margin/padding and make body/html fill the viewport */
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden; /* Prevent scrollbars */
        }
        /* Make canvas fill its container (the body) */
        #webgl-canvas {
            display: block; /* Remove potential extra space below canvas */
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="webgl-canvas"></canvas>

    <script>
        // --- Vertex Shader ---
        // Defines how vertex positions are processed.
        const vsSource = `
            attribute vec2 a_position; // Input: 2D vertex position

            void main() {
                // Output: Clip space position (x, y, z, w)
                // z = 0.0 (2D), w = 1.0 (standard for positions)
                gl_Position = vec4(a_position, 0.0, 1.0);
            }
        `;

        // --- Fragment Shader ---
        // Defines the color of each pixel (fragment).
        const fsSource = `
            // Set default precision for floating point numbers
            precision mediump float;

            void main() {
                // Output: Color (R, G, B, Alpha) - Solid Red
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }
        `;

        // --- Main WebGL Function ---
        function main() {
            const canvas = document.getElementById('webgl-canvas');
            if (!canvas) {
                console.error("Canvas element not found!");
                return;
            }

            // Try to get the WebGL rendering context
            const gl = canvas.getContext('webgl');
            if (!gl) {
                console.error("Unable to initialize WebGL. Your browser or machine may not support it.");
                alert("Unable to initialize WebGL. Your browser or machine may not support it.");
                return;
            }

            // --- Shader Compilation and Linking ---

            // Helper function to compile a shader
            function createShader(gl, type, source) {
                const shader = gl.createShader(type);
                gl.shaderSource(shader, source);
                gl.compileShader(shader);
                const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
                if (success) {
                    return shader;
                }
                // Log error if compilation failed
                console.error("Shader compilation failed:", gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
            }

            // Helper function to link shaders into a program
            function createProgram(gl, vertexShader, fragmentShader) {
                const program = gl.createProgram();
                gl.attachShader(program, vertexShader);
                gl.attachShader(program, fragmentShader);
                gl.linkProgram(program);
                const success = gl.getProgramParameter(program, gl.LINK_STATUS);
                if (success) {
                    return program;
                }
                // Log error if linking failed
                console.error("Program linking failed:", gl.getProgramInfoLog(program));
                gl.deleteProgram(program);
                return null;
            }

            // Compile shaders
            const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource);
            const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
            if (!vertexShader || !fragmentShader) return; // Stop if shaders failed

            // Link shaders into a program
            const program = createProgram(gl, vertexShader, fragmentShader);
            if (!program) return; // Stop if program linking failed

            // --- Vertex Data and Buffers ---

            // Get the location of the 'a_position' attribute in the shader program
            const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
            if (positionAttributeLocation < 0) {
                 console.error("Failed to get the storage location of a_position");
                 return;
            }

            // Create a buffer to store vertex positions on the GPU
            const positionBuffer = gl.createBuffer();

            // Bind the buffer to the ARRAY_BUFFER target (think of it as the 'current' buffer)
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

            // Define the triangle's vertices in Clip Space coordinates (-1 to +1)
            // (x, y) pairs for each vertex
            const positions = [
                -0.5, -0.5, // Bottom-left vertex
                 0.5, -0.5, // Bottom-right vertex
                 0.0,  0.5  // Top-center vertex
            ];

            // Pass the vertex data to the buffer (using Float32Array for efficiency)
            // STATIC_DRAW hints that the data won't change often
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

            // --- Rendering ---

            // Function to resize the drawing buffer to match the display size
            function resizeCanvasToDisplaySize(canvas) {
                // Lookup the size the browser is displaying the canvas in CSS pixels.
                const displayWidth  = canvas.clientWidth;
                const displayHeight = canvas.clientHeight;

                // Check if the canvas is not the same size.
                const needResize = canvas.width  !== displayWidth ||
                                   canvas.height !== displayHeight;

                if (needResize) {
                    // Make the canvas the same size
                    canvas.width  = displayWidth;
                    canvas.height = displayHeight;
                }
                return needResize;
            }

            // Resize canvas and set viewport before drawing
            resizeCanvasToDisplaySize(gl.canvas);
            gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // Tell WebGL how to convert clip space to pixels

            // Clear the canvas (set background color)
            gl.clearColor(0.1, 0.1, 0.15, 1.0); // Dark grey background
            gl.clear(gl.COLOR_BUFFER_BIT);

            // Tell WebGL to use our shader program
            gl.useProgram(program);

            // Enable the 'a_position' attribute
            gl.enableVertexAttribArray(positionAttributeLocation);

            // Bind the position buffer again (might not be strictly necessary here, but good practice)
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

            // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
            const size = 2;          // 2 components per iteration (x, y)
            const type = gl.FLOAT;   // the data is 32bit floats
            const normalize = false; // don't normalize the data
            const stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
            const offset = 0;        // start at the beginning of the buffer
            gl.vertexAttribPointer(
                positionAttributeLocation, size, type, normalize, stride, offset);

            // Draw the triangle
            const primitiveType = gl.TRIANGLES; // Draw triangles
            const drawOffset = 0;               // Start from the first vertex
            const count = 3;                    // Number of vertices to process (3 for one triangle)
            gl.drawArrays(primitiveType, drawOffset, count);

            console.log("Triangle drawn!");
        }

        // Run the main function when the page is loaded
        window.onload = main;

    </script>
</body>
</html>
**How to use it:** 1. Save the code above as an HTML file (e.g., `triangle.html`). 2. Open the file in a modern web browser that supports WebGL (like Chrome, Firefox, Edge, Safari). You should see a red triangle centered on a dark grey background that fills the entire browser window. If you resize the window, the canvas will resize with it, but the triangle itself won't redraw or change size relative to the window unless you add more complex resizing logic within the `main` function or an animation loop. This example draws it once on load.

Extract Code

I extracted the following code from that output:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL Full Page Triangle</title>
    <style>
        /* Remove default margin/padding and make body/html fill the viewport */
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden; /* Prevent scrollbars */
        }
        /* Make canvas fill its container (the body) */
        #webgl-canvas {
            display: block; /* Remove potential extra space below canvas */
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="webgl-canvas"></canvas>

    <script>
        // --- Vertex Shader ---
        // Defines how vertex positions are processed.
        const vsSource = `
            attribute vec2 a_position; // Input: 2D vertex position

            void main() {
                // Output: Clip space position (x, y, z, w)
                // z = 0.0 (2D), w = 1.0 (standard for positions)
                gl_Position = vec4(a_position, 0.0, 1.0);
            }
        `;

        // --- Fragment Shader ---
        // Defines the color of each pixel (fragment).
        const fsSource = `
            // Set default precision for floating point numbers
            precision mediump float;

            void main() {
                // Output: Color (R, G, B, Alpha) - Solid Red
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }
        `;

        // --- Main WebGL Function ---
        function main() {
            const canvas = document.getElementById('webgl-canvas');
            if (!canvas) {
                console.error("Canvas element not found!");
                return;
            }

            // Try to get the WebGL rendering context
            const gl = canvas.getContext('webgl');
            if (!gl) {
                console.error("Unable to initialize WebGL. Your browser or machine may not support it.");
                alert("Unable to initialize WebGL. Your browser or machine may not support it.");
                return;
            }

            // --- Shader Compilation and Linking ---

            // Helper function to compile a shader
            function createShader(gl, type, source) {
                const shader = gl.createShader(type);
                gl.shaderSource(shader, source);
                gl.compileShader(shader);
                const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
                if (success) {
                    return shader;
                }
                // Log error if compilation failed
                console.error("Shader compilation failed:", gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
            }

            // Helper function to link shaders into a program
            function createProgram(gl, vertexShader, fragmentShader) {
                const program = gl.createProgram();
                gl.attachShader(program, vertexShader);
                gl.attachShader(program, fragmentShader);
                gl.linkProgram(program);
                const success = gl.getProgramParameter(program, gl.LINK_STATUS);
                if (success) {
                    return program;
                }
                // Log error if linking failed
                console.error("Program linking failed:", gl.getProgramInfoLog(program));
                gl.deleteProgram(program);
                return null;
            }

            // Compile shaders
            const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource);
            const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
            if (!vertexShader || !fragmentShader) return; // Stop if shaders failed

            // Link shaders into a program
            const program = createProgram(gl, vertexShader, fragmentShader);
            if (!program) return; // Stop if program linking failed

            // --- Vertex Data and Buffers ---

            // Get the location of the 'a_position' attribute in the shader program
            const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
            if (positionAttributeLocation < 0) {
                 console.error("Failed to get the storage location of a_position");
                 return;
            }

            // Create a buffer to store vertex positions on the GPU
            const positionBuffer = gl.createBuffer();

            // Bind the buffer to the ARRAY_BUFFER target (think of it as the 'current' buffer)
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

            // Define the triangle's vertices in Clip Space coordinates (-1 to +1)
            // (x, y) pairs for each vertex
            const positions = [
                -0.5, -0.5, // Bottom-left vertex
                 0.5, -0.5, // Bottom-right vertex
                 0.0,  0.5  // Top-center vertex
            ];

            // Pass the vertex data to the buffer (using Float32Array for efficiency)
            // STATIC_DRAW hints that the data won't change often
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

            // --- Rendering ---

            // Function to resize the drawing buffer to match the display size
            function resizeCanvasToDisplaySize(canvas) {
                // Lookup the size the browser is displaying the canvas in CSS pixels.
                const displayWidth  = canvas.clientWidth;
                const displayHeight = canvas.clientHeight;

                // Check if the canvas is not the same size.
                const needResize = canvas.width  !== displayWidth ||
                                   canvas.height !== displayHeight;

                if (needResize) {
                    // Make the canvas the same size
                    canvas.width  = displayWidth;
                    canvas.height = displayHeight;
                }
                return needResize;
            }

            // Resize canvas and set viewport before drawing
            resizeCanvasToDisplaySize(gl.canvas);
            gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // Tell WebGL how to convert clip space to pixels

            // Clear the canvas (set background color)
            gl.clearColor(0.1, 0.1, 0.15, 1.0); // Dark grey background
            gl.clear(gl.COLOR_BUFFER_BIT);

            // Tell WebGL to use our shader program
            gl.useProgram(program);

            // Enable the 'a_position' attribute
            gl.enableVertexAttribArray(positionAttributeLocation);

            // Bind the position buffer again (might not be strictly necessary here, but good practice)
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

            // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
            const size = 2;          // 2 components per iteration (x, y)
            const type = gl.FLOAT;   // the data is 32bit floats
            const normalize = false; // don't normalize the data
            const stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
            const offset = 0;        // start at the beginning of the buffer
            gl.vertexAttribPointer(
                positionAttributeLocation, size, type, normalize, stride, offset);

            // Draw the triangle
            const primitiveType = gl.TRIANGLES; // Draw triangles
            const drawOffset = 0;               // Start from the first vertex
            const count = 3;                    // Number of vertices to process (3 for one triangle)
            gl.drawArrays(primitiveType, drawOffset, count);

            console.log("Triangle drawn!");
        }

        // Run the main function when the page is loaded
        window.onload = main;

    </script>
</body>
</html>

Check if all of the following conditions are true:

HTML Render

Rendering the webpage gives the following image:

LLM Generation

Query

This is a screenshot of a webpage that draws something with webgl. I'm trying to see if it drew what I wanted. Describe what is drawn in this image?

Output

The image shows a red triangle centered on a dark gray background.

LLM Generation

Query

Does this answer say that there is a picture of a triangle "The image shows a red triangle centered on a dark gray background."? Answer "Yes it does" or "No it does not".

Output

Yes it does.

Substring Evaluation

Testing if the previous output contains the string es it does: True

Check this condition is not true:

Substring Evaluation

Testing if the previous output contains the string THREE.: False

Final Answer: True

Final Answer: True