OpenGL

From Rosetta Code
Task
OpenGL
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.

Triangle created using C example compiled with GCC 4.1.2 and freeglut3.

C

Library: GLUT

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>

  1. 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>

D

Works with: GDC
Works with: DMD
Library: dglut

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>

Forth

Works with: bigFORTH
Library: MINOS
Library: Theseus

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>

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

Library: glMLite

<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>
Library: SDL

<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>

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>

Tcl

Library: Tk

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.