using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Drawing;
using sharp3d; // DllImport
namespace sharpgl
{
///
/// Summary description for OpenGLForm.
///
public class OpenGLForm : Form
{
public static float xrot; // X-axis rotation
public static float yrot; // Y-axis rotation
public static float zrot; // Z-axis rotation
public static uint[] texture; // texture
#region Member Variables
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
private static uint _hwnd = 0;
private static uint _hDC = 0;
private static uint _hRC = 0;
private bool _appActive = true;
public bool FullScreen { get; set; }
public static bool Done { get; set; }
#endregion
#region Win32 Interop
// Constant values were found in the "WinUser.h" header file.
public const int WM_ACTIVATEAPP = 0x001C;
public const int WA_ACTIVE = 1;
public const int WA_CLICKACTIVE = 2;
public const int CDS_FULLSCREEN = 0x00000004; // Flag for ChangeDisplaySettings
public const int DISP_CHANGE_SUCCESSFUL = 0; // Return value for ChangeDisplaySettings
// Constant values were found in the "WinGDI.h" header file.
public const int CCHDEVICENAME = 32; // size of a device name string
public const int CCHFORMNAME = 32; // size of a form name string
public const int DM_BITSPERPEL = 0x40000;
public const int DM_PELSWIDTH = 0x80000;
public const int DM_PELSHEIGHT = 0x100000;
public const int BITSPIXEL = 12; // number of bits per pixel
public const uint PFD_DOUBLEBUFFER = 0x00000001; // PIXELFORMATDESCRIPTOR flag
public const uint PFD_DRAW_TO_WINDOW = 0x00000004; // PIXELFORMATDESCRIPTOR flag
public const uint PFD_SUPPORT_OPENGL = 0x00000020; // PIXELFORMATDESCRIPTOR flag
public const uint PFD_TYPE_RGBA = 0; // pixel type
public const uint PFD_MAIN_PLANE = 0; // layer type
[StructLayout(LayoutKind.Sequential)]
public struct PIXELFORMATDESCRIPTOR
{
public ushort nSize;
public ushort nVersion;
public uint dwFlags;
public byte iPixelType;
public byte cColorBits;
public byte cRedBits;
public byte cRedShift;
public byte cGreenBits;
public byte cGreenShift;
public byte cBlueBits;
public byte cBlueShift;
public byte cAlphaBits;
public byte cAlphaShift;
public byte cAccumBits;
public byte cAccumRedBits;
public byte cAccumGreenBits;
public byte cAccumBlueBits;
public byte cAccumAlphaBits;
public byte cDepthBits;
public byte cStencilBits;
public byte cAuxBuffers;
public byte iLayerType;
public byte bReserved;
public uint dwLayerMask;
public uint dwVisibleMask;
public uint dwDamageMask;
}
// by marking the structure with CharSet.Auto, the structure will get marshaled as Unicode characters
// on Unicode platforms, if not the name fields would always get marshaled as arrays of ANSI characters
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class DEVMODE
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHDEVICENAME)]
public char[] dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public DEVMODE_UNION u;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHFORMNAME)]
public char[] dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlagsOrdmNup; // union of dmDisplayFlags and dmNup
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
// modeling a union in C#, each possible struct data type starts at FieldOffset 0
[StructLayout(LayoutKind.Explicit)]
public struct DEVMODE_UNION
{
[FieldOffset(0)]
public short dmOrientation;
[FieldOffset(2)]
public short dmPaperSize;
[FieldOffset(4)]
public short dmPaperLength;
[FieldOffset(6)]
public short dmPaperWidth;
[FieldOffset(8)]
public short dmScale;
[FieldOffset(10)]
public short dmCopies;
[FieldOffset(12)]
public short dmDefaultSource;
[FieldOffset(14)]
public short dmPrintQuality;
[FieldOffset(0)]
public int dmPosition_x;
[FieldOffset(4)]
public int dmPosition_y;
[FieldOffset(0)]
public int dmDisplayOrientation;
[FieldOffset(0)]
public int dmDisplayFixedOutput;
}
#endregion
#region DLLImport
[DllImport("kernel32")]
public static extern uint GetLastError();
[DllImport("user32")]
public static extern uint GetDC(uint hwnd);
[DllImport("user32")]
public static extern int ReleaseDC(uint hWnd, uint hDC);
[DllImport("user32", CharSet = CharSet.Auto)]
public static extern int ChangeDisplaySettings([MarshalAs(UnmanagedType.LPStruct)] DEVMODE lpDevMode, uint dwflags);
[DllImport("user32")]
public static extern int ShowCursor(bool bShow);
[DllImport("gdi32")]
public static extern int ChoosePixelFormat(uint hdc, ref PIXELFORMATDESCRIPTOR ppfd);
[DllImport("gdi32")]
public static extern int SetPixelFormat(uint hdc, int iPixelFormat, ref PIXELFORMATDESCRIPTOR ppfd);
[DllImport("gdi32")]
public static extern int GetDeviceCaps(uint hdc, int nIndex);
[DllImport("opengl32")]
public static extern uint wglCreateContext(uint hdc);
[DllImport("opengl32")]
public static extern bool wglDeleteContext(uint hrc);
[DllImport("opengl32")]
public static extern uint wglSwapBuffers(uint hdc);
[DllImport("opengl32")]
public static extern bool wglMakeCurrent(uint hdc, uint hglrc);
#endregion
#region OpenGLSetup
private bool SetupPixelFormat(ref uint hdc)
{
PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
ushort pfdSize = (ushort)Marshal.SizeOf(typeof(PIXELFORMATDESCRIPTOR)); // sizeof(PIXELFORMATDESCRIPTOR)
pfd.nSize = pfdSize; // size of pfd
pfd.nVersion = 1; // version number
pfd.dwFlags = (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER); // flags
pfd.iPixelType = (byte)PFD_TYPE_RGBA; // RGBA type
pfd.cColorBits = (byte)GetDeviceCaps(hdc, BITSPIXEL); // color depth
pfd.cRedBits = 0; // color bits ignored
pfd.cRedShift = 0;
pfd.cGreenBits = 0;
pfd.cGreenShift = 0;
pfd.cBlueBits = 0;
pfd.cBlueShift = 0;
pfd.cAlphaBits = 0; // no alpha buffer
pfd.cAlphaShift = 0; // shift bit ignored
pfd.cAccumBits = 0; // no accumulation buffer
pfd.cAccumRedBits = 0; // accum bits ignored
pfd.cAccumGreenBits = 0;
pfd.cAccumBlueBits = 0;
pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = 32; // 32-bit z-buffer
pfd.cStencilBits = 0; // no stencil buffer
pfd.cAuxBuffers = 0; // no auxiliary buffer
pfd.iLayerType = (byte)PFD_MAIN_PLANE; // main layer
pfd.bReserved = 0; // reserved
pfd.dwLayerMask = 0; // layer masks ignored
pfd.dwVisibleMask = 0;
pfd.dwDamageMask = 0;
int pixelformat = ChoosePixelFormat(hdc, ref pfd);
if (pixelformat == 0) // Did Windows Find A Matching Pixel Format?
{
MessageBox.Show("Can't Find A Suitable PixelFormat.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (SetPixelFormat(hdc, pixelformat, ref pfd) == 0) // Are We Able To Set The Pixel Format?
{
MessageBox.Show("Can't Set The PixelFormat.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
return true;
}
private bool InitGL()
{
OpenGL.glShadeModel(OpenGL.GL_SMOOTH);
OpenGL.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
OpenGL.glClearDepth(1.0f);
OpenGL.glEnable(OpenGL.GL_DEPTH_TEST);
OpenGL.glDepthFunc(OpenGL.GL_LEQUAL);
OpenGL.glHint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST);
OpenGL.glEnable(OpenGL.GL_TEXTURE_2D);
//OpenGL.glPolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_LINE);
return true;
}
public bool SetupRenderingContext()
{
if (!CreateGLWindow())
{
return false; // initialization failed, quit
}
_hwnd = (uint)((this.Handle).ToInt32());
_hDC = GetDC(_hwnd);
if (_hDC == 0)
{
MessageBox.Show("Can't Create A GL Device Context", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
// not doing the following wglSwapBuffers() on the DC will result in a failure to subsequently create the RC
wglSwapBuffers(_hDC);
if (!SetupPixelFormat(ref _hDC))
{
return false;
}
// create the rendering context and make it current
_hRC = wglCreateContext(_hDC);
if (_hRC == 0) // Are We Able To Get A Rendering Context?
{
MessageBox.Show("Can't Create A GL Rendering Context.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (!wglMakeCurrent(_hDC, _hRC)) // Try To Activate The Rendering Context
{
MessageBox.Show("Can't Activate The GL Rendering Context.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
OpenGLForm_Resize(this, new EventArgs()); // Set up the perspective GL screen
return InitGL(); // Initialize Our Newly Created GL Window
}
#endregion
#region FormSetup
private bool CreateGLWindow()
{
Resize += new EventHandler(OpenGLForm_Resize);
if (FullScreen)
{
TopMost = true;
WindowState = System.Windows.Forms.FormWindowState.Maximized;
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
// The cursor is displayed only if the display count is greater than or equal to 0
do
{
} while (ShowCursor(false) >= 0);
DEVMODE dmScreenSettings = new DEVMODE(); // Device Mode
dmScreenSettings.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE)); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = 640; // Selected Screen Width
dmScreenSettings.dmPelsHeight = 480; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = 16; // Selected Bits Per Pixel
dmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox.Show("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?",
"Error", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.Yes)
{
FullScreen = false; // Windowed Mode Selected. Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox.Show("Program Will Now Close.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return false; // setup failed, finished
}
}
}
if (!FullScreen)
{
TopMost = false;
WindowState = System.Windows.Forms.FormWindowState.Normal;
FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
// The cursor is displayed only if the display count is greater than or equal to 0
do
{
} while (ShowCursor(true) < 0);
}
return true;
}
#endregion
#region Constructor/Destructor
public OpenGLForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
this.FormClosing += new FormClosingEventHandler(OpenGLForm_FormClosing);
}
void OpenGLForm_FormClosing(object sender, FormClosingEventArgs e)
{
Done = true;
}
///
/// Clean up any resources being used.
///
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
if (_hRC != 0) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(0, 0)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox.Show("Release Of DC And RC Failed.", "Shutdown Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
if (!wglDeleteContext(_hRC)) // Are We Able To Delete The RC?
{
MessageBox.Show("Release Rendering Context Failed.", "Shutdown Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
if (_hDC != 0 && ReleaseDC(_hwnd, _hDC) == 0) // Are We Able To Release The DC
{
MessageBox.Show("Release Device Context Failed.", "Shutdown Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
base.Dispose(disposing);
}
#endregion
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.SuspendLayout();
//
// OpenGLForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(632, 453);
this.KeyPreview = true;
this.Name = "OpenGLForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "MainForm";
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OpenGLForm_KeyUp);
this.ResumeLayout(false);
}
#endregion
#region Events
protected override void WndProc(ref System.Windows.Forms.Message m)
{
// Listen for operating system messages.
switch (m.Msg)
{
// The WM_ACTIVATEAPP message occurs when the application
// becomes the active application or becomes inactive.
case WM_ACTIVATEAPP:
{
// The WParam value identifies what is occurring.
_appActive = ((int)m.WParam == WA_ACTIVE || (int)m.WParam == WA_CLICKACTIVE);
// Invalidate to get new scene painted.
Invalidate();
break;
}
default:
{
break;
}
}
base.WndProc(ref m);
}
/*!
This will stop the display from flickering on Paint event
*/
protected override void OnPaintBackground(PaintEventArgs e)
{
}
protected override void OnPaint(PaintEventArgs e)
{
if (_appActive)
{
Draw();
wglSwapBuffers(_hDC);
Invalidate();
}
}
private void OpenGLForm_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Escape:
{
Close();
Done = true;
break;
}
case Keys.F1:
{
if (FullScreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(null, 0); // If So Switch Back To The Desktop
}
FullScreen = !FullScreen;
Done = false;
Close(); // raise Close event to kill the current form, the form will get re-created in Main
break;
}
default:
{
break;
}
}
}
private void OpenGLForm_Resize(object sender, EventArgs e) // Resize And Initialize The GL Window
{
int width = ClientRectangle.Width;
int height = ClientRectangle.Height;
if (height == 0) // Prevent A Divide By Zero By
{
height = 1; // Making Height Equal One
}
OpenGL.glViewport(0, 0, width, height); // Reset The Current Viewport
OpenGL.glMatrixMode(OpenGL.GL_PROJECTION); // Select The Projection Matrix
OpenGL.glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
OpenGLU.gluPerspective(45.0f, (double)width / (double)height, 0.1f, 100.0f);
OpenGL.glMatrixMode(OpenGL.GL_MODELVIEW); // Select The Modelview Matrix
OpenGL.glLoadIdentity(); // Reset The Modelview Matrix
}
#endregion
public static MDLFile model = null;
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
bool fullScreen = false;
texture = new uint[1]; // storage for texture
while (!Done)
{
OpenGLForm form = new OpenGLForm(); // create the form
form.FullScreen = fullScreen; // set the user display property option
if (!form.SetupRenderingContext()) // setup form and OpenGL
{
break; // initialization failed, quit
}
else
{
model = new MDLFile("../../Models/Footman.mdl");
model.Parse();
}
Application.Run(form);
if (OpenGLForm.Done) // Was There A Quit Received?
{
break;
}
fullScreen = form.FullScreen; // switching between full screen and windowed, persist full screen option between forms
}
}
public static void GenerateTexture(Texture texture)
{
Bitmap image = new Bitmap(texture.Image);
System.Drawing.Imaging.BitmapData bitmapdata;
Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
uint index = 0;
OpenGL.glGenTextures(1, out index);
texture.TextureName = (int)index;
//uint error = OpenGL.glGetError();
OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, index);
OpenGL.glTexImage2D(OpenGL.GL_TEXTURE_2D, 0, (int)OpenGL.GL_RGB8, (uint)image.Width, (uint)image.Height, 0, OpenGLExt.GL_BGR_EXT, OpenGL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, (int)OpenGL.GL_LINEAR);
OpenGL.glTexParameteri(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, (int)OpenGL.GL_LINEAR);
image.UnlockBits(bitmapdata);
image.Dispose();
}
int time = 0;
public bool Draw()
{
OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
OpenGL.glMatrixMode(OpenGL.GL_MODELVIEW);
OpenGL.glLoadIdentity();
OpenGL.glTranslatef(0.0f, -12.0f, -50.0f);
//OpenGL.glTranslatef(0.0f, 0.0f, -5.0f);
OpenGL.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
//xrot += 0.3f;
//OpenGL.glRotatef(-90.0f + yrot, 0.0f, 1.0f, 0.0f);
//yrot -= .04f;
OpenGL.glRotatef(-90.0f + zrot, 0.0f, 0.0f, 1.0f);
zrot += 0.04f;
//OpenGL.glRotatef(90f, 1.0f, 0.0f, 0.0f);
OpenGL.glScalef(0.3f, 0.3f, 0.3f);
uint error = OpenGL.glGetError();
time++;
foreach (Shape shape in model.Shapes)
{
// TODO: manage multiple layers
Material material = model.Materials[shape.MaterialId];
int textureId = material.Layers[0].TextureId;
if (string.IsNullOrEmpty(model.Textures[textureId].Image) && material.Layers.Count > 1)
{
textureId = material.Layers[1].TextureId;
}
int textureName = 1;
textureName = model.Textures[textureId].TextureName;
OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, (uint)textureName);
//error = OpenGL.glGetError();
OpenGL.glBegin(OpenGL.GL_TRIANGLES);
foreach (Triangle triangle in shape.Triangles)
{
if (triangle != null)
{
Vertex v1 = shape.Vertices[triangle.Vertices[0]];
Vertex v2 = shape.Vertices[triangle.Vertices[1]];
Vertex v3 = shape.Vertices[triangle.Vertices[2]];
TextureVertex tv1 = shape.TextureVertices[triangle.Vertices[0]];
TextureVertex tv2 = shape.TextureVertices[triangle.Vertices[1]];
TextureVertex tv3 = shape.TextureVertices[triangle.Vertices[2]];
OpenGL.glTexCoord2f(tv1.x, tv1.y);
OpenGL.glVertex3f(v1.x, v1.y, v1.z);
OpenGL.glTexCoord2f(tv2.x, tv2.y);
OpenGL.glVertex3f(v2.x, v2.y, v2.z);
OpenGL.glTexCoord2f(tv3.x, tv3.y);
OpenGL.glVertex3f(v3.x, v3.y, v3.z);
}
}
OpenGL.glEnd();
//break;
}
//glDraw();
return true;
}
public void glDraw()
{
OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
OpenGL.glMatrixMode(OpenGL.GL_MODELVIEW);
OpenGL.glLoadIdentity();
OpenGL.glTranslatef(0.0f, 0.0f, -5.0f);
OpenGL.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
xrot += 0.3f;
OpenGL.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
yrot += 0.2f;
OpenGL.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
zrot += 0.4f;
OpenGL.glBegin(OpenGL.GL_QUADS);
// Front Face
OpenGL.glTexCoord2f(1.0f, 1.0f); // top right of texture
OpenGL.glVertex3f(1.0f, 1.0f, 1.0f); // top right of quad
OpenGL.glTexCoord2f(0.0f, 1.0f); // top left of texture
OpenGL.glVertex3f(-1.0f, 1.0f, 1.0f); // top left of quad
OpenGL.glTexCoord2f(0.0f, 0.0f); // bottom left of texture
OpenGL.glVertex3f(-1.0f, -1.0f, 1.0f); // bottom left of quad
OpenGL.glTexCoord2f(1.0f, 0.0f); // bottom right of texture
OpenGL.glVertex3f(1.0f, -1.0f, 1.0f); // bottom right of quad
// Back Face
OpenGL.glTexCoord2f(1.0f, 1.0f); // top right of texture
OpenGL.glVertex3f(-1.0f, 1.0f, -1.0f); // top right of quad
OpenGL.glTexCoord2f(0.0f, 1.0f); // top left of texture
OpenGL.glVertex3f(1.0f, 1.0f, -1.0f); // top left of quad
OpenGL.glTexCoord2f(0.0f, 0.0f); // bottom left of texture
OpenGL.glVertex3f(1.0f, -1.0f, -1.0f); // bottom left of quad
OpenGL.glTexCoord2f(1.0f, 0.0f); // bottom right of texture
OpenGL.glVertex3f(-1.0f, -1.0f, -1.0f); // bottom right of quad
// Top Face
OpenGL.glTexCoord2f(1.0f, 1.0f); // top right of texture
OpenGL.glVertex3f(1.0f, 1.0f, -1.0f); // top right of quad
OpenGL.glTexCoord2f(0.0f, 1.0f); // top left of texture
OpenGL.glVertex3f(-1.0f, 1.0f, -1.0f); // top left of quad
OpenGL.glTexCoord2f(0.0f, 0.0f); // bottom left of texture
OpenGL.glVertex3f(-1.0f, 1.0f, 1.0f); // bottom left of quad
OpenGL.glTexCoord2f(1.0f, 0.0f); // bottom right of texture
OpenGL.glVertex3f(1.0f, 1.0f, 1.0f); // bottom right of quad
// Bottom Face
OpenGL.glTexCoord2f(1.0f, 1.0f); // top right of texture
OpenGL.glVertex3f(1.0f, -1.0f, 1.0f); // top right of quad
OpenGL.glTexCoord2f(0.0f, 1.0f); // top left of texture
OpenGL.glVertex3f(-1.0f, -1.0f, 1.0f); // top left of quad
OpenGL.glTexCoord2f(0.0f, 0.0f); // bottom left of texture
OpenGL.glVertex3f(-1.0f, -1.0f, -1.0f); // bottom left of quad
OpenGL.glTexCoord2f(1.0f, 0.0f); // bottom right of texture
OpenGL.glVertex3f(1.0f, -1.0f, -1.0f); // bottom right of quad
// Right Face
OpenGL.glTexCoord2f(1.0f, 1.0f); // top right of texture
OpenGL.glVertex3f(1.0f, 1.0f, -1.0f); // top right of quad
OpenGL.glTexCoord2f(0.0f, 1.0f); // top left of texture
OpenGL.glVertex3f(1.0f, 1.0f, 1.0f); // top left of quad
OpenGL.glTexCoord2f(0.0f, 0.0f); // bottom left of texture
OpenGL.glVertex3f(1.0f, -1.0f, 1.0f); // bottom left of quad
OpenGL.glTexCoord2f(1.0f, 0.0f); // bottom right of texture
OpenGL.glVertex3f(1.0f, -1.0f, -1.0f); // bottom right of quad
// Left Face
OpenGL.glTexCoord2f(1.0f, 1.0f); // top right of texture
OpenGL.glVertex3f(-1.0f, 1.0f, 1.0f); // top right of quad
OpenGL.glTexCoord2f(0.0f, 1.0f); // top left of texture
OpenGL.glVertex3f(-1.0f, 1.0f, -1.0f); // top left of quad
OpenGL.glTexCoord2f(0.0f, 0.0f); // bottom left of texture
OpenGL.glVertex3f(-1.0f, -1.0f, -1.0f); // bottom left of quad
OpenGL.glTexCoord2f(1.0f, 0.0f); // bottom right of texture
OpenGL.glVertex3f(-1.0f, -1.0f, 1.0f); // bottom right of quad
OpenGL.glEnd();
}
}
}