OpenGL pixel shader: Difference between revisions

m
m (→‎{{header|Phix}}: not p2js)
m (→‎{{header|Wren}}: Minor tidy)
 
(6 intermediate revisions by 3 users not shown)
Line 11:
{{libheader|GLUT}}
Getting a true (pseudo) random number is surprisingly tricky. The following code makes something noisy, but not at all random:[[image:pixel_shader_C.png|right]]
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
Line 39:
"varying float x, y, z;"
"uniform float r_mod;"
"float rand(float s, float r) { return mod(mod(s, r + r_mod) * 112341.0, 1.0); }"
"void main() {"
" gl_FragColor = vec4(rand(gl_FragCoord.x, x), rand(gl_FragCoord.y, y), rand(gl_FragCoord.z, z), 1.0);"
"}";
const char *v =
Line 86:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|Go}}==
Line 94:
<br>
The following uses 'cgo' to bind to the above C libraries. As C macro functions cannot be invoked directly from Go code, it has been necessary to wrap them first in 'normal' C functions and then invoke those.
<langsyntaxhighlight lang="go">package main
 
/*
Line 172:
f := "varying float x, y, z;" +
"uniform float r_mod;" +
"float rand(float s, float r) { return mod(mod(s, r + r_mod) * 112341.0, 1.0); }" +
"void main() {" +
" gl_FragColor = vec4(rand(gl_FragCoord.x, x), rand(gl_FragCoord.y, y), rand(gl_FragCoord.z, z), 1.0);" +
"}"
 
Line 227:
setShader()
C.glutMainLoop()
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
 
=={{header|JavaScript}} =(WebGL) ===
 
<langsyntaxhighlight lang="javascript"><html style="margin: 0;">
<head>
<title>Fragment Shader WebGL Example</title>
Line 337 ⟶ 339:
</script>
</body>
</html></langsyntaxhighlight>
 
=={{header|Kotlin}}==
Line 352 ⟶ 354:
</pre>
You then need to compile the following Kotlin program, linking against opengl2.klib, and run the resulting .kexe file to view the rotating triangle.
<langsyntaxhighlight lang="scala">// Kotlin Native v0.6
 
import kotlinx.cinterop.*
Line 436 ⟶ 438:
setShader()
glutMainLoop()
}</langsyntaxhighlight>
 
=={{header|Ol}}==
<langsyntaxhighlight lang="scheme">
#!/usr/bin/ol
(import (lib gl2))
Line 477 ⟶ 479:
(glVertex2f -0.0 +0.7)
(glEnd)))
</syntaxhighlight>
</lang>
 
=={{header|Phix}}==
{{trans|CJavaScript}}
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
Note that several routines added for this demo have not yet added to the documentation, as you can tell from the syntax colouring.<br>
You can run this online [http://phix.x10.mx/p2js/OpenGLShader.htm here].
Likewise no attempt has yet been made to make this run under pwa/p2js.
<!--<langsyntaxhighlight Phixlang="phix">(notonlinephixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\OpenGLShader.exw</span>
-- demo\rosetta\OpenGLShader.exw
-- =============================
--
-- Works identically to the rc JavaScript entry under pwa/p2js, but on desktop/Phix
-- the colours cycle round white/blue/orange once per second. Beyond my ken anyway.
--</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">include</span> <span style="color: #0000FF;">..\</span><span style="color: #000000;">pGUI</span><span style="color: #0000FF;">\</span><span style="color: #000000;">opengl</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">Ihandln</span> <span style="color: #000000;">dlg</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">canvas</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">r_mod</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">angle</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">resize_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glViewport</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">functionconstant</span> <span style="color: #000000;">renderfragment_shader</span> <span style="color: #0000FF;">()=</span> <span style="color: #008000;">"""
precision highp float;
<span style="color: #7060A8;">glClear</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_COLOR_BUFFER_BIT</span><span style="color: #0000FF;">);</span>
uniform float u_time;
<span style="color: #000000;">glUniform1f</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r_mod</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">())</span>
void main(void) {
<span style="color: #7060A8;">glLoadIdentity</span><span style="color: #0000FF;">();</span>
// some gobbledegook
<span style="color: #000000;">glRotatef</span><span style="color: #0000FF;">(</span><span style="color: #000000;">angle</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">angle</span> <span style="color: #0000FF;">*</span> <span style="color: #0000FF;">.</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">);</span>
vec3 foo = vec3(pow(gl_FragCoord.xy, vec2(1.0 + sin(dot(vec4(1.0, 100.0, 0.0, 0.0), gl_FragCoord)))), 0.0);
<span style="color: #7060A8;">glBegin</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_TRIANGLES</span><span style="color: #0000FF;">);</span>
foo *= mat3(1.2, 3.9, 1.4, 4.1, 0.2, 1.4, 2.5, 1.6, 7.2);
<span style="color: #7060A8;">glVertex</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-.</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">);</span>
<span style="color: #7060A8;">glVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">);</span>
gl_FragColor = vec4(mod(foo + vec3(u_time), 1.0), 1.0);
<span style="color: #7060A8;">glVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">);</span>
}
<span style="color: #7060A8;">glEnd</span><span style="color: #0000FF;">();</span>
"""</span>
<span style="color: #000000;">angle</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">.</span><span style="color: #000000;">02</span><span style="color: #0000FF;">;</span>
<span style="color: #008080;">constant</span> <span style="color: #7060A8000000;">glFlushvertex_shader</span> <span style="color: #0000FF;">()=</span> <span style="color: #008000;">"""
attribute vec3 a_position;
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
attribute vec4 a_color;
varying vec4 v_color;
void main(void) {
gl_Position = vec4(a_position, 1.0);
v_color = a_color;
}
"""</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">vertices</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
<span style="color: #0000FF;">-</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">+</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">-</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span>
<span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">getShader</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">src</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">shader_type</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">shader</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">glCreateShader</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shader_type</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">// Compile shader from source</span>
<span style="color: #7060A8;">glShaderSource</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shader</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">src</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glCompileShader</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shader</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">glGetShaderParameter</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shader</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">GL_COMPILE_STATUS</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">glGetShaderInfoLog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shader</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">shader</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080004080;">constantinteger</span> <span style="color: #000000;">ftimeUniform</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
varying float x, y, z;
uniform float r_mod;
float rand(float s, float r) { return mod(mod(s, r + r_mod) * 112341, 1); }
void main() {
gl_FragColor = vec4(rand(gl_FragCoord.x, x), rand(gl_FragCoord.y, y), rand(gl_FragCoord.z, z), 1);
}"""</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
varying float x, y, z;
void main() {
gl_Position = ftransform();
x = gl_Position.x; y = gl_Position.y; z = gl_Position.z;
x += y; y -= x; z += x - y;
}"""</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">set_shader</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupGLMakeCurrent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">vsprog</span> <span style="color: #0000FF;">=</span> <span style="color: #0000007060A8;">glCreateShaderglCreateProgram</span><span style="color: #0000FF;">(</span><span style="color: #000000;">GL_VERTEX_SHADER</span><span style="color: #0000FF;">),</span>
<span style="color: #7060A8;">glAttachShader</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prog</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">psgetShader</span> <span style="color: #0000FF;">=(</span> <span style="color: #000000;">glCreateShadervertex_shader</span><span style="color: #0000FF;">(,</span><span style="color: #000000004600;">GL_FRAGMENT_SHADERGL_VERTEX_SHADER</span><span style="color: #0000FF;">))</span>
<span style="color: #0000007060A8;">glShaderSourceglAttachShader</span><span style="color: #0000FF;">(</span><span style="color: #000000;">psprog</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">fgetShader</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fragment_shader</span><span style="color: #0000FF;">,</span><span style="color: #004600;">GL_FRAGMENT_SHADER</span><span style="color: #0000FF;">))</span>
<span style="color: #0000007060A8;">glShaderSourceglLinkProgram</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">vprog</span><span style="color: #0000FF;">)</span>
<span style="color: #000000008080;">glCompileShaderif</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">glGetProgramParameter</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vsprog</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">GL_LINK_STATUS</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #0000007060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">glCompileShaderglGetProgramInfoLog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">psprog</span><span style="color: #0000FF;">))</span>
<span style="color: #004080008080;">integerend</span> <span style="color: #000000008080;">prog</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">glCreateProgram</span><span style="color: #0000FF;">()if</span>
<span style="color: #0000007060A8;">glAttachShaderglUseProgram</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prog</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ps</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">glAttachShader</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prog</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vs</span><span style="color: #0000FF;">)</span>
<span style="color: #000000000080;">glLinkProgram</span><span font-style="color: #0000FFitalic;">(</span><span/ style="color:Get #000000;">prog</span><spanthe style="color:indexes #0000FF;">)to communicate vertex attributes to the program.</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">glUseProgrampositionAttr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">glGetAttribLocation</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prog</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"a_position"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">// And specify that we will be actually delivering data to those attributes.</span>
<span style="color: #000000;">r_mod</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">glGetUniformLocation</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prog</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"r_mod"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glEnableVertexAttribArray</span><span style="color: #0000FF;">(</span><span style="color: #000000;">positionAttr</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">timeUniform</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">glGetUniformLocation</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prog</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"u_time"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">// Store vertex positions and colors in array buffer objects.</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">positionBuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">glCreateBuffer</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">glBindBuffer</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_ARRAY_BUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">positionBuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">integer</span> <span style="color: #000000;">size</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">pData</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">glFloat32Array</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vertices</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glBufferData</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_ARRAY_BUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">size</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pData</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">GL_STATIC_DRAW</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glEnable</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_DEPTH_TEST</span><span style="color: #0000FF;">);</span>
<span style="color: #000080;font-style:italic;">//Specify the array data to render. </span>
<span style="color: #7060A8;">glBindBuffer</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_ARRAY_BUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">positionBuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glVertexAttribPointer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">positionAttr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">GL_FLOAT</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glClearColor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glViewport</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glUniform1f</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timeUniform</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">glClear</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_COLOR_BUFFER_BIT</span> <span style="color: #0000FF;">||</span> <span style="color: #004600;">GL_DEPTH_BUFFER_BIT</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">numVertices</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vertices</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">;</span> <span style="color: #000080;font-style:italic;">// 3 coordinates per vertex</span>
<span style="color: #7060A8;">glDrawArrays</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_TRIANGLES</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">numVertices</span><span style="color: #0000FF;">);</span>
<span style="color: #7060A8;">glFlush</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
Line 551 ⟶ 602:
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGLCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RESIZE_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"resize_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #008000;">"RASTERSIZE=640x480"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TITLE=OpenGLShader, SHRINK=YES"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupShowIupMap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">set_shader</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupSetGlobalFunctionIupShow</span><span style="color: #0000FF;">(</span><span style="color: #008000000000;">"IDLE_ACTION"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"render"dlg</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">timer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">1000</span><span style="color: #0000FF;">/</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #000000008080;">dlg</span> <span style="color: #0000FF;">=if</span> <span style="color: #7060A8;">IupDestroyplatform</span><span style="color: #0000FF;">()!=</span><span style="color: #000000004600;">dlgJS</span> <span style="color: #0000FF008080;">)then</span>
<span style="color: #7060A8;">IupCloseIupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDestroy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket/gui
(require typed/opengl)
Line 638 ⟶ 692:
(define gl (new my-canvas% [parent win]))
(send win show #t)</langsyntaxhighlight>
 
=={{header|Tcl}}==
Line 646 ⟶ 700:
Using the [http://www.tcl3d.org Tcl3d] library and liberally borrowing from [http://wiki.tcl.tk/41477 this pixel shader demo on the wiki], here is a brute translation of the C implementation.
 
<syntaxhighlight lang="tcl">
<lang Tcl>
package require tcl3d
 
Line 709 ⟶ 763:
set_shader
render
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|FreeGLUT}}
{{libheader|GLEW}}
<br>
As it's not currently possible for Wren-cli to access OpenGL directly, we embed a Wren script in a C application to complete this task. See the [[OpenGL#Wren]] task for some of the issues involved here.
<syntaxhighlight lang="wren">/* OpenGL_pixel_shader.wren */
 
import "random" for Random
 
var GL_COLOR_BUFFER_BIT = 0x4000
 
var GL_TRIANGLES = 0x0004
 
var GL_VERTEX_SHADER = 0x8b31
var GL_FRAGMENT_SHADER = 0x8b30
 
var GLUT_ACTION_ON_WINDOW_CLOSE = 0x01f9
var GLUT_ACTION_GLUTMAINLOOP_RETURNS = 0x0001
 
var GLUT_DOUBLE = 0x0002
var GLUT_RGB = 0x0000
 
var Rand = Random.new()
 
var Angle = 0
var R_mod = 0
 
class GL {
foreign static clear(mask)
 
foreign static uniform1f(location, v0)
 
foreign static loadIdentity()
 
foreign static rotatef(angle, x, y, z)
 
foreign static begin(mode)
 
foreign static vertex3f(x, y, z)
 
foreign static end()
 
foreign static createShader(shaderType)
 
foreign static shaderSource(shader, count, string, length)
 
foreign static compileShader(shader)
 
foreign static createProgram()
 
foreign static attachShader(program, shader)
 
foreign static linkProgram(program)
 
foreign static useProgram(program)
 
foreign static getUniformLocation(program, name)
}
 
class Glut {
foreign static initDisplayMode(mode)
 
foreign static initWindowSize(width, height)
 
foreign static createWindow(name)
 
foreign static swapBuffers()
 
foreign static idleFunc(clazz, signature)
 
foreign static setOption(eWhat, value)
}
 
class Glew {
foreign static init()
 
foreign static isSupported(name)
}
 
class GLCallbacks {
static render() {
GL.clear(GL_COLOR_BUFFER_BIT)
GL.uniform1f(R_mod, Rand.float())
GL.loadIdentity()
GL.rotatef(Angle, Angle * 0.1, 1, 0)
GL.begin(GL_TRIANGLES)
GL.vertex3f(-1, -0.5, 0)
GL.vertex3f(0, 1, 0)
GL.vertex3f(1, 0, 0)
GL.end()
Angle = Angle + 0.02
Glut.swapBuffers()
}
}
 
var setShader = Fn.new {
var f =
"varying float x, y, z;
uniform float r_mod;
float rand(float s, float r) { return mod(mod(s, r + r_mod) * 112341.0, 1.0);}
void main() {
gl_FragColor = vec4(rand(gl_FragCoord.x, x), rand(gl_FragCoord.y, y), rand(gl_FragCoord.z, z), 1.0);
}"
 
var v =
"varying float x, y, z;
void main() {
gl_Position = ftransform();
x = gl_Position.x; y = gl_Position.y; z = gl_Position.z;
x += y; y -= x; z += x - y;
}"
 
var vs = GL.createShader(GL_VERTEX_SHADER)
var ps = GL.createShader(GL_FRAGMENT_SHADER)
GL.shaderSource(ps, 1, f, null)
GL.shaderSource(vs, 1, v, null)
 
GL.compileShader(vs)
GL.compileShader(ps)
 
var prog = GL.createProgram()
GL.attachShader(prog, ps)
GL.attachShader(prog, vs)
 
GL.linkProgram(prog)
GL.useProgram(prog)
R_mod = GL.getUniformLocation(prog, "r_mod")
}
 
Glut.initDisplayMode(GLUT_DOUBLE | GLUT_RGB)
Glut.initWindowSize(200, 200)
Glut.createWindow("Stuff")
Glut.idleFunc("GLCallbacks", "render()")
Glew.init()
if (!Glew.isSupported("GL_VERSION_2_0")) {
System.print("GL 2.0 unsupported\n")
return
}
setShader.call()
Glut.setOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS)</syntaxhighlight>
<br>
We now embed this Wren script in the following C program, compile and run it.
<syntaxhighlight lang="c">#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/freeglut.h>
#include "wren.h"
 
/* C <=> Wren interface functions */
 
WrenVM *vm;
 
const char *idleClass, *idleMethod;
 
void idle() {
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", idleClass, 0);
WrenHandle *method = wrenMakeCallHandle(vm, idleMethod);
wrenCall(vm, method);
wrenReleaseHandle(vm, method);
}
 
void C_clear(WrenVM* vm) {
GLbitfield mask = (GLbitfield)wrenGetSlotDouble(vm, 1);
glClear(mask);
}
 
void C_uniform1f(WrenVM* vm) {
GLint location = (GLint)wrenGetSlotDouble(vm, 1);
GLfloat v0 = (GLfloat)wrenGetSlotDouble(vm, 2);
glUniform1f(location, v0);
}
 
void C_loadIdentity(WrenVM* vm) {
glLoadIdentity();
}
 
void C_rotatef(WrenVM* vm) {
GLdouble angle = (GLdouble)wrenGetSlotDouble(vm, 1);
GLdouble x = (GLdouble)wrenGetSlotDouble(vm, 2);
GLdouble y = (GLdouble)wrenGetSlotDouble(vm, 3);
GLdouble z = (GLdouble)wrenGetSlotDouble(vm, 4);
glRotatef(angle, x, y, z);
}
 
void C_begin(WrenVM* vm) {
GLenum mode = (GLenum)wrenGetSlotDouble(vm, 1);
glBegin(mode);
}
 
void C_vertex3f(WrenVM* vm) {
GLfloat x = (GLfloat)wrenGetSlotDouble(vm, 1);
GLfloat y = (GLfloat)wrenGetSlotDouble(vm, 2);
GLfloat z = (GLfloat)wrenGetSlotDouble(vm, 3);
glVertex3f(x, y, z);
}
 
void C_end(WrenVM* vm) {
glEnd();
}
 
void C_createShader(WrenVM* vm) {
GLenum shaderType = (GLenum)wrenGetSlotDouble(vm, 1);
GLuint shader = glCreateShader(shaderType);
wrenSetSlotDouble(vm, 0, (double)shader);
}
 
void C_shaderSource(WrenVM* vm) {
GLuint shader = (GLuint)wrenGetSlotDouble(vm, 1);
GLsizei count = (GLsizei)wrenGetSlotDouble(vm, 2);
// assume for simplicity there will always be one shader string and the fourth parameter will be null
const GLchar *string = (const GLchar *)wrenGetSlotString(vm, 3);
glShaderSource(shader, count, &string, 0);
}
 
void C_compileShader(WrenVM* vm) {
GLuint shader = (GLuint)wrenGetSlotDouble(vm, 1);
glCompileShader(shader);
// check shader compiled ok
GLint shader_compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_compiled);
if (shader_compiled != GL_TRUE) {
GLsizei log_length = 0;
GLchar message[1024];
glGetShaderInfoLog(shader, 1024, &log_length, message);
printf("%s\n", message);
}
}
 
void C_createProgram(WrenVM* vm) {
GLuint program = glCreateProgram();
wrenSetSlotDouble(vm, 0, (double)program);
}
 
void C_attachShader(WrenVM* vm) {
GLuint program = (GLuint)wrenGetSlotDouble(vm, 1);
GLuint shader = (GLuint)wrenGetSlotDouble(vm, 2);
glAttachShader(program, shader);
}
 
void C_linkProgram(WrenVM* vm) {
GLuint program = (GLuint)wrenGetSlotDouble(vm, 1);
// check program linked ok
glBindAttribLocation(program, 0, "position");
glBindAttribLocation(program, 1, "texcoord");
glBindAttribLocation(program, 2, "normal");
glBindAttribLocation(program, 3, "color");
glLinkProgram(program);
GLint program_linked;
glGetProgramiv(program, GL_LINK_STATUS, &program_linked);
if (program_linked != GL_TRUE) {
GLsizei log_length = 0;
GLchar message[1024];
glGetProgramInfoLog(program, 1024, &log_length, message);
printf("%s\n", message);
}
}
 
void C_useProgram(WrenVM* vm) {
GLuint program = (GLuint)wrenGetSlotDouble(vm, 1);
glUseProgram(program);
}
 
void C_getUniformLocation(WrenVM* vm) {
GLuint program = (GLuint)wrenGetSlotDouble(vm, 1);
const GLchar *name = (const GLchar *)wrenGetSlotString(vm, 2);
GLint location = glGetUniformLocation(program, name);
wrenSetSlotDouble(vm, 0, (double)location);
}
 
void C_initDisplayMode(WrenVM* vm) {
unsigned int mode = (unsigned int)wrenGetSlotDouble(vm, 1);
glutInitDisplayMode(mode);
}
 
void C_initWindowSize(WrenVM* vm) {
int width = (int)wrenGetSlotDouble(vm, 1);
int height = (int)wrenGetSlotDouble(vm, 2);
glutInitWindowSize(width, height);
}
 
void C_createWindow(WrenVM* vm) {
const char *name = wrenGetSlotString(vm, 1);
glutCreateWindow(name);
}
 
void C_swapBuffers(WrenVM* vm) {
glutSwapBuffers();
}
 
void C_idleFunc(WrenVM* vm) {
idleClass = wrenGetSlotString(vm, 1);
idleMethod = wrenGetSlotString(vm, 2);
glutIdleFunc(&idle);
}
 
void C_setOption(WrenVM* vm) {
GLenum eWhat = (GLenum)wrenGetSlotDouble(vm, 1);
int value = (int)wrenGetSlotDouble(vm, 2);
glutSetOption(eWhat, value);
}
 
void C_init(WrenVM* vm) {
glewInit();
}
 
void C_isSupported(WrenVM* vm) {
const char *name = (const char *)wrenGetSlotString(vm, 1);
GLboolean supported = glewIsSupported(name);
wrenSetSlotBool(vm, 0, (bool)supported);
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "GL") == 0) {
if (isStatic && strcmp(signature, "clear(_)") == 0) return C_clear;
if (isStatic && strcmp(signature, "uniform1f(_,_)") == 0) return C_uniform1f;
if (isStatic && strcmp(signature, "loadIdentity()") == 0) return C_loadIdentity;
if (isStatic && strcmp(signature, "rotatef(_,_,_,_)") == 0) return C_rotatef;
if (isStatic && strcmp(signature, "begin(_)") == 0) return C_begin;
if (isStatic && strcmp(signature, "vertex3f(_,_,_)") == 0) return C_vertex3f;
if (isStatic && strcmp(signature, "end()") == 0) return C_end;
if (isStatic && strcmp(signature, "createShader(_)") == 0) return C_createShader;
if (isStatic && strcmp(signature, "shaderSource(_,_,_,_)") == 0) return C_shaderSource;
if (isStatic && strcmp(signature, "compileShader(_)") == 0) return C_compileShader;
if (isStatic && strcmp(signature, "createProgram()") == 0) return C_createProgram;
if (isStatic && strcmp(signature, "attachShader(_,_)") == 0) return C_attachShader;
if (isStatic && strcmp(signature, "linkProgram(_)") == 0) return C_linkProgram;
if (isStatic && strcmp(signature, "useProgram(_)") == 0) return C_useProgram;
if (isStatic && strcmp(signature, "getUniformLocation(_,_)") == 0) return C_getUniformLocation;
} else if (strcmp(className, "Glut") == 0) {
if (isStatic && strcmp(signature, "initDisplayMode(_)") == 0) return C_initDisplayMode;
if (isStatic && strcmp(signature, "initWindowSize(_,_)") == 0) return C_initWindowSize;
if (isStatic && strcmp(signature, "createWindow(_)") == 0) return C_createWindow;
if (isStatic && strcmp(signature, "swapBuffers()") == 0) return C_swapBuffers;
if (isStatic && strcmp(signature, "idleFunc(_,_)") == 0) return C_idleFunc;
if (isStatic && strcmp(signature, "setOption(_,_)") == 0) return C_setOption;
} else if (strcmp(className, "Glew") == 0) {
if (isStatic && strcmp(signature, "init()") == 0) return C_init;
if (isStatic && strcmp(signature, "isSupported(_)") == 0) return C_isSupported;
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
int main(int argc, char **argv) {
glutInit(&argc, argv);
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignMethodFn = &bindForeignMethod;
vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "OpenGL_pixel_shader.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
glutMainLoop();
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
Same as C example.
</pre>
 
{{omit from|Blast}}
9,476

edits