Skip to content

Instantly share code, notes, and snippets.

@youngnh
Created February 19, 2010 21:59
Show Gist options
  • Save youngnh/309262 to your computer and use it in GitHub Desktop.
Save youngnh/309262 to your computer and use it in GitHub Desktop.
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
n :: [Normal3 GLfloat]
n = [(Normal3 (-1.0) 0.0 0.0),
(Normal3 0.0 1.0 0.0),
(Normal3 1.0 0.0 0.0),
(Normal3 0.0 (-1.0) 0.0),
(Normal3 0.0 0.0 1.0),
(Normal3 0.0 0.0 (-1.0))]
faces :: [[Vertex3 GLfloat]]
faces = [[(v 0), (v 1), (v 2), (v 3)],
[(v 3), (v 2), (v 6), (v 7)],
[(v 7), (v 6), (v 5), (v 4)],
[(v 4), (v 5), (v 1), (v 0)],
[(v 5), (v 6), (v 2), (v 1)],
[(v 7), (v 4), (v 0), (v 3)]]
v :: Int -> Vertex3 GLfloat
v x = Vertex3 v0 v1 v2
where v0
| x == 0 || x == 1 || x == 2 || x == 3 = -1
| x == 4 || x == 5 || x == 6 || x == 7 = 1
v1
| x == 0 || x == 1 || x == 4 || x == 5 = -1
| x == 2 || x == 3 || x == 6 || x == 7 = 1
v2
| x == 0 || x == 3 || x == 4 || x == 7 = 1
| x == 1 || x == 2 || x == 5 || x == 6 = -1
drawBox :: IO ()
drawBox = let nfaces = zip n faces
in do mapM (\(n, [v0, v1, v2, v3]) -> do
renderPrimitive Quads $ do
normal n
vertex v0
vertex v1
vertex v2
vertex v3) nfaces
return ()
display :: DisplayCallback
display = do
clear [ColorBuffer, DepthBuffer]
drawBox
swapBuffers
lightDiffuse :: Color4 GLfloat
lightDiffuse = Color4 1.0 0.0 0.0 1.0
lightPosition :: Vertex4 GLfloat
lightPosition = Vertex4 1.0 1.0 1.0 0.0
initfn :: IO ()
initfn = let light0 = Light 0
in do diffuse light0 $= lightDiffuse
position light0 $= lightPosition
light light0 $= Enabled
lighting $= Enabled
depthFunc $= Just Lequal
matrixMode $= Projection
perspective 40.0 1.0 1.0 10.0
matrixMode $= Modelview 0
lookAt (Vertex3 0.0 0.0 5.0) (Vertex3 0.0 0.0 0.0) (Vector3 0.0 1.0 0.0)
translate ((Vector3 0.0 0.0 (-1.0))::Vector3 GLfloat)
rotate 60 ((Vector3 1.0 0.0 0.0)::Vector3 GLfloat)
rotate (-20) ((Vector3 0.0 0.0 1.0)::Vector3 GLfloat)
main :: IO ()
main = do
getArgsAndInitialize
initialDisplayMode $= [DoubleBuffered, RGBMode, WithDepthBuffer]
createWindow "red 3D lighted cube"
displayCallback $= display
initfn
mainLoop
/* Copyright (c) Mark J. Kilgard, 1997. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
/* This program was requested by Patrick Earl; hopefully someone else
will write the equivalent Direct3D immediate mode program. */
#include <GL/glut.h>
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0} };
GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */
{0, 1, 2, 3},
{3, 2, 6, 7},
{7, 6, 5, 4},
{4, 5, 1, 0},
{5, 6, 2, 1},
{7, 4, 0, 3} };
GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */
void
drawBox(void)
{
int i;
for (i = 0; i < 3; i++) {
glBegin(GL_QUADS);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
}
void
display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawBox();
glutSwapBuffers();
}
void
init(void)
{
/* Setup cube vertex data. */
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
/* Enable a single OpenGL light. */
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
/* Use depth buffering for hidden surface elimination. */
glEnable(GL_DEPTH_TEST);
/* Setup the view of the cube. */
glMatrixMode(GL_PROJECTION);
gluPerspective( /* field of view in degree */ 40.0,
/* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 10.0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in positive Y direction */
/* Adjust cube position to be asthetic angle. */
glTranslatef(0.0, 0.0, -1.0);
glRotatef(60, 1.0, 0.0, 0.0);
glRotatef(-20, 0.0, 0.0, 1.0);
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("red 3D lighted cube");
glutDisplayFunc(display);
init();
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment