OpenGL/Utah teapot: Difference between revisions

m
(Added Kotlin)
m (→‎{{header|Wren}}: Minor tidy)
 
(19 intermediate revisions by 9 users not shown)
Line 1:
{{draft task|OpenGL}}
 
This is a way to render the classic Utah Teapot using OpenGL library.
 
See also: [https://en.wikipedia.org/wiki/Utah_teapot Utah Teapot wikipage].
<br><br>
 
=={{header|C}}==
Line 9 ⟶ 10:
 
This implementation sticks to the task requirements and only shows the teapot, it's rotating, so you can enjoy it's magnificence from all possible viewpoints and perspectives.
<syntaxhighlight lang="c">
<lang C>
/*Abhishek Ghosh, MahaShoshti, 26th September 2017*/
 
#include<gl/freeglut.h>
 
Line 61 ⟶ 60:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#include "fbgfx.bi"
#include once "GL/glut.bi"
 
Dim Shared As Double rot = 0.0
 
Sub onIdle Cdecl ()
rot += 0.01
glutPostRedisplay()
End Sub
 
Sub display Cdecl ()
Dim matCol(0 To 3) As Const GLfloat = {1, 0, 0, 0}
glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
glPushMatrix()
glRotatef(30, 1, 1, 0)
glRotatef(rot, 0, 1, 1)
glMaterialfv GL_FRONT, GL_DIFFUSE, @matCol(0)
glutWireTeapot(0.5)
glPopMatrix()
glFlush()
End Sub
 
Sub init Cdecl ()
Dim white(0 To 3) As Const GLfloat = {1, 1, 1, 0}
Dim shini(1) As Const GLfloat = {70}
glClearColor(0.5, 0.5, 0.5, 0)
glShadeModel(GL_SMOOTH)
glLightfv(GL_LIGHT0, GL_AMBIENT, @white(0))
glLightfv(GL_LIGHT0, GL_DIFFUSE, @white(0))
glMaterialfv(GL_FRONT, GL_SHININESS, @shini(0))
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_DEPTH_TEST)
End Sub
 
Var argc = Cint(0)
glutInit(0, Strptr( " " ))
glutInitDisplayMode GLUT_SINGLE Or GLUT_RGB Or GLUT_DEPTH
glutInitWindowSize(900, 700)
glutCreateWindow("Utah Teapot")
glutIdleFunc(@onIdle)
glutDisplayFunc(@display)
init()
glutMainLoop()</syntaxhighlight>
 
=={{header|Go}}==
{{trans|C}}
{{libheader|FreeGLUT}}
<br>
Although there are a number of third party Go bindings for OpenGL, the following uses 'cgo' to interface directly with the C libraries.
<syntaxhighlight lang="go">package main
 
/*
#cgo LDFLAGS: -lGL -lGLU -lglut
#include <stdlib.h>
#include <GL/freeglut.h>
 
extern void display();
extern void onIdle();
 
typedef void (*callback) ();
 
static inline callback displayFunc() {
return display;
}
 
static inline callback idleFunc() {
return onIdle;
}
*/
import "C"
import "unsafe"
 
var rot = 0.0
var matCol = [4]C.float{1, 0, 0, 0}
 
//export display
func display() {
C.glClear(C.GL_COLOR_BUFFER_BIT | C.GL_DEPTH_BUFFER_BIT)
C.glPushMatrix()
C.glRotatef(30, 1, 1, 0)
C.glRotatef(C.float(rot), 0, 1, 1)
C.glMaterialfv(C.GL_FRONT, C.GL_DIFFUSE, &matCol[0])
C.glutWireTeapot(0.5)
C.glPopMatrix()
C.glFlush()
}
 
//export onIdle
func onIdle() {
rot += 0.01
C.glutPostRedisplay()
}
 
func initialize() {
white := [4]C.float{1, 1, 1, 0}
shini := [1]C.float{70}
C.glClearColor(0.5, 0.5, 0.5, 0)
C.glShadeModel(C.GL_SMOOTH)
C.glLightfv(C.GL_LIGHT0, C.GL_AMBIENT, &white[0])
C.glLightfv(C.GL_LIGHT0, C.GL_DIFFUSE, &white[0])
C.glMaterialfv(C.GL_FRONT, C.GL_SHININESS, &shini[0])
C.glEnable(C.GL_LIGHTING)
C.glEnable(C.GL_LIGHT0)
C.glEnable(C.GL_DEPTH_TEST)
}
 
func main() {
argc := C.int(0)
C.glutInit(&argc, nil)
C.glutInitDisplayMode(C.GLUT_SINGLE | C.GLUT_RGB | C.GLUT_DEPTH)
C.glutInitWindowSize(900, 700)
tl := "The Amazing, Rotating Utah Teapot brought to you in OpenGL via freeglut."
tlc := C.CString(tl)
C.glutCreateWindow(tlc)
initialize()
C.glutDisplayFunc(C.displayFunc())
C.glutIdleFunc(C.idleFunc())
C.glutMainLoop()
C.free(unsafe.Pointer(tlc))
}</syntaxhighlight>
 
=={{header|J}}==
{{trans|C}}
{{libheader|FreeGLUT}}
<br>
Direct translation from C.
<syntaxhighlight lang="j">NB. Teapot using freeglut
require '~Projects/freeglut/gldefs.ijs'
 
f=: 1.1-1.1
void=: 0$''
 
rot=: f+0
matCol=: f+1 0 0 0
 
cb1=: cdcb '+ x x'
cb2=: cdcb '+ x x x'
 
cdcallback=: 3 : 0
y=. 15!:17''
select. #y
case. 1 do. display 0
case. 2 do. onIdle 0
end.
)
 
display=: 3 : 0
glClear(GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT)
glPushMatrix void
glRotatef((30+f);(1+f);(1+f);f)
glRotatef(rot;f;(1+f);(1+f))
glMaterialfv(GL_FRONT;GL_DIFFUSE;<matCol)
glutWireTeapot(0.5)
glPopMatrix void
glFlush void
)
 
onIdle=: 3 : 0
rot=: rot+0.01
glutPostRedisplay void
)
 
init=: 3 : 0
pos=. f+1,1,1,0
white=. f+1,1,1,0
shini=. ,f+70
glClearColor(0.5;0.5;0.5;f)
glShadeModel(GL_SMOOTH)
glLightfv(GL_LIGHT0;GL_AMBIENT;white)
glLightfv(GL_LIGHT0;GL_DIFFUSE;white)
glMaterialfv(GL_FRONT;GL_SHININESS;shini)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_DEPTH_TEST)
)
 
main=: 3 : 0
argC=. ,2-2
argV=.<,0{a.
 
glutInit(argC;argV)
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE;GLUT_ACTION_GLUTMAINLOOP_RETURNS)
glutInitDisplayMode(GLUT_SINGLE+GLUT_RGB+GLUT_DEPTH)
glutInitWindowSize(900;700)
glutCreateWindow(<'The Amazing, Rotating Utah Teapot brought to you in OpenGL via freeglut.')
init void
glutDisplayFunc(cb1)
glutIdleFunc(cb2)
glutMainLoop void
void
)</syntaxhighlight>
 
=={{header|Julia}}==
Makie implements OpenGL shading graphics as part of its plotting functionality. The files are from the University of Utah site.
<syntaxhighlight lang="julia">using Makie, FileIO, InfoZIP
 
if stat("newell_teaset/teapot.obj").size == 0
download("https://www.cs.utah.edu/~natevm/newell_teaset/newell_teaset.zip", "newell_teaset.zip")
InfoZIP.unzip("newell_teaset.zip")
end
 
utah_teapot = FileIO.load("newell_teaset/teapot.obj")
scene = plot(utah_teapot; color = :aquamarine, shading=true, show_axis=false)
rotate!(scene, Quaternion(0.6, 0.2, 0.2, 4.0))
display(scene)
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|C}}
{{libheader|freeglutFreeGLUT}}
{{works with|Ubuntu 14.04}}
Assuming that freeglut is already installed on your system in the default location(s), you first need to build opengl.klib using the following .def file and the cinterop tool:
Line 75 ⟶ 284:
</pre>
You then need to compile the following Kotlin program, linking against opengl.klib, and run the resulting .kexe file to view the rotating teapot.
<langsyntaxhighlight lang="scala">// Kotlin Native v0.6
 
import kotlinx.cinterop.*
Line 125 ⟶ 334:
glutIdleFunc(staticCFunction(::onIdle))
glutMainLoop()
}</langsyntaxhighlight>
 
=={{header|Nim}}==
{{trans|C}}
{{libheader|OpenGL}}
{{libheader|Nim bindings for OpenGL}}
<syntaxhighlight lang="nim">import opengl, opengl/glut
 
var
rot = 0.0
matCol = [GLfloat 1, 0, 0, 0]
 
proc onIdle() {.cdecl.} =
rot += 0.01
glutPostRedisplay()
 
proc display() {.cdecl.} =
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glPushMatrix()
glRotatef(30, 1, 1, 0)
glRotatef(rot, 0, 1, 1)
glMaterialfv(GL_FRONT, GL_DIFFUSE, addr(matCol[0]))
glutWireTeapot(0.5)
glPopMatrix()
glFlush()
 
var argc: cint = 0
glutInit(addr(argc), nil)
glutInitDisplayMode(GLUT_SINGLE or GLUT_RGB or GLUT_DEPTH)
glutInitWindowSize(900, 700)
discard glutCreateWindow("Utah Teapot")
glutIdleFunc(onIdle)
glutDisplayFunc(display)
loadExtensions()
glutMainLoop()</syntaxhighlight>
 
=={{header|Ol}}==
{{libheader|GL}}{{libheader|GLU}}
<langsyntaxhighlight lang="lisp">
; initial data:
(define vertices '(
Line 244 ⟶ 487:
(for-each render Handle:)
(for-each render Spout:))
</syntaxhighlight>
</lang>
 
=={{header|Phix}}==
{{trans|C}}
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (freeglut, allocate, poke, OpenGL 1.0)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">GL</span><span style="color: #0000FF;">/</span><span style="color: #000000;">gl</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">GL</span><span style="color: #0000FF;">/</span><span style="color: #000000;">freeglut</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">rot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">;</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">matCol</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">matCol</span><span style="color: #0000FF;">,</span>
<span style="color: #7060A8;">atom_to_float32</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: #7060A8;">atom_to_float32</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: #7060A8;">atom_to_float32</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: #7060A8;">atom_to_float32</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: #008080;">function</span> <span style="color: #7060A8;">display</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">glClear</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">or_bits</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: #7060A8;">glPushMatrix</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">glRotatef</span><span style="color: #0000FF;">(</span><span style="color: #000000;">30</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>
<span style="color: #7060A8;">glRotatef</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rot</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;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">glMaterialfv</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_FRONT</span><span style="color: #0000FF;">,</span><span style="color: #000000;">GL_DIFFUSE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">matCol</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">glutWireTeapot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glPopMatrix</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: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">onIdle</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">rot</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">0.01</span>
<span style="color: #000000;">glutPostRedisplay</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">init</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">white</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">white</span><span style="color: #0000FF;">,</span>
<span style="color: #7060A8;">atom_to_float32</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: #7060A8;">atom_to_float32</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: #7060A8;">atom_to_float32</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: #7060A8;">atom_to_float32</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: #004080;">atom</span> <span style="color: #000000;">shini</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shini</span><span style="color: #0000FF;">,</span>
<span style="color: #7060A8;">atom_to_float32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">70</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glClearColor</span><span style="color: #0000FF;">(.</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,.</span><span style="color: #000000;">5</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;">glShadeModel</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_SMOOTH</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">glLightfv</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_LIGHT0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">GL_AMBIENT</span><span style="color: #0000FF;">,</span><span style="color: #000000;">white</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">glLightfv</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_LIGHT0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">GL_DIFFUSE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">white</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">glMaterialfv</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_FRONT</span><span style="color: #0000FF;">,</span><span style="color: #000000;">GL_SHININESS</span><span style="color: #0000FF;">,</span><span style="color: #000000;">shini</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glEnable</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_LIGHTING</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">glEnable</span><span style="color: #0000FF;">(</span><span style="color: #004600;">GL_LIGHT0</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: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">glutInit</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">glutInitDisplayMode</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">or_all</span><span style="color: #0000FF;">({</span><span style="color: #000000;">GLUT_SINGLE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">GLUT_RGB</span><span style="color: #0000FF;">,</span><span style="color: #000000;">GLUT_DEPTH</span><span style="color: #0000FF;">}))</span>
<span style="color: #000000;">glutInitWindowSize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">900</span><span style="color: #0000FF;">,</span><span style="color: #000000;">700</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">glutCreateWindow</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"The Amazing, Rotating Utah Teapot brought to you in OpenGL via freeglut."</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">init</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">glutDisplayFunc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">call_back</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"display"</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">glutIdleFunc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">call_back</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"onIdle"</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">glutMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
To run this, you will need the freeglut package from [http://phix.x10.mx/pmwiki/pmwiki.php?n=Main.Freeglut-TheFreeOpenglUtilityToolkit PCAN]
 
=={{header|Raku}}==
{{trans|C}}
<syntaxhighlight lang="raku" line># 20210524 Raku programming solution
 
use NativeCall;
 
my $rot = 0e0;
# https://www.khronos.org/opengl/wiki/OpenGL_Type
enum GLenum (
GL_SMOOTH => 0x1D01, GL_LIGHT0 => 0x4000, GL_AMBIENT => 0x1200,
GL_DIFFUSE => 0x1201, GL_FRONT => 0x0404, GL_SHININESS => 0x1601,
GL_LIGHTING => 0x0B50, GL_DEPTH_TEST => 0x0B71,
);
enum GLbitfield ( GL_COLOR_BUFFER_BIT => 0x00004000, GL_DEPTH_BUFFER_BIT => 0x00000100, );
enum GLUTdisplay_mode ( GLUT_RGB => 0x0000, GLUT_SINGLE => 0x0000, GLUT_DEPTH => 0x0010, );
 
 
constant $lib = 'glut';
sub glutInit(CArray[uint32], CArray[Str]) is native($lib) {*};
sub glutInitDisplayMode(uint32 $mode) is native($lib) {*};
sub glutInitWindowSize(int32 $width, int32 $height) is native($lib) {*};
sub glutCreateWindow(Str $str) is native($lib) {*};
sub glutDisplayFunc(&func ()) is native($lib) {*};
sub glutWireTeapot(num64 $size) is native($lib) {*};
sub glutIdleFunc(&func ()) is native($lib) {*};
sub glutPostRedisplay() is native($lib) {*};
sub glutMainLoop() is native($lib) {*};
 
 
constant $gllib = 'GL';
sub glClearColor(num32 $red, num32 $green, num32 $blue, num32 $alpha) is native($gllib) {*};
sub glShadeModel(int32) is native($gllib) {*};
sub glEnable(int32) is native($gllib) {*};
sub glClear(int32) is native($gllib) {*};
sub glRotatef(num32 $angle, num32 $x, num32 $y, num32 $z) is native($gllib) {*};
sub glPushMatrix() is native($gllib) {*};
sub glPopMatrix() is native($gllib) {*};
sub glFlush() is native($gllib) {*};
sub glLightfv (int32, int32, CArray[num32]) is native($gllib) {*};
sub glMaterialfv(int32, int32, CArray[num32]) is native($gllib) {*};
 
 
sub init {
glClearColor(.5e0,.5e0,.5e0,0e0);
glShadeModel(GL_SMOOTH);
glLightfv(GL_LIGHT0,GL_AMBIENT,CArray[num32].new: 1e0,1e0,1e0,0e0); # white
glLightfv(GL_LIGHT0,GL_DIFFUSE,CArray[num32].new: 1e0,1e0,1e0,0e0); # white
glMaterialfv(GL_FRONT,GL_SHININESS,CArray[num32].new: 70e0); # skinless so no effect ?
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
 
sub display {
glClear(GL_COLOR_BUFFER_BIT+|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(30e0,1e0,1e0,0e0);
glRotatef($rot,0e0,1e0,1e0);
glMaterialfv(GL_FRONT,GL_DIFFUSE, CArray[num32].new: 0e0,1e0,0e0,0e0); # green
glutWireTeapot(.5e0);
glPopMatrix();
glFlush();
}
 
sub onIdle {
$rot += 0.1e0; # changed from 0.01 for faster rotation rate
glutPostRedisplay();
}
 
 
glutInit(CArray[uint32].new,CArray[Str].new);
glutInitDisplayMode(GLUT_SINGLE+|GLUT_RGB+|GLUT_DEPTH);
glutInitWindowSize(900,700);
glutCreateWindow("The Amazing, Rotating Utah Teapot brought to you in OpenGL via freeglut.");
init();
glutDisplayFunc(&display);
glutIdleFunc(&onIdle);
glutMainLoop();
</syntaxhighlight>
 
Output: [https://drive.google.com/file/d/1XdLJhCRZ79cwDBPD7XDoRFeNFKc94-kp/view (Offsite Media file) ]
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|FreeGLUT}}
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_Utah_teapot.wren */
 
var Rot = 0
var MatCol = [1, 0, 0, 0]
 
var GL_COLOR_BUFFER_BIT = 0x4000
var GL_DEPTH_BUFFER_BIT = 0x0100
 
var GL_SMOOTH = 0x1d01
var GL_FRONT = 0x0404
var GL_DIFFUSE = 0x1201
var GL_LIGHT0 = 0x4000
var GL_AMBIENT = 0x1200
var GL_LIGHTING = 0x0b50
var GL_SHININESS = 0x1601
var GL_DEPTH_TEST = 0x0B71
 
var GLUT_SINGLE = 0x0000
var GLUT_RGB = 0x0000
var GLUT_DEPTH = 0x0010
 
var GLUT_ACTION_ON_WINDOW_CLOSE = 0x01f9
var GLUT_ACTION_GLUTMAINLOOP_RETURNS = 0x0001
 
class GL {
foreign static clearColor(red, green, blue, alpha)
 
foreign static clear(mask)
 
foreign static shadeModel(mode)
 
foreign static pushMatrix()
 
foreign static rotatef(angle, x, y, z)
 
foreign static materialfv(face, pname, params)
 
foreign static popMatrix()
 
foreign static flush()
 
foreign static lightfv(light, pname, params)
 
foreign static enable(cap)
}
 
class Glut {
foreign static initDisplayMode(mode)
 
foreign static initWindowSize(width, height)
 
foreign static createWindow(name)
 
foreign static displayFunc(clazz, method)
 
foreign static idleFunc(clazz, method)
 
foreign static postRedisplay()
 
foreign static wireTeapot(dSize)
 
foreign static setOption(eWhat, value)
}
 
class GLCallbacks {
static display() {
GL.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
GL.pushMatrix()
GL.rotatef(30, 1, 1, 0)
GL.rotatef(Rot, 0, 1, 1)
GL.materialfv(GL_FRONT, GL_DIFFUSE, MatCol)
Glut.wireTeapot(0.5)
GL.popMatrix()
GL.flush()
}
 
static onIdle() {
Rot = Rot + 0.01
Glut.postRedisplay()
}
}
 
var init = Fn.new {
var white = [1, 1, 1, 0]
var shini = [70]
 
GL.clearColor(0.5, 0.5, 0.5, 0)
GL.shadeModel(GL_SMOOTH)
GL.lightfv(GL_LIGHT0, GL_AMBIENT, white)
GL.lightfv(GL_LIGHT0, GL_DIFFUSE, white)
GL.materialfv(GL_FRONT, GL_SHININESS, shini)
GL.enable(GL_LIGHTING)
GL.enable(GL_LIGHT0)
GL.enable(GL_DEPTH_TEST)
}
 
Glut.initDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)
Glut.initWindowSize(900, 700)
Glut.createWindow("The Amazing, Rotating Utah Teapot brought to you in OpenGL via freeglut.")
init.call()
Glut.displayFunc("GLCallbacks", "display()")
Glut.idleFunc("GLCallbacks", "onIdle()")
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/gl.h>
#include <GL/freeglut.h>
#include "wren.h"
 
/* C <=> Wren interface functions */
 
WrenVM *vm;
 
const char *displayClass, *displayMethod, *idleClass, *idleMethod;
 
void display() {
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", displayClass, 0);
WrenHandle *method = wrenMakeCallHandle(vm, displayMethod);
wrenCall(vm, method);
wrenReleaseHandle(vm, method);
}
 
void idle() {
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", idleClass, 0);
WrenHandle *method = wrenMakeCallHandle(vm, idleMethod);
wrenCall(vm, method);
wrenReleaseHandle(vm, method);
}
 
void C_clearColor(WrenVM* vm) {
GLclampf red = (GLclampf)wrenGetSlotDouble(vm, 1);
GLclampf green = (GLclampf)wrenGetSlotDouble(vm, 2);
GLclampf blue = (GLclampf)wrenGetSlotDouble(vm, 3);
GLclampf alpha = (GLclampf)wrenGetSlotDouble(vm, 4);
glClearColor(red, green, blue, alpha);
}
 
void C_clear(WrenVM* vm) {
GLbitfield mask = (GLbitfield)wrenGetSlotDouble(vm, 1);
glClear(mask);
}
 
void C_shadeModel(WrenVM* vm) {
GLenum mode = (GLenum)wrenGetSlotDouble(vm, 1);
glShadeModel(mode);
}
 
void C_pushMatrix(WrenVM* vm) {
glPushMatrix();
}
 
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_materialfv(WrenVM* vm) {
GLenum face = (GLenum)wrenGetSlotDouble(vm, 1);
GLenum pname = (GLenum)wrenGetSlotDouble(vm, 2);
int count = wrenGetListCount(vm, 3);
GLfloat params[count];
int i;
for (i = 0; i < count; ++i) {
wrenGetListElement(vm, 3, i, 1);
params[i] = (GLfloat)wrenGetSlotDouble(vm, 1);
}
glMaterialfv(face, pname, (const GLfloat*)params);
}
 
void C_popMatrix(WrenVM* vm) {
glPopMatrix();
}
 
void C_flush(WrenVM* vm) {
glFlush();
}
 
void C_lightfv(WrenVM* vm) {
GLenum light = (GLenum)wrenGetSlotDouble(vm, 1);
GLenum pname = (GLenum)wrenGetSlotDouble(vm, 2);
int count = wrenGetListCount(vm, 3);
GLfloat params[count];
int i;
for (i = 0; i < count; ++i) {
wrenGetListElement(vm, 3, i, 1);
params[i] = (GLfloat)wrenGetSlotDouble(vm, 1);
}
glLightfv(light, pname, (const GLfloat*)params);
}
 
void C_enable(WrenVM* vm) {
GLenum cap = (GLenum)wrenGetSlotDouble(vm, 1);
glEnable(cap);
}
 
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_displayFunc(WrenVM* vm) {
displayClass = wrenGetSlotString(vm, 1);
displayMethod = wrenGetSlotString(vm, 2);
glutDisplayFunc(&display);
}
 
void C_idleFunc(WrenVM* vm) {
idleClass = wrenGetSlotString(vm, 1);
idleMethod = wrenGetSlotString(vm, 2);
glutIdleFunc(&idle);
}
 
void C_postRedisplay(WrenVM* vm) {
glutPostRedisplay();
}
 
void C_wireTeapot(WrenVM* vm) {
GLdouble dSize = (GLdouble)wrenGetSlotDouble(vm, 1);
glutWireTeapot(dSize);
}
 
void C_setOption(WrenVM* vm) {
GLenum eWhat = (GLenum)wrenGetSlotDouble(vm, 1);
int value = (int)wrenGetSlotDouble(vm, 2);
glutSetOption(eWhat, value);
}
 
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, "clearColor(_,_,_,_)") == 0) return C_clearColor;
if (isStatic && strcmp(signature, "clear(_)") == 0) return C_clear;
if (isStatic && strcmp(signature, "shadeModel(_)") == 0) return C_shadeModel;
if (isStatic && strcmp(signature, "pushMatrix()") == 0) return C_pushMatrix;
if (isStatic && strcmp(signature, "rotatef(_,_,_,_)") == 0) return C_rotatef;
if (isStatic && strcmp(signature, "materialfv(_,_,_)") == 0) return C_materialfv;
if (isStatic && strcmp(signature, "popMatrix()") == 0) return C_popMatrix;
if (isStatic && strcmp(signature, "flush()") == 0) return C_flush;
if (isStatic && strcmp(signature, "lightfv(_,_,_)") == 0) return C_lightfv;
if (isStatic && strcmp(signature, "enable(_)") == 0) return C_enable;
 
} 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, "displayFunc(_,_)") == 0) return C_displayFunc;
if (isStatic && strcmp(signature, "idleFunc(_,_)") == 0) return C_idleFunc;
if (isStatic && strcmp(signature, "postRedisplay()") == 0) return C_postRedisplay;
if (isStatic && strcmp(signature, "wireTeapot(_)") == 0) return C_wireTeapot;
if (isStatic && strcmp(signature, "setOption(_,_)") == 0) return C_setOption;
}
}
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_Utah_teapot.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>
9,476

edits