OpenGL
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
In this task, the goal is to display a smooth shaded triangle with OpenGL.
AutoHotkey
<lang AutoHotkey>hOpenGL32 := DllCall("LoadLibrary", "Str", "opengl32") Gui, +LastFound +Resize hDC := DllCall("GetDC", "uInt", WinExist())
VarSetCapacity(pfd, 40, 0) NumPut(40, pfd, 0, "uShort") NumPut(1, pfd, 2, "uShort") NumPut(37, pfd, 4, "uInt") NumPut(24, pfd, 9, "uChar") NumPut(16, pfd, 23, "uChar") DllCall("SetPixelFormat", "uInt", hDC, "uInt", DllCall("ChoosePixelFormat", "uInt", hDC, "uInt", &pfd), "uInt", &pfd)
hRC := DllCall("opengl32\wglCreateContext", "uInt", hDC) DllCall("opengl32\wglMakeCurrent", "uInt", hDC, "uInt", hRC) Gui, Show, w640 h480, Triangle OnExit, ExitSub SetTimer, Paint, 50 return
Paint:
DllCall("opengl32\glClearColor", "Float", 0.3, "Float", 0.3, "Float", 0.3, "Float", 0)
DllCall("opengl32\glClear", "uInt", 0x4100) ;GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
DllCall("opengl32\glShadeModel", "uInt", 0x1D01) ;GL_SMOOTH
DllCall("opengl32\glLoadIdentity") DllCall("opengl32\glTranslatef", "Float", -15, "Float", -15, "Float", 0)
DllCall("opengl32\glBegin", "uInt", 0x0004) ;GL_TRIANGLES DllCall("opengl32\glColor3f", "Float", 1, "Float", 0, "Float", 0) DllCall("opengl32\glVertex2f", "Float", 0, "Float", 0) DllCall("opengl32\glColor3f", "Float", 0, "Float", 1, "Float", 0) DllCall("opengl32\glVertex2f", "Float", 30, "Float", 0) DllCall("opengl32\glColor3f", "Float", 0, "Float", 0, "Float", 1) DllCall("opengl32\glVertex2f", "Float", 0, "Float", 30) DllCall("opengl32\glEnd")
DllCall("SwapBuffers", "uInt", hDC) return
GuiSize:
DllCall("opengl32\glViewport", "Int", 0, "Int", 0, "Int", A_GuiWidth, "Int", A_GuiHeight)
DllCall("opengl32\glMatrixMode", "uInt", 0x1701) ;GL_PROJECTION
DllCall("opengl32\glLoadIdentity")
DllCall("opengl32\glOrtho", "Double", -30, "Double", 30, "Double", -30, "Double", 30, "Double", -30, "Double", 30)
DllCall("opengl32\glMatrixMode", "uInt", 0x1700) ;GL_MODELVIEW
return
GuiClose:
ExitApp
ExitSub:
DllCall("opengl32\wglMakeCurrent", "uInt", 0, "uInt", 0)
DllCall("opengl32\wglDeleteContext", "uInt", hRC)
DllCall("ReleaseDC", "uInt", hDC)
DllCall("FreeLibrary", "uInt", hOpenGL32)
ExitApp</lang>
C
In this example, we use GLUT to create a window and handle the main loop in a portable way. Windowing systems like MS Windows and X11 have their own platform-specific ways of handling these things.
<lang c>#include<GL/gl.h>
- include<GL/glut.h>
void paint(void) { glClearColor(0.3,0.3,0.3,0.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);
glLoadIdentity(); glTranslatef(-15.0, -15.0, 0.0);
glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); glVertex2f(0.0, 0.0); glColor3f(0.0, 1.0, 0.0); glVertex2f(30.0, 0.0); glColor3f(0.0, 0.0, 1.0); glVertex2f(0.0, 30.0); glEnd();
glFlush(); }
void reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-30.0, 30.0, -30.0, 30.0, -30.0, 30.0); glMatrixMode(GL_MODELVIEW); }
int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitWindowSize(640, 480); glutCreateWindow("Triangle");
glutDisplayFunc(paint); glutReshapeFunc(reshape);
glutMainLoop();
return 0; }</lang>
C#
C# example using the OpenTK library, which is multiplatform and provides C# OpenGL bindings for .Net and Mono. This code creates it's own window and draws the triangle into it.
<lang csharp>using OpenTK; using OpenTK.Graphics; namespace OpenGLTest {
class Program { static void Main(string[] args) { //Create the OpenGL window GameWindow window = new GameWindow(640, 480, GraphicsMode.Default, "OpenGL Example");
GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Ortho(-30.0, 30.0, -30.0, 30.0, -30.0, 30.0); GL.MatrixMode(MatrixMode.Modelview);
//Add event handler to render to the window when called window.RenderFrame += new RenderFrameEvent(a_RenderFrame); //Starts the window's updating/rendering events window.Run(); } static void a_RenderFrame(GameWindow sender, RenderFrameEventArgs e) { GL.ClearColor(0.3f, 0.3f, 0.3f, 0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.ShadeModel(ShadingModel.Smooth);
GL.LoadIdentity(); GL.Translate(-15.0f, -15.0f, 0.0f);
GL.Begin(BeginMode.Triangles); GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex2(0.0f, 0.0f); GL.Color3(0.0f, 1.0f, 0.0f); GL.Vertex2(30f, 0.0f); GL.Color3(0.0f, 0.0f, 1.0f); GL.Vertex2(0.0f, 30.0f); GL.End(); //Swaps the buffers on the window so that what we draw becomes visible sender.SwapBuffers(); } }
}</lang>
Clojure
In this example, we use Penumbra, which is an idiomatic wrapper for OpenGL. <lang lisp>(use 'penumbra.opengl) (require '[penumbra.app :as app])
(defn init [state]
(app/title! "Triangle") (clear-color 0.3 0.3 0.3 0) (shade-model :smooth) state)
(defn reshape [[x y w h] state]
(ortho-view -30 30 -30 30 -30 30) (load-identity) (translate -15 -15) state)
(defn display [[dt time] state]
(draw-triangles (color 1 0 0) (vertex 0 0) (color 0 1 0) (vertex 30 0) (color 0 0 1) (vertex 0 30)))
(app/start {:display display, :reshape reshape, :init init} {})</lang>
D
opengl_sample.d: <lang d>module opengl_sample; // file name + directory import dglut.core, dglut.window, dglut.opengl;
void main() {
with (new Canvas) { setName("Triangle"); map;
onResize = (Canvas self) { // A delegate literal that takes a parameter. with (self) glViewport(0, 0, width, height); MatrixMode.Projection.Identity; // For functions without parameters, the () can be omitted. glOrtho(-30, 30, -30, 30, -30, 30); MatrixMode.Modelview; };
onDisplay=(Canvas self) { scope(exit) self.swap; // Scope guards ease exception-safe programming glClearColor(0.3f, 0.3f, 0.3f, 0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity; // A convenience wrapper around glTranslatef. Supports numbers, arrays and vectors. Translate(-15, -15, 0); // This is a delegate literal as well. Triangles is a wrapper around glBegin and glEnd. Triangles = { Color(1f, 0f, 0f); Vertex(0, 0); Color(0f, 1f, 0f); Vertex(30, 0); Color(0f, 0f, 1f); Vertex(0, 30); }; }; } loop;
}</lang>
Factor
Translated from C <lang factor>USING: kernel math math.rectangles opengl.gl sequences ui ui.gadgets ui.render ; IN: rosettacode.opengl
TUPLE: triangle-gadget < gadget ;
- reshape ( width height -- )
[ 0 0 ] 2dip glViewport GL_PROJECTION glMatrixMode glLoadIdentity -30.0 30.0 -30.0 30.0 -30.0 30.0 glOrtho GL_MODELVIEW glMatrixMode ;
- paint ( -- )
0.3 0.3 0.3 0.0 glClearColor GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT bitor glClear GL_SMOOTH glShadeModel glLoadIdentity -15.0 -15.0 0.0 glTranslatef GL_TRIANGLES glBegin 1.0 0.0 0.0 glColor3f 0.0 0.0 glVertex2f 0.0 1.0 0.0 glColor3f 30.0 0.0 glVertex2f 0.0 0.0 1.0 glColor3f 0.0 30.0 glVertex2f glEnd glFlush ;
M: triangle-gadget pref-dim* drop { 640 480 } ; M: triangle-gadget draw-gadget*
rect-bounds nip first2 reshape paint ;
- triangle-window ( -- )
[ triangle-gadget new "Triangle" open-window ] with-ui ;
MAIN: triangle-window </lang>
Forth
triangle.fs: <lang forth>import glconst import float glconst also float also opengl also</lang>
triangle.m: <lang forth>#! xbigforth \ automatic generated code \ do not edit
also editor also minos also forth
include triangle.fs component class triangle public:
early widget early open early dialog early open-app ( [varstart] ) ( [varend] )
how:
: open new DF[ 0 ]DF s" Triangle" open-component ; : dialog new DF[ 0 ]DF s" Triangle" open-dialog ; : open-app new DF[ 0 ]DF s" Triangle" open-application ;
class;
triangle implements
( [methodstart] ) ( [methodend] ) : widget ( [dumpstart] ) GL[ ^ glcanvas with
0 0 w @ h @ glViewport GL_PROJECTION glMatrixMode glLoadIdentity -30e 30e -30e 30e -30e 30e glOrtho GL_MODELVIEW glMatrixMode 0.3e 0.3e 0.3e 0.0e glClearColor GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT or glClear GL_SMOOTH glShadeModel glLoadIdentity -15e -15e 0e glTranslatef GL_TRIANGLES glBegin 1e 0e 0e glColor3f 0e 0e glVertex2f 0e 1e 0e glColor3f 30e 0e glVertex2f 0e 0e 1e glColor3f 0e 30e glVertex2f glEnd glFlush endwith ]GL ( MINOS ) ^^ CK[ ( x y b n -- ) 2drop 2drop ]CK ( MINOS ) $280 $1 *hfil $1E0 $1 *vfil glcanvas new
&1 vabox new ( [dumpend] ) ; : init ^>^^ assign widget 1 :: init ;
class;
- main
triangle open-app $1 0 ?DO stop LOOP bye ;
script? [IF] main [THEN] previous previous previous</lang>
Haskell
<lang haskell>import Graphics.Rendering.OpenGL import Graphics.UI.GLUT
main = do
getArgsAndInitialize createWindow "Triangle" displayCallback $= display matrixMode $= Projection loadIdentity ortho2D 0 30 0 30 matrixMode $= Modelview 0 mainLoop
display = do
clear [ColorBuffer] renderPrimitive Triangles $ do corner 1 0 0 5 5 corner 0 1 0 25 5 corner 0 0 1 5 25 swapBuffers
corner r g b x y = do color (Color3 r g b :: Color3 GLfloat)
vertex (Vertex2 x y :: Vertex2 GLfloat)</lang>
J
<lang J>coclass 'example' (coinsert[require) 'jzopengl'
create=:3 :0
ogl=: conew'jzopengl' wd 'pc p;cc c isigraph opengl rightmove bottommove;pas 0 0;pshow;'
)
p_close=: destroy=:3 :0
destroy__ogl wd'pclose' codestroy
)
corner=:4 :0
glColor3d x glVertex2d y
)
p_c_paint=:3 :0
rc__ogl glClear GL_COLOR_BUFFER_BIT glBegin GL_TRIANGLES 1 0 0 corner 0 0-0.5 0 1 0 corner 1 0-0.5 0 0 1 corner 0 1-0.5 glEnd show__ogl
)
conew~'example'</lang>
Note: OpenGL's initial state is well defined by the OpenGL standard.
MAXScript
The choice of OpenGL or D3D in MAX is a user configuration setting. All MAXScript code is platform independent. <lang maxscript>newMesh = mesh numVerts:3 numFaces:1 setMesh newMesh vertices:#([-100, -100, 0], [100, -100, 0], [-100, 100, 0]) faces:#([1, 2, 3]) defaultVCFaces newMesh setVertColor newMesh 1 red setVertColor newMesh 2 green setVertColor newMesh 3 blue setCVertMode newMesh true update newMesh viewport.setType #view_top max tool maximize viewport.SetRenderLevel #smoothhighlights</lang>
OCaml
<lang ocaml>open GL open Glut
let display() =
glClearColor 0.3 0.3 0.3 0.0; glClear[GL_COLOR_BUFFER_BIT; GL_DEPTH_BUFFER_BIT];
glShadeModel GL_SMOOTH;
glLoadIdentity(); glTranslate (-15.0) (-15.0) (0.0);
glBegin GL_TRIANGLES; glColor3 1.0 0.0 0.0; glVertex2 0.0 0.0; glColor3 0.0 1.0 0.0; glVertex2 30.0 0.0; glColor3 0.0 0.0 1.0; glVertex2 0.0 30.0; glEnd();
glFlush();
let reshape ~width ~height =
glViewport 0 0 width height; glMatrixMode GL_PROJECTION; glLoadIdentity(); glOrtho(-30.0) 30.0 (-30.0) 30.0 (-30.0) 30.0; glMatrixMode GL_MODELVIEW;
let () =
ignore(glutInit Sys.argv); glutInitWindowSize 640 480; ignore(glutCreateWindow "Triangle");
glutDisplayFunc ~display; glutReshapeFunc ~reshape;
glutMainLoop();
- </lang>
Perl
<lang perl>use OpenGL;
sub triangle {
glBegin GL_TRIANGLES; glColor3f 1.0, 0.0, 0.0; glVertex2f 5.0, 5.0; glColor3f 0.0, 1.0, 0.0; glVertex2f 25.0, 5.0; glColor3f 0.0, 0.0, 1.0; glVertex2f 5.0, 25.0; glEnd;
};
glpOpenWindow; glMatrixMode GL_PROJECTION; glLoadIdentity; gluOrtho2D 0.0, 30.0, 0.0, 30.0; glMatrixMode GL_MODELVIEW;
glClear GL_COLOR_BUFFER_BIT; triangle; glpFlush;
glpMainLoop;</lang>
<lang perl>use SDL::App; use SDL::Event; use SDL::OpenGL;
$app = SDL::App->new(
-gl => 1,
);
sub triangle {
glBegin(GL_TRIANGLES); glColor(1.0, 0.0, 0.0); glVertex(5.0, 5.0); glColor(0.0, 1.0, 0.0); glVertex(25.0, 5.0); glColor(0.0, 0.0, 1.0); glVertex(5.0, 25.0); glEnd();
}
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 30.0, 0.0, 30.0); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT); triangle(); $app->sync; $app->loop ({
SDL_QUIT() => sub { exit; },
});</lang>
PicoLisp
This is for the 64-bit version. <lang PicoLisp>(load "@lib/openGl.l")
(glutInit) (glutInitWindowSize 400 300) (glutCreateWindow "Triangle")
(displayPrg
(glClearColor 0.3 0.3 0.3 0.0) (glClear (| GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT)) (glShadeModel GL_SMOOTH) (glLoadIdentity) (glTranslatef -15.0 -15.0 0.0) (glBegin GL_TRIANGLES) (glColor3f 1.0 0.0 0.0) (glVertex2f 0.0 0.0) (glColor3f 0.0 1.0 0.0) (glVertex2f 30.0 0.0) (glColor3f 0.0 0.0 1.0) (glVertex2f 0.0 30.0) (glEnd) (glFlush) )
(reshapeFunc
'((Width Height) (glViewport 0 0 Width Height) (glMatrixMode GL_PROJECTION) (glLoadIdentity) (glOrtho -30.0 30.0 -30.0 30.0 -30.0 30.0) (glMatrixMode GL_MODELVIEW) ) )
- Exit upon mouse click
(mouseFunc '((Btn State X Y) (bye)))
(glutMainLoop)</lang>
Python
<lang python>#-*- coding: utf8 -*-
from OpenGL.GL import * from OpenGL.GLUT import *
def paint():
glClearColor(0.3,0.3,0.3,0.0) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glShadeModel(GL_SMOOTH)
glLoadIdentity() glTranslatef(-15.0, -15.0, 0.0)
glBegin(GL_TRIANGLES) glColor3f(1.0, 0.0, 0.0) glVertex2f(0.0, 0.0) glColor3f(0.0, 1.0, 0.0) glVertex2f(30.0, 0.0) glColor3f(0.0, 0.0, 1.0) glVertex2f(0.0, 30.0) glEnd()
glFlush()
def reshape(width, height):
glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(-30.0, 30.0, -30.0, 30.0, -30.0, 30.0) glMatrixMode(GL_MODELVIEW)
if __name__ == '__main__':
glutInit(1, 1) glutInitWindowSize(640, 480) glutCreateWindow("Triangle")
glutDisplayFunc(paint) glutReshapeFunc(reshape)
glutMainLoop()</lang>
R
<lang R>library(rgl) x <- c(-1, -1, 1) y <- c(0, -1, -1) z <- c(0, 0, 0) M <- cbind(x,y,z) rgl.bg(color="gray15") triangles3d(M, col=rainbow(8))</lang>
Ruby
<lang ruby>require 'rubygems' require 'gl' require 'glut'
include Gl include Glut
paint = lambda do
glClearColor(0.3,0.3,0.3,0.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glShadeModel(GL_SMOOTH) glLoadIdentity glTranslatef(-15.0, -15.0, 0.0) glBegin(GL_TRIANGLES) glColor3f(1.0, 0.0, 0.0) glVertex2f(0.0, 0.0) glColor3f(0.0, 1.0, 0.0) glVertex2f(30.0, 0.0) glColor3f(0.0, 0.0, 1.0) glVertex2f(0.0, 30.0) glEnd glFlush
end
reshape = lambda do |width, height|
glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity glOrtho(-30.0, 30.0, -30.0, 30.0, -30.0, 30.0) glMatrixMode(GL_MODELVIEW)
end
glutInit glutInitWindowSize(640, 480) glutCreateWindow("Triangle")
glutDisplayFunc(paint) glutReshapeFunc(reshape)
glutMainLoop</lang>
Tcl
Also requires the tcl3d package. <lang Tcl>package require Tk package require tcl3d
proc resizedWin {win w h} {
glViewport 0 0 $w $h glMatrixMode GL_PROJECTION glLoadIdentity glOrtho -30.0 30.0 -30.0 30.0 -30.0 30.0 glMatrixMode GL_MODELVIEW
} proc paintShape {win} {
glClearColor 0.0 0.0 0.0 0.5 glClear [expr {$::GL_COLOR_BUFFER_BIT+$::GL_DEPTH_BUFFER_BIT}] glShadeModel GL_SMOOTH glLoadIdentity glTranslatef -15.0 -15.0 0.0 glBegin GL_TRIANGLES glColor3f 1.0 0.0 0.0 glVertex2f 5.0 5.0 glColor3f 0.0 1.0 0.0 glVertex2f 25.0 5.0 glColor3f 0.0 0.0 1.0 glVertex2f 5.0 25.0 glEnd $win swapbuffers
}
togl .surface -width 640 -height 480 -double true -depth true \
-displayproc paintShape -reshapeproc resizedWin
pack .surface -fill both -expand 1</lang>Most of this code should be very familiar to anyone looking at the C version above, or with normal Tk applications.