<!DOCTYPE html>
<head>
<title>Example 2</title>
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f0f0;
}
canvas {
display: block;
margin: 20px auto;
border: 1px solid #ccc;
width: 400px;
height: 300px;
}
h1 {
color: green;
margin-top: 20px;
}
h3 {
color: black;
margin-bottom: 20px;
}
.shader-input {
width: 80%;
max-width: 600px;
height: 100px;
margin: 10px auto;
display: block;
font-family: monospace;
padding: 10px;
border: 1px solid #ccc;
box-sizing: border-box;
background-color: #fff;
}
.controls {
margin: 20px;
padding: 10px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.compile-btn {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: darkred;
color: #fff;
border: none;
border-radius: 5px;
transition: background-color 0.3s;
}
.compile-btn:hover {
background-color: red;
}
h4 {
color: #333;
margin-bottom: 10px;
}
</style>
</head>
<body onload="start()">
<h1>GeeksforGeeks</h1>
<h3>Approach 2: Shader Compilation from Input Fields</h3>
<canvas id="glcanvas">
Oops, your browser does not support the <code>canvas</code> tag.
</canvas>
<div class="controls">
<h4>Vertex Shader Code</h4>
<textarea id="vertexShaderInput" class="shader-input">
attribute vec3 position;
void main(void) {
gl_Position = vec4(position, 1.0);
}
</textarea>
<h4>Fragment Shader Code</h4>
<textarea id="fragmentShaderInput" class="shader-input">
precision mediump float;
uniform float uTime;
void main(void) {
vec2 st = gl_FragCoord.xy / vec2(400, 300);
float r = sin(uTime + 8.0 * 3.14159265359 * st.x);
float g = fract(sin(3.0 * 3.14159265359 * st.y));
float b = sin(uTime + 3.14159265359 * st.x * st.y);
vec3 color = vec3(r, b, g);
gl_FragColor = vec4(color, 1.0);
}
</textarea>
<button class="compile-btn" onclick="compileShadersFromInput()">Compile Shaders</button>
</div>
<script type="text/javascript">
let gl;
let shadeProg;
let vBuff;
let iBuff;
let timer = 0;
function initWebGL(){
let canvas = document.getElementById("glcanvas");
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (!gl) {
alert("Unable to initialize WebGL. Your browser may not support it.");
return;
}
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
initBuffers();
}
function compileShadersFromInput() {
let vertexShaderCode = document.getElementById('vertexShaderInput').value;
let fragmentShaderCode = document.getElementById('fragmentShaderInput').value;
compileShaders(vertexShaderCode, fragmentShaderCode);
}
function compileShaders(vertexCode, fragmentCode){
if (shadeProg) {
gl.deleteProgram(shadeProg);
}
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexCode);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
alert("Vertex Shader Compilation Error: " + gl.getShaderInfoLog(vertexShader));
return;
}
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentCode);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
alert("Fragment Shader Compilation Error: " + gl.getShaderInfoLog(fragmentShader));
return;
}
shadeProg = gl.createProgram();
gl.attachShader(shadeProg, vertexShader);
gl.attachShader(shadeProg, fragmentShader);
gl.linkProgram(shadeProg);
if (!gl.getProgramParameter(shadeProg, gl.LINK_STATUS)) {
alert("Program Linking Error: " + gl.getProgramInfoLog(shadeProg));
return;
}
render();
}
function initBuffers(){
let vertices = new Float32Array([
-1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, -1.0, 0.0
]);
vBuff = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuff);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
let indices = new Uint16Array([0, 1, 3, 2]);
iBuff = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuff);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
}
function animationLoop(){
requestAnimationFrame(animationLoop);
render();
}
function render(){
if (!shadeProg) return;
timer += 0.1;
gl.useProgram(shadeProg);
let attId = gl.getAttribLocation(shadeProg, "position");
gl.enableVertexAttribArray(attId);
gl.bindBuffer(gl.ARRAY_BUFFER, vBuff);
gl.vertexAttribPointer(attId, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuff);
gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_SHORT, 0);
}
function start(){
initWebGL();
animationLoop();
}
</script>
</body>
</html>