svn path=/trunk/tao/; revision=67650
This commit is contained in:
David Hudson 2006-11-09 23:22:55 +00:00
Родитель 1c24444d52
Коммит 3d2fd92d2b
19 изменённых файлов: 3017 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,670 @@
#region License
/*
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
#region Original Credits/License
/*
Copyright (c) 2002-2004 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Marcus Geelnard
marcus.geelnard at home.se
*/
/*****************************************************************************
* Title: GLBoing
* Desc: Tribute to Amiga Boing.
* Author: Jim Brooks <gfx@jimbrooks.org>
* Original Amiga authors were R.J. Mical and Dale Luck.
* GLFW conversion by Marcus Geelnard
* Notes: - 360' = 2*PI [radian]
*
* - Distances between objects are created by doing a relative
* Z translations.
*
* - Although OpenGL enticingly supports alpha-blending,
* the shadow of the original Boing didn't affect the color
* of the grid.
*
* - [Marcus] Changed timing scheme from interval driven to frame-
* time based animation steps (which results in much smoother
* movement)
*
* History of Amiga Boing:
*
* Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in
* 1985. According to legend, it was written ad-hoc in one night by
* R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast
* and smooth, attendees did not believe the Amiga prototype was really doing
* the rendering. Suspecting a trick, they began looking around the booth for
* a hidden computer or VCR.
*****************************************************************************/
#endregion Original Credits/License
using System;
using Tao.Glfw;
using Tao.OpenGl;
namespace GlfwExamples {
#region Class Documentation
/// <summary>
/// This is a small test application for GLFW.
/// </summary>
/// <remarks>
/// Tribute to Amiga's Boing.
/// </remarks>
#endregion Class Documentation
public sealed class Boing {
// --- Fields ---
#region Private Constants
private const float PI = 3.1415926535897932384626433832795f;
private const int RAND_MAX = 4095;
private const float RADIUS = 70;
// 22.5 makes 8 bands like original Boing
private const float STEP_LONGITUDE = 22.5f;
private const float STEP_LATITUDE = 22.5f;
private const float DISTANCE_BALL = RADIUS * 2 + RADIUS * 0.1f;
// Distance from viewer to middle of buing area
private const float VIEW_SCENE_DISTANCE = DISTANCE_BALL * 3 + 200;
// Length (width) of grid
private const float GRID_SIZE = (RADIUS * 4.5f);
private const float BOUNCE_HEIGHT = (RADIUS * 2.1f);
private const float BOUNCE_WIDTH = (RADIUS * 2.1f);
// Maximum allowed delta time per physics iteration
private const float MAX_DELTA_TIME = 0.02f;
// Animation speed (50.0 mimics the original GLUT demo speed)
private const float ANIMATION_SPEED = 50;
private const float SHADOW_OFFSET_X = -20;
private const float SHADOW_OFFSET_Y = 10;
private const float SHADOW_OFFSET_Z = 0;
private const float WALL_LEFT_OFFSET = 0;
private const float WALL_RIGHT_OFFSET = 5f;
#endregion Private Constants
#region Private Enums
#region DrawType
/// <summary>
/// Draw type.
/// </summary>
private enum DrawType {
/// <summary>
/// Draw ball.
/// </summary>
DrawBall,
/// <summary>
/// Draw ball's shadow.
/// </summary>
DrawBallShadow
}
#endregion DrawType
#endregion Private Enums
#region Private Structs
#region Vertex
/// <summary>
/// Vertex structure.
/// </summary>
private struct Vertex {
/// <summary>
/// X coordinate.
/// </summary>
public float X;
/// <summary>
/// Y coordinate.
/// </summary>
public float Y;
/// <summary>
/// Z coordinate.
/// </summary>
public float Z;
}
#endregion Vertex
#endregion Private Structs
#region Private Static Fields
private static Random rand = new Random();
private static double currentTime, oldTime, timeDifference;
private static float yRotationDegree = 0;
private static float yRotationDegreeIncrement = 2;
private static float ballX = -RADIUS;
private static float ballY = -RADIUS;
private static float ballXIncrement = 1;
private static float ballYIncrement = 2;
private static DrawType drawType;
private static bool isColor;
#endregion Private Static Fields
// --- Application Entry Point ---
#region Run()
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Run() {
bool isRunning = true;
// Initialise GLFW
Glfw.glfwInit();
if(Glfw.glfwOpenWindow(400, 400, 0, 0, 0, 0, 16, 0, Glfw.GLFW_WINDOW) == Gl.GL_FALSE) {
Glfw.glfwTerminate();
return;
}
Glfw.glfwSetWindowTitle("Boing (classic Amiga demo)");
Glfw.glfwSetWindowSizeCallback(new Glfw.GLFWwindowsizefun(Reshape));
Glfw.glfwEnable(Glfw.GLFW_STICKY_KEYS);
Glfw.glfwSwapInterval(1);
// TODO: Glfw.glfwSetTime(0.0);
Init();
// Main loop
while(isRunning) {
// Timing
currentTime = Glfw.glfwGetTime();
timeDifference = currentTime - oldTime;
oldTime = currentTime;
// Draw one frame
Display();
// Swap buffers
Glfw.glfwSwapBuffers();
// Check if we are still running
isRunning = ((Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Glfw.GLFW_RELEASE) &&
Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE);
}
// Close OpenGL window and terminate GLFW
Glfw.glfwTerminate();
}
#endregion Run()
// --- Private Static Methods ---
#region BounceBall(double timeDifference)
/// <summary>
/// Bounces the ball.
/// </summary>
/// <param name="timeDifference">
/// The time difference.
/// </param>
private static void BounceBall(double timeDifference) {
float sign;
float degree;
// Bounce on walls
if(ballX > (BOUNCE_WIDTH / 2 + WALL_RIGHT_OFFSET)) {
ballXIncrement = -0.5f - 0.75f * (float) rand.NextDouble() / (float) RAND_MAX;
yRotationDegreeIncrement = -yRotationDegreeIncrement;
}
if(ballX < -(BOUNCE_HEIGHT / 2 + WALL_LEFT_OFFSET)) {
ballXIncrement = 0.5f + 0.75f * (float) rand.NextDouble() / (float) RAND_MAX;
yRotationDegreeIncrement = -yRotationDegreeIncrement;
}
// Bounce on floor / ceiling
if(ballY > BOUNCE_HEIGHT / 2) {
ballYIncrement = -0.75f - 1.0f * (float) rand.NextDouble() / (float) RAND_MAX;
}
if(ballY < -BOUNCE_HEIGHT / 2 * 0.85f) {
ballYIncrement = 0.75f + 1 * (float) rand.NextDouble() / (float) RAND_MAX;
}
// Update ball position
ballX += (float) (ballXIncrement * (timeDifference * ANIMATION_SPEED));
ballY += (float) (ballYIncrement * (timeDifference * ANIMATION_SPEED));
// Simulate the effects of gravity on Y movement
if(ballYIncrement < 0) {
sign = -1;
}
else {
sign = 1;
}
degree = (ballY + BOUNCE_HEIGHT / 2) * 90 / BOUNCE_HEIGHT;
if(degree > 80) {
degree = 80;
}
else if(degree < 10) {
degree = 10;
}
ballYIncrement = sign * 4 * (float) SinDegree(degree);
}
#endregion BounceBall(double timeDifference)
#region double CosDegree(double degree)
/// <summary>
/// 360' Cos().
/// </summary>
/// <param name="degree">
/// The degree.
/// </param>
/// <returns>
/// The Cos.
/// </returns>
private static double CosDegree(double degree) {
return Math.Cos(DegreeToRadian(degree));
}
#endregion double CosDegree(double degree)
#region CrossProduct(Vertex a, Vertex b, Vertex c, out Vertex normal)
/// <summary>
/// Computes a cross product for a vector normal.
/// </summary>
/// <param name="a">
/// First vector.
/// </param>
/// <param name="b">
/// Second vector.
/// </param>
/// <param name="c">
/// Third vector.
/// </param>
/// <param name="normal">
/// The normalized vector.
/// </param>
private static void CrossProduct(Vertex a, Vertex b, Vertex c, out Vertex normal) {
float u1, u2, u3;
float v1, v2, v3;
u1 = b.X - a.X;
u2 = b.Y - a.Y;
u3 = b.Y - a.Z;
v1 = c.X - a.X;
v2 = c.Y - a.Y;
v3 = c.Z - a.Z;
normal.X = u2 * v3 - v2 * v3;
normal.Y = u3 * v1 - v3 * u1;
normal.Z = u1 * v2 - v1 * u2;
}
#endregion CrossProduct(Vertex a, Vertex b, Vertex c, out Vertex normal)
#region double DegreeToRadian(double degree)
/// <summary>
/// Converts a degree to a radian.
/// </summary>
/// <param name="degree">
/// The degree.
/// </param>
/// <returns>
/// The radian.
/// </returns>
private static double DegreeToRadian(double degree) {
return degree / 360 * (2 * PI);
}
#endregion double DegreeToRadian(double degree)
#region Display()
/// <summary>
/// Draws a frame.
/// </summary>
private static void Display() {
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glPushMatrix();
drawType = DrawType.DrawBallShadow;
DrawBoingBall();
DrawGrid();
drawType = DrawType.DrawBall;
DrawBoingBall();
Gl.glPopMatrix();
Gl.glFlush();
}
#endregion Display()
#region DrawBoingBall()
/// <summary>
/// Draws the Boing ball.
/// </summary>
/// <remarks>
/// The Boing ball is sphere in which each facet is a rectangle. Facet colors
/// alternate between red and white. The ball is built by stacking latitudinal
/// circles. Each circle is composed of a widely-separated set of points, so
/// that each facet is noticably large.
/// </remarks>
private static void DrawBoingBall() {
float degreeOfLongitude;
double timeDifferenceTotal, timeDifferenceTemp;
Gl.glPushMatrix();
Gl.glMatrixMode(Gl.GL_MODELVIEW);
// Another relative Z translation to separate objects
Gl.glTranslatef(0, 0, (float) DISTANCE_BALL);
// Update ball position and rotation (iterate if necessary)
timeDifferenceTotal = timeDifference;
while(timeDifferenceTotal > 0.0) {
timeDifferenceTemp = timeDifferenceTotal > MAX_DELTA_TIME ? MAX_DELTA_TIME :
timeDifferenceTotal;
timeDifferenceTotal -= timeDifferenceTemp;
BounceBall(timeDifferenceTemp);
yRotationDegree = TruncateDegree((float) (yRotationDegree + yRotationDegreeIncrement *
(timeDifferenceTemp * ANIMATION_SPEED)));
}
// Set ball position
Gl.glTranslatef(ballX, ballY, 0);
// Offset the shadow
if(drawType == DrawType.DrawBallShadow) {
Gl.glTranslatef(SHADOW_OFFSET_X, SHADOW_OFFSET_Y, SHADOW_OFFSET_Z);
}
// Tilt the ball
Gl.glRotatef(-20, 0, 0, 1);
// Continually rotate ball around Y axis
Gl.glRotatef(yRotationDegree, 0, 1, 0);
// Set OpenGL state for Boing ball
Gl.glCullFace(Gl.GL_FRONT);
Gl.glEnable(Gl.GL_CULL_FACE);
Gl.glEnable(Gl.GL_NORMALIZE);
// Build a faceted latitude slice of the Boing ball, stepping same-sized vertical
// bands of the sphere
for(degreeOfLongitude = 0; degreeOfLongitude < 180;
degreeOfLongitude += STEP_LONGITUDE) {
// Draw a latitude circle at this longitude
DrawBoingBallBand(degreeOfLongitude, degreeOfLongitude + STEP_LONGITUDE);
}
Gl.glPopMatrix();
}
#endregion DrawBoingBall()
#region DrawBoingBallBand(float low, float high)
/// <summary>
/// Drawa a faceted latitude band of the Boing ball.
/// </summary>
/// <param name="low">
/// The low longitude of the slice.
/// </param>
/// <param name="high">
/// The high longitude of the slice.
/// </param>
private static void DrawBoingBallBand(float low, float high) {
// "ne" means north-east, so on
Vertex neVertex;
Vertex nwVertex;
Vertex seVertex;
Vertex swVertex;
Vertex normalVertex;
float degreeLatitude;
// Iterate thru the points of a latitude circle. A latitude circle is a 2D set of
// X, Z points
for(degreeLatitude = 0; degreeLatitude <= (360 - STEP_LATITUDE);
degreeLatitude += STEP_LATITUDE) {
// Color this polygon with red or white
if(isColor) {
Gl.glColor3f(0.8f, 0.1f, 0.1f);
}
else {
Gl.glColor3f(0.95f, 0.95f, 0.95f);
}
#if BOING_DEBUG
if(degreeLatitude >= 180) {
if(isColor) {
Gl.glColor3f(0.1f, 0.8f, 0.1f);
}
else {
Gl.glColor3f(0.5f, 0.5f, 0.95f);
}
}
#endif
isColor = !isColor;
// Change color if drawing shadow
if(drawType == DrawType.DrawBallShadow) {
Gl.glColor3f(0.35f, 0.35f, 0.35f);
}
// Assign each Y
neVertex.Y = nwVertex.Y = (float) CosDegree(high) * RADIUS;
swVertex.Y = seVertex.Y = (float) CosDegree(low) * RADIUS;
// Assign each X, Z with Sin, Cos values scaled by latitude radius indexed by
// longitude. E.G. longitude = 0 and longitude = 180 are at the poles, so zero
// scale is Sin(longitude), while longitude = 90 (Sin(90) = 1) is at equator
neVertex.X = (float) CosDegree(degreeLatitude) * (float) (RADIUS * SinDegree(low + STEP_LONGITUDE));
seVertex.X = (float) CosDegree(degreeLatitude) * (float) (RADIUS * SinDegree(low));
nwVertex.X = (float) CosDegree(degreeLatitude + STEP_LATITUDE) * (float) (RADIUS * SinDegree(low + STEP_LONGITUDE));
swVertex.X = (float) CosDegree(degreeLatitude + STEP_LATITUDE) * (float) (RADIUS * SinDegree(low));
neVertex.Z = (float) SinDegree(degreeLatitude) * (float) (RADIUS * SinDegree(low + STEP_LONGITUDE));
seVertex.Z = (float) SinDegree(degreeLatitude) * (float) (RADIUS * SinDegree(low));
nwVertex.Z = (float) SinDegree(degreeLatitude + STEP_LATITUDE) * (float) (RADIUS * SinDegree(low + STEP_LONGITUDE));
swVertex.Z = (float) SinDegree(degreeLatitude + STEP_LATITUDE) * (float) (RADIUS * SinDegree(low));
// Draw the facet
Gl.glBegin(Gl.GL_POLYGON);
CrossProduct(neVertex, nwVertex, swVertex, out normalVertex);
Gl.glNormal3f(normalVertex.X, normalVertex.Y, normalVertex.Z);
Gl.glVertex3f(neVertex.X, neVertex.Y, neVertex.Z);
Gl.glVertex3f(nwVertex.X, nwVertex.Y, nwVertex.Z);
Gl.glVertex3f(swVertex.X, swVertex.Y, swVertex.Z);
Gl.glVertex3f(seVertex.X, seVertex.Y, seVertex.Z);
Gl.glEnd();
#if BOING_DEBUG
Console.WriteLine("-----------------------------------------------------------");
Console.WriteLine("lat = {0} low = {1} high = {2}", degreeLatitude, low, high);
Console.WriteLine( "vert_ne x = %.8f y = %.8f z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z );
Console.WriteLine( "vert_nw x = %.8f y = %.8f z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z );
Console.WriteLine( "vert_se x = %.8f y = %.8f z = %.8f \n", vert_se.x, vert_se.y, vert_se.z );
Console.WriteLine( "vert_sw x = %.8f y = %.8f z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z );
#endif
}
// Toggle color so that next band will opposite red/white colors than this one
isColor = !isColor;
}
#endregion DrawBoingBallBand(float low, float high)
#region DrawGrid()
/// <summary>
/// Draws the purple grid of lines behind the Boing ball.
/// </summary>
private static void DrawGrid() {
int row, column;
int rowTotal = 12; // must be divisible by 2
int columnTotal = rowTotal; // must be same as rowTotal
float widthLine = 2; // should be divisible by 2
float sizeCell = (float) GRID_SIZE / rowTotal;
float z_offset = -40;
float xl, xr;
float yt, yb;
Gl.glPushMatrix();
Gl.glDisable(Gl.GL_CULL_FACE);
// Another relative Z translation to separate objects
Gl.glTranslatef(0, 0, DISTANCE_BALL);
// Draw vertical lines (as skinny 3D rectangles)
for(column = 0; column <= columnTotal; column++) {
// Compute coordinatess of line
xl = (float) -GRID_SIZE / 2 + column * sizeCell;
xr = xl + widthLine;
yt = (float) GRID_SIZE / 2;
yb = (float) -GRID_SIZE / 2 - widthLine;
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(0.6f, 0.1f, 0.6f); // purple
Gl.glVertex3f(xr, yt, z_offset); // NE
Gl.glVertex3f(xl, yt, z_offset); // NW
Gl.glVertex3f(xl, yb, z_offset); // SW
Gl.glVertex3f(xr, yb, z_offset); // SE
Gl.glEnd();
}
// Draw horizontal lines (as skinny 3D rectangles)
for(row = 0; row <= rowTotal; row++) {
// Compute coordinates of line
yt = (float) GRID_SIZE / 2 - row * sizeCell;
yb = yt - widthLine;
xl = (float) -GRID_SIZE / 2;
xr = (float) GRID_SIZE / 2 + widthLine;
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(0.6f, 0.1f, 0.6f); // purple
Gl.glVertex3f(xr, yt, z_offset); // NE
Gl.glVertex3f(xl, yt, z_offset); // NW
Gl.glVertex3f(xl, yb, z_offset); // SW
Gl.glVertex3f(xr, yb, z_offset); // SE
Gl.glEnd();
}
Gl.glPopMatrix();
}
#endregion DrawGrid()
#region Init()
/// <summary>
/// Initializes some GL settings.
/// </summary>
private static void Init() {
// Clear background
Gl.glClearColor(0.55f, 0.55f, 0.55f, 0.0f);
// Flat shading
Gl.glShadeModel(Gl.GL_FLAT);
}
#endregion Init()
#region double PerspectiveAngle(double size, double distance)
/// <summary>
/// Calculates the angle to be passed to <see cref="Glu.gluPerspective" /> so that
/// a scene is visible.
/// </summary>
/// <param name="size">
/// The size of the segment when the angle is intersected at
/// <paramref name="distance" />.
/// </param>
/// <param name="distance">
/// The distance from viewpoint to the scene.
/// </param>
/// <returns></returns>
private static double PerspectiveAngle(double size, double distance) {
double radianTheta = 2 * Math.Atan2(size / 2, distance);
return (double) (180 * radianTheta) / PI;
}
#endregion double PerspectiveAngle(double size, double distance)
#region double SinDegree(double degree)
/// <summary>
/// 360' Sin().
/// </summary>
/// <param name="degree">
/// The degree.
/// </param>
/// <returns>
/// The Sin.
/// </returns>
private static double SinDegree(double degree) {
return Math.Sin(DegreeToRadian(degree));
}
#endregion double SinDegree(double degree)
#region float TruncateDegree(float degree)
/// <summary>
/// Truncates a degree.
/// </summary>
/// <param name="degree">
/// The degree to truncate.
/// </param>
/// <returns>
/// The truncated degree value.
/// </returns>
private static float TruncateDegree(float degree) {
if(degree >= 360.0f) {
return (degree - 360.0f);
}
else {
return degree;
}
}
#endregion float TruncateDegree(float degree)
// --- Private GLFW Callback Methods ---
#region Reshape(int width, int height)
/// <summary>
/// Handles GLFW's window reshape callback.
/// </summary>
/// <param name="width">
/// New window width.
/// </param>
/// <param name="height">
/// New window height.
/// </param>
private static void Reshape(int width, int height) {
Gl.glViewport(0, 0, width, height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(PerspectiveAngle(RADIUS * 2, 200),
(double) width / (double) height,
1,
VIEW_SCENE_DISTANCE);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt(0, 0, VIEW_SCENE_DISTANCE, // eye
0, 0, 0, // center of vision
0, -1, 0); // up vector
}
#endregion Reshape(int width, int height)
}
}

Двоичные данные
examples/GlfwExamples/Data/pong3d_field.tga Normal file

Двоичный файл не отображается.

Двоичные данные
examples/GlfwExamples/Data/pong3d_instr.tga Normal file

Двоичный файл не отображается.

Двоичные данные
examples/GlfwExamples/Data/pong3d_menu.tga Normal file

Двоичный файл не отображается.

Двоичные данные
examples/GlfwExamples/Data/pong3d_title.tga Normal file

Двоичный файл не отображается.

Двоичные данные
examples/GlfwExamples/Data/pong3d_winner1.tga Normal file

Двоичный файл не отображается.

Двоичные данные
examples/GlfwExamples/Data/pong3d_winner2.tga Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,448 @@
#region License
/*
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
#region Original Credits/License
/*
Copyright (c) 2002-2004 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Marcus Geelnard
marcus.geelnard at home.se
*/
/*
* 3-D gear wheels. This program is in the public domain.
*
* Command line options:
* -info print GL implementation information
* -exit automatically exit after 30 seconds
*
*
* Brian Paul
*
*
* Marcus Geelnard:
* - Conversion to GLFW
* - Time based rendering (frame rate independent)
* - Slightly modified camera that should work better for stereo viewing
*/
#endregion Original Credits/License
using System;
using Tao.Glfw;
using Tao.OpenGl;
namespace GlfwExamples {
#region Class Documentation
/// <summary>
/// This is a small test application for GLFW.
/// </summary>
/// <remarks>
/// Classic gears.
/// </remarks>
#endregion Class Documentation
public sealed class Gears {
// --- Fields ---
#region Private Constants
private const float PI = 3.141592654f;
#endregion Private Constants
#region Private Static Fields
private static bool isRunning = true;
private static double currentTime = 0;
private static double oldTime = 0;
private static double timeDifference = 0;
private static int frameCount;
private static int autoExit = 0;
private static float[] lightPosition = new float[] {5, 5, 10, 0};
private static float[] redMaterial = new float[] {0.8f, 0.1f, 0, 1};
private static float[] greenMaterial = new float[] {0, 0.8f, 0.2f, 1};
private static float[] blueMaterial = new float[] {0.2f, 0.2f, 1, 1};
private static float rotateX = 20, rotateY = 30, rotateZ = 0;
private static int gear1, gear2, gear3;
private static float angle = 0;
#endregion Private Static Fields
// --- Application Entry Point ---
#region Run()
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Run() {
// Initialise GLFW and open window
Glfw.glfwInit();
if(Glfw.glfwOpenWindow(300, 300, 0, 0, 0, 0, 0, 0, Glfw.GLFW_WINDOW) == Gl.GL_FALSE) {
Glfw.glfwTerminate();
return;
}
Glfw.glfwSetWindowTitle("Gears");
Glfw.glfwEnable(Glfw.GLFW_KEY_REPEAT);
Glfw.glfwSwapInterval(0);
Init();
// Set callback functions
Glfw.glfwSetWindowSizeCallback(new Glfw.GLFWwindowsizefun(Reshape));
Glfw.glfwSetKeyCallback(new Glfw.GLFWkeyfun(Key));
// Main loop
while(isRunning) {
// Draw gears
Draw();
// Update animation
Animate();
// Swap Buffers
Glfw.glfwSwapBuffers();
if(Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_FALSE) {
isRunning = false;
}
}
// Close OpenGL window and terminate GLFW
Glfw.glfwTerminate();
}
#endregion Run()
// --- Private Static Methods ---
#region Animate()
/// <summary>
/// Updates animation parameters.
/// </summary>
private static void Animate() {
angle += 100 * (float) timeDifference;
}
#endregion Animate()
#region Draw()
/// <summary>
/// OpenGL draw function and timing.
/// </summary>
private static void Draw() {
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glPushMatrix();
Gl.glRotatef(rotateX, 1, 0, 0);
Gl.glRotatef(rotateY, 0, 1, 0);
Gl.glRotatef(rotateZ, 0, 0, 1);
Gl.glPushMatrix();
Gl.glTranslatef(-3, -2, 0);
Gl.glRotatef(angle, 0, 0, 1);
Gl.glCallList(gear1);
Gl.glPopMatrix();
Gl.glPushMatrix();
Gl.glTranslatef(3.1f, -2, 0);
Gl.glRotatef(-2 * angle - 9, 0, 0, 1);
Gl.glCallList(gear2);
Gl.glPopMatrix();
Gl.glPushMatrix();
Gl.glTranslatef(-3.1f, 4.2f, 0);
Gl.glRotatef(-2 * angle - 25, 0, 0, 1);
Gl.glCallList(gear3);
Gl.glPopMatrix();
Gl.glPopMatrix();
frameCount++;
double newTime = Glfw.glfwGetTime();
timeDifference = newTime - currentTime;
currentTime = newTime;
if(currentTime - oldTime >= 5.0) {
double seconds = currentTime - oldTime;
double fps = frameCount / seconds;
Console.WriteLine("{0} frames in {1} seconds = {2} FPS", frameCount, seconds, fps);
oldTime = currentTime;
frameCount = 0;
if((currentTime >= 0.999 * autoExit) && (autoExit > 0)) {
isRunning = false;
}
}
}
#endregion Draw()
#region Gear(float innerRadius, float outerRadius, float width, float teeth, float toothDepth)
private static void Gear(float innerRadius, float outerRadius, float width, float teeth, float toothDepth) {
int i;
float r0, r1, r2;
float angle, da;
float u, v, len;
r0 = innerRadius;
r1 = outerRadius - toothDepth / 2;
r2 = outerRadius + toothDepth / 2;
da = 2 * PI / teeth / 4;
Gl.glShadeModel(Gl.GL_FLAT);
Gl.glNormal3f(0, 0, 1);
// draw front face
Gl.glBegin(Gl.GL_QUAD_STRIP);
for(i = 0; i <= teeth; i++) {
angle = i * 2 * PI / teeth;
Gl.glVertex3f(r0 * (float) Math.Cos(angle), r0 * (float) Math.Sin(angle), width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(angle), r1 * (float) Math.Sin(angle), width * 0.5f);
if(i < teeth) {
Gl.glVertex3f(r0 * (float) Math.Cos(angle), r0 * (float) Math.Sin(angle), width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(angle + 3 * da), r1 * (float) Math.Sin(angle + 3 * da), width * 0.5f);
}
}
Gl.glEnd();
// draw front sides of teeth
Gl.glBegin(Gl.GL_QUADS);
da = 2 * PI / teeth / 4;
for(i = 0; i < teeth; i++) {
angle = i * 2 * PI / teeth;
Gl.glVertex3f(r1 * (float) Math.Cos(angle), r1 * (float) Math.Sin(angle), width * 0.5f);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + da), r2 * (float) Math.Sin(angle + da), width * 0.5f);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + 2 * da), r2 * (float) Math.Sin(angle + 2 * da), width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(angle + 3 * da), r1 * (float) Math.Sin(angle + 3 * da), width * 0.5f);
}
Gl.glEnd();
Gl.glNormal3f(0, 0, -1);
// draw back face
Gl.glBegin(Gl.GL_QUAD_STRIP);
for(i = 0; i <= teeth; i++) {
angle = i * 2 * PI / teeth;
Gl.glVertex3f(r1 * (float) Math.Cos(angle), r1 * (float) Math.Sin(angle), -width * 0.5f);
Gl.glVertex3f(r0 * (float) Math.Cos(angle), r0 * (float) Math.Sin(angle), -width * 0.5f);
if(i < teeth) {
Gl.glVertex3f(r1 * (float) Math.Cos(angle + 3 * da), r1 * (float) Math.Sin(angle + 3 * da), -width * 0.5f);
Gl.glVertex3f(r0 * (float) Math.Cos(angle), r0 * (float) Math.Sin(angle), -width * 0.5f);
}
}
Gl.glEnd();
// draw back sides of teeth
Gl.glBegin(Gl.GL_QUADS);
da = 2 * PI / teeth / 4;
for(i = 0; i < teeth; i++) {
angle = i * 2 * PI / teeth;
Gl.glVertex3f(r1 * (float) Math.Cos(angle + 3 * da), r1 * (float) Math.Sin(angle + 3 * da), -width * 0.5f);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + 2 * da), r2 * (float) Math.Sin(angle + 2 * da), -width * 0.5f);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + da), r2 * (float) Math.Sin(angle + da), -width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(angle), r1 * (float) Math.Sin(angle), -width * 0.5f);
}
Gl.glEnd();
// draw outward faces of teeth
Gl.glBegin(Gl.GL_QUAD_STRIP);
for(i = 0; i < teeth; i++) {
angle = i * 2 * PI / teeth;
Gl.glVertex3f(r1 * (float) Math.Cos(angle), r1 * (float) Math.Sin(angle), width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(angle), r1 * (float) Math.Sin(angle), -width * 0.5f);
u = r2 * (float) Math.Cos(angle + da) - r1 * (float) Math.Cos(angle);
v = r2 * (float) Math.Sin(angle + da) - r1 * (float) Math.Sin(angle);
len = (float) Math.Sqrt(u * u + v * v);
u /= len;
v /= len;
Gl.glNormal3f(v, -u, 0);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + da), r2 * (float) Math.Sin(angle + da), width * 0.5f);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + da), r2 * (float) Math.Sin(angle + da), -width * 0.5f);
Gl.glNormal3f((float) Math.Cos(angle), (float) Math.Sin(angle), 0);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + 2 * da), r2 * (float) Math.Sin(angle + 2 * da), width * 0.5f);
Gl.glVertex3f(r2 * (float) Math.Cos(angle + 2 * da), r2 * (float) Math.Sin(angle + 2 * da), -width * 0.5f);
u = r1 * (float) Math.Cos(angle + 3 * da) - r2 * (float) Math.Cos(angle + 2 * da);
v = r1 * (float) Math.Sin(angle + 3 * da) - r2 * (float) Math.Sin(angle + 2 * da);
Gl.glNormal3f(v, -u, 0);
Gl.glVertex3f(r1 * (float) Math.Cos(angle + 3 * da), r1 * (float) Math.Sin(angle + 3 * da), width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(angle + 3 * da), r1 * (float) Math.Sin(angle + 3 * da), -width * 0.5f);
Gl.glNormal3f((float) Math.Cos(angle), (float) Math.Sin(angle), 0);
}
Gl.glVertex3f(r1 * (float) Math.Cos(0), r1 * (float) Math.Sin(0), width * 0.5f);
Gl.glVertex3f(r1 * (float) Math.Cos(0), r1 * (float) Math.Sin(0), -width * 0.5f);
Gl.glEnd();
Gl.glShadeModel(Gl.GL_SMOOTH);
// draw inside radius cylinder
Gl.glBegin(Gl.GL_QUAD_STRIP);
for(i = 0; i <= teeth; i++) {
angle = i * 2 * PI / teeth;
Gl.glNormal3f((float) -Math.Cos(angle), (float) -Math.Sin(angle), 0);
Gl.glVertex3f(r0 * (float) Math.Cos(angle), r0 * (float) Math.Sin(angle), -width * 0.5f);
Gl.glVertex3f(r0 * (float) Math.Cos(angle), r0 * (float) Math.Sin(angle), width * 0.5f);
}
Gl.glEnd();
}
#endregion Gear(float innerRadius, float outerRadius, float width, float teeth, float toothDepth)
#region Init()
/// <summary>
/// Performs program and OpenGL initialization.
/// </summary>
/// <param name="arguments">
/// The command line arguments.
/// </param>
private static void Init() {
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, lightPosition);
Gl.glEnable(Gl.GL_CULL_FACE);
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glEnable(Gl.GL_DEPTH_TEST);
// make the gears
gear1 = Gl.glGenLists(1);
Gl.glNewList(gear1, Gl.GL_COMPILE);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT_AND_DIFFUSE, redMaterial);
Gear(1, 4, 1, 20, 0.7f);
Gl.glEndList();
gear2 = Gl.glGenLists(1);
Gl.glNewList(gear2, Gl.GL_COMPILE);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT_AND_DIFFUSE, greenMaterial);
Gear(0.5f, 2, 2, 10, 0.7f);
Gl.glEndList();
gear3 = Gl.glGenLists(1);
Gl.glNewList(gear3, Gl.GL_COMPILE);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT_AND_DIFFUSE, blueMaterial);
Gear(1.3f, 2, 0.5f, 10, 0.7f);
Gl.glEndList();
Gl.glEnable(Gl.GL_NORMALIZE);
//for(int i = 0; i < arguments.Length; i++) {
// if(arguments[i] == "-info") {
// Console.WriteLine("GL_RENDERER = {0}", Gl.glGetString(Gl.GL_RENDERER));
// Console.WriteLine("GL_VERSION = {0}", Gl.glGetString(Gl.GL_VERSION));
// Console.WriteLine("GL_VENDOR = {0}", Gl.glGetString(Gl.GL_VENDOR));
// Console.WriteLine("GL_EXTENSIONS = {0}", Gl.glGetString(Gl.GL_EXTENSIONS));
// }
// else if(arguments[i] == "-exit") {
// autoExit = 30;
// Console.WriteLine("Auto Exit after {0} seconds.", autoExit);
// }
//}
}
#endregion Init()
// --- Private GLFW Callback Methods ---
#region Key(int key, int action)
/// <summary>
/// Changes view angle, exits the app.
/// </summary>
/// <param name="key">
/// The key.
/// </param>
/// <param name="action">
/// The key action.
/// </param>
private static void Key(int key, int action) {
if(action != Glfw.GLFW_PRESS) {
return;
}
switch(key) {
case (int) 'Z':
if(Glfw.glfwGetKey(Glfw.GLFW_KEY_LSHIFT) == Gl.GL_TRUE) {
rotateZ -= 5;
}
else {
rotateZ += 5;
}
break;
case Glfw.GLFW_KEY_ESC:
isRunning = false;
break;
case Glfw.GLFW_KEY_UP:
rotateX += 5;
break;
case Glfw.GLFW_KEY_DOWN:
rotateX -= 5;
break;
case Glfw.GLFW_KEY_LEFT:
rotateY += 5;
break;
case Glfw.GLFW_KEY_RIGHT:
rotateY -= 5;
break;
default:
return;
}
}
#endregion Key(int key, int action)
#region Reshape(int width, int height)
/// <summary>
/// Reshape callback.
/// </summary>
/// <param name="width">
/// The window width.
/// </param>
/// <param name="height">
/// The window height.
/// </param>
private static void Reshape(int width, int height) {
float h = (float) height / (float) width;
float xMax, zNear, zFar;
zNear = 5;
zFar = 30;
xMax = zNear * 0.5f;
Gl.glViewport(0, 0, width, height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glFrustum(-xMax, xMax, -xMax * h, xMax * h, zNear, zFar);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glTranslatef(0, 0, -20);
}
#endregion Reshape(int width, int height)
}
}

77
examples/GlfwExamples/GlfwExamples.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,77 @@
namespace GlfwExamples
{
partial class GlfwExamples
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lstExamples = new System.Windows.Forms.ListBox();
this.btnRun = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// lstExamples
//
this.lstExamples.FormattingEnabled = true;
this.lstExamples.Location = new System.Drawing.Point(13, 13);
this.lstExamples.Name = "lstExamples";
this.lstExamples.Size = new System.Drawing.Size(258, 173);
this.lstExamples.Sorted = true;
this.lstExamples.TabIndex = 0;
this.lstExamples.DoubleClick += new System.EventHandler(this.lstExamples_SelectedIndexChanged);
//
// btnRun
//
this.btnRun.Location = new System.Drawing.Point(94, 192);
this.btnRun.Name = "btnRun";
this.btnRun.Size = new System.Drawing.Size(95, 23);
this.btnRun.TabIndex = 1;
this.btnRun.Text = "Run";
this.btnRun.UseVisualStyleBackColor = true;
this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
//
// GlfwExamples
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(283, 224);
this.Controls.Add(this.btnRun);
this.Controls.Add(this.lstExamples);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "GlfwExamples";
this.Text = "GlfwExamples";
this.Load += new System.EventHandler(this.frmExamples_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListBox lstExamples;
private System.Windows.Forms.Button btnRun;
}
}

Просмотреть файл

@ -0,0 +1,22 @@
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Просмотреть файл

@ -0,0 +1,26 @@
GlfwExamples
http://www.taoframework.com
Copyright ©2003-2004 Randy Ridge, All rights reserved.
These are C# ports of some OpenGL examples developed for GLFW, the originals
are available from http://glfw.sourceforge.net.
These examples use Tao.OpenGl and Tao.Glfw. Make sure you have the
appropriate native GLFW libraries for your system installed.
These examples are fairly well documented, however, do not take
them to be 'best practices' for .NET OpenGL development. The
intent of these ports is as an introduction or as a comparison
against the original native versions.
If you'd like to contribute you can port the remaining examples as supplied
with GLFW. I never got around to them, but they look pretty trivial.
Randy Ridge
http://www.taoframework.com
Change Log:
April 23, 2004:
Initial release, version 1.0.0.0.

Просмотреть файл

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace GlfwExamples
{
public partial class GlfwExamples : Form
{
public GlfwExamples()
{
InitializeComponent();
}
private void frmExamples_Load(object sender, EventArgs e)
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type type in types)
{
MemberInfo[] runMethods = type.GetMember("Run");
foreach (MemberInfo run in runMethods)
{
lstExamples.Items.Add(type.Name);
}
}
}
private void btnRun_Click(object sender, EventArgs e)
{
SelectExample();
}
private void SelectExample()
{
Type example = Assembly.GetExecutingAssembly().GetType("GlfwExamples." + lstExamples.SelectedItem.ToString(), true, true);
example.InvokeMember("Run", BindingFlags.InvokeMethod, null, null, null);
}
private void lstExamples_SelectedIndexChanged(object sender, EventArgs e)
{
SelectExample();
}
}
}

Просмотреть файл

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

Просмотреть файл

@ -0,0 +1,324 @@
#region License
/*
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
#region Original Credits/License
/*
Copyright (c) 2002-2004 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Marcus Geelnard
marcus.geelnard at home.se
*/
#endregion Original Credits/License
using System;
using Tao.Glfw;
using Tao.OpenGl;
namespace GlfwExamples {
#region Class Documentation
/// <summary>
/// This is a small test application for GLFW.
/// </summary>
/// <remarks>
/// Keyboard input test.
/// </remarks>
#endregion Class Documentation
public sealed class KeyTest {
// --- Fields ---
#region Private Static Fields
private static bool isRunning = true;
private static bool isKeyRepeat = false;
private static bool isSystemKeys = true;
#endregion Private Static Fields
// --- Application Entry Point ---
#region Run()
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Run() {
int windowWidth, windowHeight;
double currentTime;
// Initialise GLFW
Glfw.glfwInit();
// Open OpenGL window
if(Glfw.glfwOpenWindow(250, 100, 0, 0, 0, 0, 0, 0, Glfw.GLFW_WINDOW) == Gl.GL_FALSE) {
Glfw.glfwTerminate();
return;
}
// Set key callback function
Glfw.glfwSetKeyCallback(new Glfw.GLFWkeyfun(Key));
// Set title
Glfw.glfwSetWindowTitle("Press some keys!");
// Main loop
while(isRunning) {
// Get time
currentTime = Glfw.glfwGetTime();
// Get window size (may be different than the requested size)
Glfw.glfwGetWindowSize(out windowWidth, out windowHeight);
windowHeight = windowHeight > 0 ? windowHeight : 1;
// Set viewport
Gl.glViewport(0, 0, windowWidth, windowHeight);
// Clear color buffer
Gl.glClearColor((float) (0.5f + 0.5f * (float) Math.Sin(3.0 * currentTime)),
0, 0, 0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
// Swap buffers
Glfw.glfwSwapBuffers();
// Check if the window was closed
if(Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_FALSE) {
isRunning = false;
}
}
// Close OpenGL window and terminate GLFW
Glfw.glfwTerminate();
}
#endregion Run()
// --- Private GLFW Callback Methods ---
#region Key(int key, int action)
/// <summary>
/// Handles GLFW key callback.
/// </summary>
/// <param name="key">
/// The key.
/// </param>
/// <param name="action">
/// The key action.
/// </param>
private static void Key(int key, int action) {
if(action != Glfw.GLFW_PRESS) {
return;
}
switch(key) {
case Glfw.GLFW_KEY_ESC:
Console.WriteLine("ESC => quit program");
isRunning = false;
break;
case Glfw.GLFW_KEY_F1:
case Glfw.GLFW_KEY_F2:
case Glfw.GLFW_KEY_F3:
case Glfw.GLFW_KEY_F4:
case Glfw.GLFW_KEY_F5:
case Glfw.GLFW_KEY_F6:
case Glfw.GLFW_KEY_F7:
case Glfw.GLFW_KEY_F8:
case Glfw.GLFW_KEY_F9:
case Glfw.GLFW_KEY_F10:
case Glfw.GLFW_KEY_F11:
case Glfw.GLFW_KEY_F12:
case Glfw.GLFW_KEY_F13:
case Glfw.GLFW_KEY_F14:
case Glfw.GLFW_KEY_F15:
case Glfw.GLFW_KEY_F16:
case Glfw.GLFW_KEY_F17:
case Glfw.GLFW_KEY_F18:
case Glfw.GLFW_KEY_F19:
case Glfw.GLFW_KEY_F20:
case Glfw.GLFW_KEY_F21:
case Glfw.GLFW_KEY_F22:
case Glfw.GLFW_KEY_F23:
case Glfw.GLFW_KEY_F24:
case Glfw.GLFW_KEY_F25:
Console.WriteLine("F{0}", 1 + key - Glfw.GLFW_KEY_F1);
break;
case Glfw.GLFW_KEY_UP:
Console.WriteLine("UP");
break;
case Glfw.GLFW_KEY_DOWN:
Console.WriteLine("DOWN");
break;
case Glfw.GLFW_KEY_LEFT:
Console.WriteLine("LEFT");
break;
case Glfw.GLFW_KEY_RIGHT:
Console.WriteLine("RIGHT");
break;
case Glfw.GLFW_KEY_LSHIFT:
Console.WriteLine("LSHIFT");
break;
case Glfw.GLFW_KEY_RSHIFT:
Console.WriteLine("RSHIFT");
break;
case Glfw.GLFW_KEY_LCTRL:
Console.WriteLine("LCTRL");
break;
case Glfw.GLFW_KEY_RCTRL:
Console.WriteLine("RCTRL");
break;
case Glfw.GLFW_KEY_LALT:
Console.WriteLine("LALT");
break;
case Glfw.GLFW_KEY_RALT:
Console.WriteLine("RALT");
break;
case Glfw.GLFW_KEY_TAB:
Console.WriteLine("TAB");
break;
case Glfw.GLFW_KEY_ENTER:
Console.WriteLine("ENTER");
break;
case Glfw.GLFW_KEY_BACKSPACE:
Console.WriteLine("BACKSPACE");
break;
case Glfw.GLFW_KEY_INSERT:
Console.WriteLine("INSERT");
break;
case Glfw.GLFW_KEY_DEL:
Console.WriteLine("DEL");
break;
case Glfw.GLFW_KEY_PAGEUP:
Console.WriteLine("PAGEUP");
break;
case Glfw.GLFW_KEY_PAGEDOWN:
Console.WriteLine("PAGEDOWN");
break;
case Glfw.GLFW_KEY_HOME:
Console.WriteLine("HOME");
break;
case Glfw.GLFW_KEY_END:
Console.WriteLine("END");
break;
case Glfw.GLFW_KEY_KP_0:
Console.WriteLine("KEYPAD 0");
break;
case Glfw.GLFW_KEY_KP_1:
Console.WriteLine("KEYPAD 1");
break;
case Glfw.GLFW_KEY_KP_2:
Console.WriteLine("KEYPAD 2");
break;
case Glfw.GLFW_KEY_KP_3:
Console.WriteLine("KEYPAD 3");
break;
case Glfw.GLFW_KEY_KP_4:
Console.WriteLine("KEYPAD 4");
break;
case Glfw.GLFW_KEY_KP_5:
Console.WriteLine("KEYPAD 5");
break;
case Glfw.GLFW_KEY_KP_6:
Console.WriteLine("KEYPAD 6");
break;
case Glfw.GLFW_KEY_KP_7:
Console.WriteLine("KEYPAD 7");
break;
case Glfw.GLFW_KEY_KP_8:
Console.WriteLine("KEYPAD 8");
break;
case Glfw.GLFW_KEY_KP_9:
Console.WriteLine("KEYPAD 9");
break;
case Glfw.GLFW_KEY_KP_DIVIDE:
Console.WriteLine("KEYPAD DIVIDE");
break;
case Glfw.GLFW_KEY_KP_MULTIPLY:
Console.WriteLine("KEYPAD MULTIPLY");
break;
case Glfw.GLFW_KEY_KP_SUBTRACT:
Console.WriteLine("KEYPAD SUBTRACT");
break;
case Glfw.GLFW_KEY_KP_ADD:
Console.WriteLine("KEYPAD ADD");
break;
case Glfw.GLFW_KEY_KP_DECIMAL:
Console.WriteLine("KEYPAD DECIMAL");
break;
case Glfw.GLFW_KEY_KP_EQUAL:
Console.WriteLine("KEYPAD =");
break;
case Glfw.GLFW_KEY_KP_ENTER:
Console.WriteLine("KEYPAD ENTER");
break;
case Glfw.GLFW_KEY_SPACE:
Console.WriteLine("SPACE");
break;
case (int) 'R':
isKeyRepeat = !isKeyRepeat;
if(isKeyRepeat) {
Glfw.glfwEnable(Glfw.GLFW_KEY_REPEAT);
}
else {
Glfw.glfwDisable(Glfw.GLFW_KEY_REPEAT);
}
Console.WriteLine("R => Key repeat: {0}", isKeyRepeat ? "ON" : "OFF");
break;
case (int) 'S':
isSystemKeys = !isSystemKeys;
if(isSystemKeys) {
Glfw.glfwEnable(Glfw.GLFW_SYSTEM_KEYS);
}
else {
Glfw.glfwDisable(Glfw.GLFW_SYSTEM_KEYS);
}
Console.WriteLine("S => System keys: {0}", isSystemKeys ? "ON" : "OFF");
break;
default:
if(key > 0 && key < 256) {
Console.WriteLine("{0}", (char) key);
}
else {
Console.WriteLine("???");
}
break;
}
}
#endregion Key(int key, int action)
}
}

Просмотреть файл

@ -0,0 +1,115 @@
#region License
/*
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
#region Original Credits/License
/*
Copyright (c) 2002-2004 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Marcus Geelnard
marcus.geelnard at home.se
*/
#endregion Original Credits/License
using System;
using Tao.Glfw;
using Tao.OpenGl;
namespace GlfwExamples {
#region Class Documentation
/// <summary>
/// This is a small test application for GLFW.
/// </summary>
/// <remarks>
/// The program lists all available fullscreen video modes.
/// </remarks>
#endregion Class Documentation
public sealed class ListModes {
// --- Fields ---
#region Private Constants
// Maximum number of modes that we want to list
private const int MAX_NUMBER_OF_MODES = 400;
#endregion Private Constants
// --- Application Entry Point ---
#region Run()
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Run() {
Glfw.GLFWvidmode desktopMode;
Glfw.GLFWvidmode[] availableModes = new Glfw.GLFWvidmode[MAX_NUMBER_OF_MODES];
int modeCount;
// Initialize GLFW
if(Glfw.glfwInit() == Gl.GL_FALSE) {
return;
}
// Show desktop video mode
Glfw.glfwGetDesktopMode(out desktopMode);
Console.WriteLine("Desktop mode: {0} x {1} x {2}", desktopMode.Width,
desktopMode.Height, desktopMode.RedBits + desktopMode.GreenBits +
desktopMode.BlueBits);
// List available video modes
modeCount = Glfw.glfwGetVideoModes(availableModes, MAX_NUMBER_OF_MODES);
Console.WriteLine("Available modes:");
for(int i = 0; i < modeCount; i++) {
Console.WriteLine("{0}: {1} x {2} x {3}", i, availableModes[i].Width,
availableModes[i].Height, availableModes[i].RedBits +
availableModes[i].GreenBits + availableModes[i].BlueBits);
}
// Terminate GLFW
Glfw.glfwTerminate();
Console.Write("\n\nPress Enter to exit...");
Console.ReadLine();
}
#endregion Run()
}
}

Просмотреть файл

@ -0,0 +1,919 @@
#region License
/*
MIT License
Copyright ©2003-2006 The Tao Framework Team
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
#region Tao Port Credits
/* Original Tao port by Simon <the-real-sim@gmx.de> */
#endregion Tao Port Credits
#region Original Credits/License
/*
Copyright (c) 2002-2004 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Marcus Geelnard
marcus.geelnard at home.se
*/
//========================================================================
// This is a small test application for GLFW.
// This is an OpenGL port of the famous "PONG" game (the first computer
// game ever?). It is very simple, and could be improved alot. It was
// created in order to show off the gaming capabilities of GLFW.
//========================================================================
#endregion Original Credits/License
using System;
using Tao.Glfw;
using Tao.OpenGl;
namespace GlfwExamples {
#region Class Documentation
/// <summary>
/// This is a small test application for GLFW
/// </summary>
/// <remarks>
/// This is an OpenGL port of the famous "PONG" game (the first computer
/// game ever?). It is very simple, and could be improved alot. It was
/// created in order to show off the gaming capabilities of GLFW.
/// </remarks>
#endregion Class Documentation
public sealed class Pong {
#region fields
/// <summary> Screen resolution: width </summary>
public static int width = 640;
/// <summary> Screen resolution: height </summary>
public static int height = 480;
/// <summary> Player size (units): X dimension </summary>
public static float playerSizeX = 0.05f;
/// <summary> Player size (units): Y dimension </summary>
public static float playerSizeY = 0.15f;
/// <summary> Ball size (units) </summary>
public static float ballSize = 0.02f;
/// <summary> Maximum player movement speed (units / second) </summary>
public static float maxSpeed = 1.5f;
/// <summary> Player movement acceleration (units / seconds^2) </summary>
public static float acceleration = 4.0f;
/// <summary> Player movement deceleration (units / seconds^2) </summary>
public static float deceleration = 2.0f;
/// <summary> Ball movement speed (units / second) </summary>
public static float ballSpeed = 0.4f;
/// <summary>
/// Menu options
/// </summary>
public enum MenuOption {
None,Play,Quit
}
/// <summary>
/// Game events
/// </summary>
public enum GameEvent {
NobodyWins,
Player1Wins,
Player2Wins
}
/// <summary>
/// Game winners
/// </summary>
public enum Winner {
Nobody,
Player1,
Player2
}
/// <summary> The winning player </summary>
public static int winningPlayer;
/// <summary>
/// Camera positions
/// </summary>
public enum CameraPosition {
Classic,
Above,
Spectator
}
/// <summary> Default camera position </summary>
public static CameraPosition cameraDefault = CameraPosition.Classic;
/// <summary>
/// Textures
/// </summary>
public enum Textures {
Title,
Menu,
Instr,
Winner1,
Winner2,
Field,
Num_textures
}
/// <summary>
/// Texture file names
/// </summary>
public static String[] TexName = {"Data/pong3d_title.tga",
"Data/pong3d_menu.tga",
"Data/pong3d_instr.tga",
"Data/pong3d_winner1.tga",
"Data/pong3d_winner2.tga",
"Data/pong3d_field.tga"};
/// <summary> Frame information </summary>
public static double thisTime, oldTime, dt, startTime;
/// <summary> Camera position information </summary>
public static CameraPosition cameraPos;
/// <summary>
/// Player information
/// </summary>
public struct Player {
/// <summary> Player Id: Player 1 or Player 2 </summary>
public int id;
/// <summary> Y-position of player paddle: -1.0 to +1.0 </summary>
public double posY;
/// <summary> Maximum speed of player paddle: -MAX_SPEED to +MAX_SPEED </summary>
public double speedY;
}
/// <summary>Players</summary>
public static Player Player1,Player2;
/// <summary> Ball information </summary>
public struct Ball {
public double posX, posY;
public double speedX, speedY;
}
/// <summary> The game ball </summary>
public static Ball gameBall;
#region Lighting configuration
public static float[] envAmbient;
public static float[] light1Position;
public static float[] light1Diffuse;
public static float[] light1Ambient;
#endregion Lighting configuration
#region Object material properties
public static float[] Player1Diffuse;
public static float[] Player1Ambient;
public static float[] Player2Diffuse;
public static float[] Player2Ambient;
public static float[] ballDiffuse;
public static float[] ballAmbient;
public static float[] borderDiffuse;
public static float[] borderAmbient;
public static float[] floorDiffuse;
public static float[] floorAmbient;
#endregion Object material properties
/// <summary> OpenGL texture object IDs </summary>
public static int[] TexId = new int[(int)Textures.Num_textures];
#endregion fields
/// <summary>
/// LoadTextures
///
/// Load textures from disk and upload to OpenGL card
/// </summary>
public static void LoadTextures() {
int i;
// Generate texture objects
Gl.glGenTextures((int)Textures.Num_textures, TexId);
// Load textures
for(i = 0; i < (int)Textures.Num_textures; i++) {
// Select texture object
Gl.glBindTexture(Gl.GL_TEXTURE_2D, TexId[i]);
// Set texture parameters
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
// Upload texture from file to texture memory
Glfw.glfwLoadTexture2D(TexName[i], 0);
}
}
/// <summary>
/// DrawImage
///
/// Draw a 2d image as a texture
/// </summary>
/// <param name="texnum">An int</param>
/// <param name="x1">A float</param>
/// <param name="x2">A float</param>
/// <param name="y1">A float</param>
/// <param name="y2">A float</param>
public static void DrawImage(int texnum, float x1, float x2, float y1, float y2) {
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, TexId[texnum]);
Gl.glBegin(Gl.GL_QUADS);
Gl.glTexCoord2f(0.0f, 1.0f);
Gl.glVertex2f(x1, y1);
Gl.glTexCoord2f(1.0f, 1.0f);
Gl.glVertex2f(x2, y1);
Gl.glTexCoord2f(1.0f, 0.0f);
Gl.glVertex2f(x2, y2);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex2f(x1, y2);
Gl.glEnd();
Gl.glDisable(Gl.GL_TEXTURE_2D);
}
/// <summary>
/// GameMenu
///
/// Returns menu option
/// </summary>
/// <returns>A MenuOption</returns>
public static MenuOption GameMenu() {
MenuOption option;
// Enable sticky keys
Glfw.glfwEnable(Glfw.GLFW_STICKY_KEYS);
// Wait for a game menu key to be pressed
do
{
// Get window size
Glfw.glfwGetWindowSize(out width, out height);
// Set viewport
Gl.glViewport(0, 0, width, height);
// Clear display
Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
// Setup projection matrix
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f);
// Setup modelview matrix
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
// Display title
Gl.glColor3f(1.0f, 1.0f, 1.0f);
DrawImage((int)Textures.Title, 0.1f, 0.9f, 0.0f, 0.3f);
// Display menu
Gl.glColor3f(1.0f, 1.0f, 0.0f);
DrawImage((int)Textures.Menu, 0.38f, 0.62f, 0.35f, 0.5f);
// Display instructions
Gl.glColor3f(0.0f, 1.0f, 1.0f);
DrawImage((int)Textures.Instr, 0.32f, 0.68f, 0.65f, 0.85f);
// Swap buffers
Glfw.glfwSwapBuffers();
// Check for keys
if(Glfw.glfwGetKey('Q') == Gl.GL_TRUE || Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_FALSE) {
option = MenuOption.Quit;
}
else if(Glfw.glfwGetKey(Glfw.GLFW_KEY_F1) == Gl.GL_TRUE) {
option = MenuOption.Play;
}
else {
option = MenuOption.None;
}
// To avoid horrible busy waiting, sleep for at least 20 ms
Glfw.glfwSleep(0.02);
}
while( option == MenuOption.None );
// Disable sticky keys
Glfw.glfwDisable(Glfw.GLFW_STICKY_KEYS);
return option;
}
/// <summary>
/// NewGame
///
/// Initialize a new game
/// </summary>
public static void NewGame() {
// Frame information
startTime = thisTime = Glfw.glfwGetTime();
// Camera information
cameraPos = cameraDefault;
// Player 1 information
Player1.posY = 0.0;
Player1.speedY = 0.0;
// Player 2 information
Player2.posY = 0.0;
Player2.speedY = 0.0;
// Ball information
gameBall.posX = -1.0 + playerSizeX;
gameBall.posY = Player1.posY;
gameBall.speedX = 1.0;
gameBall.speedY = 1.0;
}
/// <summary>
/// PlayerControl
/// </summary>
public static void PlayerControl() {
float[] joy1pos = new float[2];
float[] joy2pos = new float[2];
// Get joystick X & Y axis positions
Glfw.glfwGetJoystickPos(Glfw.GLFW_JOYSTICK_1, out joy1pos[0], 2);
Glfw.glfwGetJoystickPos(Glfw.GLFW_JOYSTICK_2, out joy2pos[0], 2);
// Player 1 control
if(Glfw.glfwGetKey('A') == Gl.GL_TRUE || joy1pos[1] > 0.2f) {
Player1.speedY += dt * acceleration;
if(Player1.speedY > maxSpeed) {
Player1.speedY = maxSpeed;
}
}
else if(Glfw.glfwGetKey('Z') == Gl.GL_TRUE || joy1pos[1] < -0.2f) {
Player1.speedY -= dt * acceleration;
if(Player1.speedY < -maxSpeed) {
Player1.speedY = -maxSpeed;
}
}
else {
Player1.speedY /= System.Math.Exp(deceleration * dt);
}
// Player 2 control
if(Glfw.glfwGetKey('K') == Gl.GL_TRUE || joy2pos[1] > 0.2f) {
Player2.speedY += dt * acceleration;
if(Player2.speedY > maxSpeed) {
Player2.speedY = maxSpeed;
}
}
else if(Glfw.glfwGetKey('M') == Gl.GL_TRUE || joy2pos[1] < -0.2f) {
Player2.speedY -= dt * acceleration;
if(Player2.speedY < -maxSpeed) {
Player2.speedY = -maxSpeed;
}
}
else {
Player2.speedY /= System.Math.Exp(deceleration * dt);
}
// Update player 1 position
Player1.posY += dt * Player1.speedY;
if(Player1.posY > 1.0 - playerSizeY) {
Player1.posY = 1.0 - playerSizeY;
Player1.speedY = 0.0;
}
else if(Player1.posY < -1.0 + playerSizeY) {
Player1.posY = -1.0 + playerSizeY;
Player1.speedY = 0.0;
}
// Update player 2 position
Player2.posY += dt * Player2.speedY;
if(Player2.posY > 1.0 - playerSizeY) {
Player2.posY = 1.0 - playerSizeY;
Player2.speedY = 0.0;
}
else if(Player2.posY < -1.0 + playerSizeY) {
Player2.posY = -1.0 + playerSizeY;
Player2.speedY = 0.0;
}
}
/// <summary>
/// UpdateDisplay
///
/// Draw graphics (all game related OpenGL stuff goes here)
/// </summary>
public static void UpdateDisplay() {
// Get window size
Glfw.glfwGetWindowSize(out width, out height);
// Set viewport
Gl.glViewport(0, 0, width, height);
// Clear display
Gl.glClearColor(0.02f, 0.02f, 0.02f, 0.0f);
Gl.glClearDepth(1.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
// Setup projection matrix
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(
55.0f, // Angle of view
(float)width / (float)height, // Aspect
1.0f, // Near Z
100.0f // Far Z
);
// Setup modelview matrix
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
switch(cameraPos) {
default:
case CameraPosition.Classic:
Glu.gluLookAt(
0.0f, 0.0f, 2.5f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f
);
break;
case CameraPosition.Above:
Glu.gluLookAt(
0.0f, 0.0f, 2.5f,
(float)gameBall.posX, (float)gameBall.posY, 0.0f,
0.0f, 1.0f, 0.0f
);
break;
case CameraPosition.Spectator:
Glu.gluLookAt(
0.0f, -2.0, 1.2f,
(float)gameBall.posX, (float)gameBall.posY, 0.0f,
0.0f, 0.0f, 1.0f
);
break;
}
// Enable depth testing
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glDepthFunc(Gl.GL_LEQUAL);
// Enable lighting
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glLightModelfv(Gl.GL_LIGHT_MODEL_AMBIENT, envAmbient);
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_LOCAL_VIEWER, Gl.GL_TRUE);
Gl.glLightModeli(Gl.GL_LIGHT_MODEL_TWO_SIDE, Gl.GL_FALSE);
Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, light1Position);
Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, light1Diffuse);
Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, light1Ambient);
Gl.glEnable(Gl.GL_LIGHT1);
// Front face is counter-clock-wise
Gl.glFrontFace(Gl.GL_CCW);
// Enable face culling (not necessary, but speeds up rendering)
Gl.glCullFace(Gl.GL_BACK);
Gl.glEnable(Gl.GL_CULL_FACE);
// Draw Player 1
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, Player1Diffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, Player1Ambient);
DrawBox(-1.0f, (float)Player1.posY - playerSizeY, 0.0f,
-1.0f + playerSizeX, (float)Player1.posY + playerSizeY, 0.1f);
// Draw Player 2
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, Player2Diffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, Player2Ambient);
DrawBox(1.0f - playerSizeX, (float)Player2.posY - playerSizeY, 0.0f,
1.0f, (float)Player2.posY + playerSizeY, 0.1f);
// Draw Ball
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, ballDiffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, ballAmbient);
DrawBox((float)gameBall.posX - ballSize, (float)gameBall.posY - ballSize, 0.0f,
(float)gameBall.posX + ballSize, (float)gameBall.posY + ballSize, ballSize * 2);
// Top game field border
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, borderDiffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, borderAmbient);
DrawBox(-1.1f, 1.0f, 0.0f, 1.1f, 1.1f, 0.1f);
// Bottom game field border
Gl.glColor3f(0.0f, 0.0f, 0.7f);
DrawBox(-1.1f, -1.1f, 0.0f, 1.1f, -1.0f, 0.1f);
// Left game field border
DrawBox(-1.1f, -1.0f, 0.0f, -1.0f, 1.0f, 0.1f);
// Left game field border
DrawBox(1.0f, -1.0f, 0.0f, 1.1f, 1.0f, 0.1f);
// Enable texturing
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, TexId[(int)Textures.Field]);
// Game field floor
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, floorDiffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, floorAmbient);
DrawBox(-1.01f, -1.01f, -0.01f, 1.01f, 1.01f, 0.0f);
// Disable texturing
Gl.glDisable(Gl.GL_TEXTURE_2D);
// Disable face culling
Gl.glDisable(Gl.GL_CULL_FACE);
// Disable lighting
Gl.glDisable(Gl.GL_LIGHTING);
// Disable depth testing
Gl.glDisable(Gl.GL_DEPTH_TEST);
}
/// <summary>
/// GameOver
/// </summary>
public static void GameOver() {
// Enable sticky keys
Glfw.glfwEnable(Glfw.GLFW_STICKY_KEYS);
// Until the user presses ESC or SPACE
while(Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Gl.GL_FALSE && Glfw.glfwGetKey(' ') == Gl.GL_FALSE &&
Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE) {
// Draw display
UpdateDisplay();
// Setup projection matrix
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f);
// Setup modelview matrix
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
// Enable blending
Gl.glEnable(Gl.GL_BLEND);
// Dim background
Gl.glBlendFunc(Gl.GL_ONE_MINUS_SRC_ALPHA, Gl.GL_SRC_ALPHA);
Gl.glColor4f(0.3f, 0.3f, 0.3f, 0.3f);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex2f(0.0f, 0.0f);
Gl.glVertex2f(1.0f, 0.0f);
Gl.glVertex2f(1.0f, 1.0f);
Gl.glVertex2f(0.0f, 1.0f);
Gl.glEnd();
// Display winner text
Gl.glBlendFunc(Gl.GL_ONE, Gl.GL_ONE_MINUS_SRC_COLOR);
if(winningPlayer == (int)Winner.Player1) {
Gl.glColor4f(1.0f, 0.5f, 0.5f, 1.0f);
DrawImage((int)Textures.Winner1, 0.35f, 0.65f, 0.46f, 0.54f);
}
else if(winningPlayer == (int)Winner.Player2) {
Gl.glColor4f(0.5f, 1.0f, 0.5f, 1.0f);
DrawImage((int)Textures.Winner2, 0.35f, 0.65f, 0.46f, 0.54f);
}
// Disable blending
Gl.glDisable(Gl.GL_BLEND);
// Swap buffers
Glfw.glfwSwapBuffers();
}
// Disable sticky keys
Glfw.glfwDisable(Glfw.GLFW_STICKY_KEYS);
}
/// <summary>
/// DrawBox
///
/// Draw a 3D box
/// </summary>
/// <param name="x1">A float</param>
/// <param name="y1">A float</param>
/// <param name="z1">A float</param>
/// <param name="x2">A float</param>
/// <param name="y2">A float</param>
/// <param name="z2">A float</param>
public static void DrawBox(float x1, float y1, float z1, float x2, float y2, float z2) {
float texScale = 4.0f;
// Draw six sides of a cube
Gl.glBegin(Gl.GL_QUADS);
// Side 1 (down)
Gl.glNormal3f(0.0f, 0.0f, -1.0f);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex3f(x1, y2, z1);
Gl.glTexCoord2f(texScale, 0.0f);
Gl.glVertex3f(x2, y2, z1);
Gl.glTexCoord2f(texScale, texScale);
Gl.glVertex3f(x2, y1, z1);
Gl.glTexCoord2f(0.0f, texScale);
Gl.glVertex3f(x1, y1, z1);
// Side 2 (up)
Gl.glNormal3f(0.0f, 0.0f, 1.0f);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex3f(x1, y1, z2);
Gl.glTexCoord2f(texScale, 0.0f);
Gl.glVertex3f(x2, y1, z2);
Gl.glTexCoord2f(texScale, texScale);
Gl.glVertex3f(x2, y2, z2);
Gl.glTexCoord2f(0.0f, texScale);
Gl.glVertex3f(x1, y2, z2);
// Side 3 (backward)
Gl.glNormal3f(0.0f, -1.0f, 0.0f);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex3f(x1, y1, z1);
Gl.glTexCoord2f(texScale, 0.0f);
Gl.glVertex3f(x2, y1, z1);
Gl.glTexCoord2f(texScale, texScale);
Gl.glVertex3f(x2, y1, z2);
Gl.glTexCoord2f(0.0f, texScale);
Gl.glVertex3f(x1, y1, z2);
// Side 4 (forward)
Gl.glNormal3f(0.0f, 1.0f, 0.0f);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex3f(x1, y2, z2);
Gl.glTexCoord2f(texScale, 0.0f);
Gl.glVertex3f(x2, y2, z2);
Gl.glTexCoord2f(texScale, texScale);
Gl.glVertex3f(x2, y2, z1);
Gl.glTexCoord2f(0.0f, texScale);
Gl.glVertex3f(x1, y2, z1);
// Side 5 (left)
Gl.glNormal3f(-1.0f, 0.0f, 0.0f);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex3f(x1, y1, z2);
Gl.glTexCoord2f(texScale, 0.0f);
Gl.glVertex3f(x1, y2, z2);
Gl.glTexCoord2f(texScale, texScale);
Gl.glVertex3f(x1, y2, z1);
Gl.glTexCoord2f(0.0f, texScale);
Gl.glVertex3f(x1, y1, z1);
// Side 6 (right)
Gl.glNormal3f(1.0f, 0.0f, 0.0f);
Gl.glTexCoord2f(0.0f, 0.0f);
Gl.glVertex3f(x2, y1, z1);
Gl.glTexCoord2f(texScale, 0.0f);
Gl.glVertex3f(x2, y2, z1);
Gl.glTexCoord2f(texScale, texScale);
Gl.glVertex3f(x2, y2, z2);
Gl.glTexCoord2f(0.0f, texScale);
Gl.glVertex3f(x2, y1, z2);
Gl.glEnd();
}
/// <summary>
/// GameLoop
/// </summary>
static void GameLoop() {
int playing;
GameEvent gameEvent;
// Initialize a new game
NewGame();
// Enable sticky keys
Glfw.glfwEnable(Glfw.GLFW_STICKY_KEYS);
// Loop until the game ends
playing = Gl.GL_TRUE;
while(playing == Gl.GL_TRUE && Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE) {
// Frame timer
oldTime = thisTime;
thisTime = Glfw.glfwGetTime();
dt = thisTime - oldTime;
// Get user input and update player positions
PlayerControl();
// Move the ball, and check if a player hits/misses the ball
gameEvent = BallControl();
// Did we have a winner?
switch(gameEvent) {
case GameEvent.Player1Wins:
winningPlayer = Player1.id;
playing = Gl.GL_FALSE;
break;
case GameEvent.Player2Wins:
winningPlayer = Player2.id;
playing = Gl.GL_FALSE;
break;
default:
break;
}
// Did the user press ESC?
if(Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Gl.GL_TRUE) {
playing = Gl.GL_FALSE;
}
// Did the user change camera view?
if(Glfw.glfwGetKey('1') == Gl.GL_TRUE) {
cameraPos = CameraPosition.Classic;
}
else if(Glfw.glfwGetKey('2') == Gl.GL_TRUE) {
cameraPos = CameraPosition.Above;
}
else if(Glfw.glfwGetKey('3') == Gl.GL_TRUE) {
cameraPos = CameraPosition.Spectator;
}
// Draw display
UpdateDisplay();
// Swap buffers
Glfw.glfwSwapBuffers();
}
// Disable sticky keys
Glfw.glfwDisable(Glfw.GLFW_STICKY_KEYS);
// Show winner
GameOver();
}
/// <summary>
/// BallControl
/// </summary>
/// <returns>A GameEvent</returns>
public static GameEvent BallControl() {
GameEvent gameEvent;
double ballspeed;
// Calculate new ball speed
ballspeed = ballSpeed * (1.0 + 0.02 * (thisTime - startTime));
gameBall.speedX = gameBall.speedX > 0 ? ballspeed : -ballspeed;
gameBall.speedY = gameBall.speedY > 0 ? ballspeed : -ballspeed;
gameBall.speedY *= 0.74321;
// Update ball position
gameBall.posX += dt * gameBall.speedX;
gameBall.posY += dt * gameBall.speedY;
// Did the ball hit a top/bottom wall?
if(gameBall.posY >= 1.0) {
gameBall.posY = 2.0 - gameBall.posY;
gameBall.speedY = -gameBall.speedY;
}
else if(gameBall.posY <= -1.0) {
gameBall.posY = -2.0 - gameBall.posY;
gameBall.speedY = -gameBall.speedY;
}
// Did the ball hit/miss a player?
gameEvent = GameEvent.NobodyWins;
// Is the ball entering the player 1 goal?
if(gameBall.posX < -1.0 + playerSizeX) {
// Did player 1 catch the ball?
if(gameBall.posY > (Player1.posY - playerSizeY) &&
gameBall.posY < (Player1.posY + playerSizeY)) {
gameBall.posX = -2.0 + 2.0 * playerSizeX - gameBall.posX;
gameBall.speedX = -gameBall.speedX;
}
else {
gameEvent = GameEvent.Player2Wins;
}
}
// Is the ball entering the player 2 goal?
if(gameBall.posX > 1.0 - playerSizeX) {
// Did player 2 catch the ball?
if(gameBall.posY > (Player2.posY - playerSizeY) &&
gameBall.posY < (Player2.posY + playerSizeY)) {
gameBall.posX = 2.0 - 2.0 * playerSizeX - gameBall.posX;
gameBall.speedX = -gameBall.speedX;
}
else {
gameEvent = GameEvent.Player1Wins;
}
}
return gameEvent;
}
/// <summary>
/// Main
///
/// Program entry point
/// </summary>
public static void Run() {
MenuOption menuoption;
envAmbient = new float[]{1.0f,1.0f,1.0f,1.0f};
light1Position = new float[]{-3.0f,3.0f,2.0f,1.0f};
light1Diffuse = new float[]{1.0f,1.0f,1.0f,0.0f};
light1Ambient = new float[]{0.0f,0.0f,0.0f,0.0f};
Player1Diffuse = new float[]{1.0f,0.3f,0.3f,1.0f};
Player1Ambient = new float[]{0.3f,0.1f,0.0f,1.0f};
Player2Diffuse = new float[]{0.3f,1.0f,0.3f,1.0f};
Player2Ambient = new float[]{0.1f,0.3f,0.1f,1.0f};
ballDiffuse = new float[]{1.0f,1.0f,0.5f,1.0f};
ballAmbient = new float[]{0.3f,0.3f,0.1f,1.0f};
borderDiffuse = new float[]{0.3f,0.3f,1.0f,1.0f};
borderAmbient = new float[]{0.1f,0.1f,0.3f,1.0f};
floorDiffuse = new float[]{1.0f,1.0f,1.0f,1.0f};
floorAmbient = new float[]{0.3f,0.3f,0.3f,1.0f};
Player1.id = 1;
Player2.id = 2;
// Initialize GLFW
if(Glfw.glfwInit() == Gl.GL_FALSE) {
System.Environment.Exit(0);
}
// Open OpenGL window
if(Glfw.glfwOpenWindow(width, height, 0, 0, 0, 0, 16, 0, Glfw.GLFW_FULLSCREEN) == Gl.GL_FALSE) {
Glfw.glfwTerminate();
System.Environment.Exit(0);
}
// Load all textures
LoadTextures();
// Main loop
do
{
// Get menu option
menuoption = GameMenu();
// If the user wants to play, let him...
if(menuoption == MenuOption.Play) {
GameLoop();
}
}
while( menuoption != MenuOption.Quit );
// Unload all textures
if(Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_FALSE) {
Gl.glDeleteTextures((int)Textures.Num_textures, TexId);
}
// Terminate GLFW
Glfw.glfwTerminate();
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace GlfwExamples
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new GlfwExamples());
}
}
}

Просмотреть файл

@ -0,0 +1,59 @@
#region License
/*
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
[assembly: AllowPartiallyTrustedCallers]
[assembly: AssemblyCompany("Randy Ridge http://www.taoframework.com")]
#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Retail")]
#endif
[assembly: AssemblyCopyright("©2003-2004 Randy Ridge. All rights reserved.")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyDefaultAlias("GlfwExamples.Triangle")]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyDescription("GLFW Triangle example.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyKeyName("")]
#if DEBUG
[assembly: AssemblyProduct("GlfwExamples.Triangle.exe *** Debug Build ***")]
#else
[assembly: AssemblyProduct("GlfwExamples.Triangle.exe")]
#endif
[assembly: AssemblyTitle("GLFW Triangle Example")]
[assembly: AssemblyTrademark("Randy Ridge")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: CLSCompliant(true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.Execution)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.SkipVerification)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.UnmanagedCode)]

Просмотреть файл

@ -0,0 +1,169 @@
#region License
/*
MIT License
Copyright ©2003-2004 Randy Ridge
http://www.taoframework.com
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#endregion License
#region Original Credits/License
/*
Copyright (c) 2002-2004 Marcus Geelnard
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
Marcus Geelnard
marcus.geelnard at home.se
*/
#endregion Original Credits/License
using System;
using Tao.Glfw;
using Tao.OpenGl;
namespace GlfwExamples {
#region Class Documentation
/// <summary>
/// This is a small test application for GLFW.
/// </summary>
/// <remarks>
/// The program opens a window (640x480), and renders a spinning colored triangle (it
/// is controlled with both the GLFW timer and the mouse). It also calculates the
/// rendering speed (FPS), which is displayed in the window title bar.
/// </remarks>
#endregion Class Documentation
public sealed class Triangle {
// --- Application Entry Point ---
#region Run()
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Run() {
int windowWidth, windowHeight;
int mouseX, mouseY;
bool isRunning;
double currentTime, startTime, frameRate;
int frameCount;
// Initialise GLFW
Glfw.glfwInit();
// Open OpenGL window
if(Glfw.glfwOpenWindow(640, 480, 0, 0, 0, 0, 0, 0, Glfw.GLFW_WINDOW) == Gl.GL_FALSE) {
Glfw.glfwTerminate();
return;
}
// Enable sticky keys
Glfw.glfwEnable(Glfw.GLFW_STICKY_KEYS);
// Disable vertical sync (on cards that support it)
Glfw.glfwSwapInterval(0);
// Main loop
isRunning = true;
frameCount = 0;
startTime = Glfw.glfwGetTime();
while(isRunning) {
// Get time and mouse position
currentTime = Glfw.glfwGetTime();
Glfw.glfwGetMousePos(out mouseX, out mouseY);
// Calculate and display FPS (frames per second)
if((currentTime - startTime) > 1.0 || frameCount == 0) {
frameRate = frameCount / (currentTime - startTime);
Glfw.glfwSetWindowTitle(string.Format("Spinning Triangle ({0:0} FPS)",
frameRate));
startTime = currentTime;
frameCount = 0;
}
frameCount++;
// Get window size (may be different than the requested size)
Glfw.glfwGetWindowSize(out windowWidth, out windowHeight);
windowHeight = windowHeight > 0 ? windowHeight : 1;
// Set viewport
Gl.glViewport(0, 0, windowWidth, windowHeight);
// Clear color buffer
Gl.glClearColor(0, 0, 0, 0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
// Select and setup the projection matrix
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(65, windowWidth / (double) windowHeight, 1, 100);
// Select and setup the modelview matrix
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt(0, 1, 0, // Eye-position
0, 20, 0, // View-point
0, 0, 1); // Up-vector
// Draw a rotating colorful triangle
Gl.glTranslatef(0, 14, 0);
Gl.glRotatef(0.3f * (float) mouseX + (float) currentTime * 100, 0, 0, 1);
Gl.glBegin(Gl.GL_TRIANGLES);
Gl.glColor3f(1, 0, 0);
Gl.glVertex3f(-5, 0, -4);
Gl.glColor3f(0, 1, 0);
Gl.glVertex3f(5, 0, -4);
Gl.glColor3f(0, 0, 1);
Gl.glVertex3f(0, 0, 6);
Gl.glEnd();
// Swap buffers
Glfw.glfwSwapBuffers();
// Check if the ESC key was pressed or the window was closed
isRunning = ((Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Glfw.GLFW_RELEASE) &&
Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE);
}
// Close OpenGL window and terminate GLFW
Glfw.glfwTerminate();
}
#endregion Run()
}
}