the_mickster
asked on
Rubik's Cube creation in OpenGL and C#
I am really new to OpenGL and I have a question about some code that I wrote. I am writting a Rubik's Cube program using C# .NET and OpenGL. I can generate the 27 individual cubes and I can use glRotate and glTranslate, but only when I call the resize event. I know that I am definitly doing something worng. Any help, or code about how to move the actual cube(s) not just the camera would be great! Thanks.
HERE'S what i have so far:
CUBE CLASS:
//**********************
// Namespace References
//**********************
using System;
using System.Drawing;
using System.Windows.Forms;
using CsGL.OpenGL;
namespace cube
{
public class OurView : OpenGLControl
{
//************************ ********** ********** **
//Global Variable Declaration and Instantiation
//************************ ********** ********** **
float xDeg = 0.0f;
float yDeg = 0.0f;
public OurView()
: base()
{
//Creates our own Keyboard event.
this.KeyDown += new KeyEventHandler(OurView_On KeyDown);
}
public override void glDraw()
{
// Clear the buffers before drawing the cube.
GL.glClear(GL.GL_COLOR_BUF FER_BIT | GL.GL_DEPTH_BUFFER_BIT);
GL.glLoadIdentity();
// Translate into the screen.
GL.glTranslatef(0.0f, 0.0f, -10.0f);
GL.glRotatef(xDeg, 1.0f, 0.0f, 0.0f);
GL.glRotatef(yDeg, 0.0f, 1.0f, 0.0f);
this.glDrawCube();
}
protected override void InitGLContext()
{
GL.glShadeModel(GL.GL_SMOO TH); // Set Smooth Shading
//GL.glClear(GL.GL_COLOR_B UFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clears the color buffer
GL.glClearColor(0.4f, 0.4f, 0.4f, 0.0f); // BackGround Color
GL.glClearDepth(1.0f); // Depth buffer setup
GL.glEnable(GL.GL_DEPTH_TE ST); // Enables Depth Testing
GL.glDepthFunc(GL.GL_LEQUA L); // The Type Of Depth Test To Do
GL.glHint(GL.GL_PERSPECTIV E_CORRECTI ON_HINT, GL.GL_NICEST); // Really Nice Perspective Calculations
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
Size s = Size;
double aspect_ratio = (double)s.Width / (double)s.Height;
GL.glMatrixMode(GL.GL_PROJ ECTION); // Select The Projection Matrix
GL.glLoadIdentity(); // Reset The Projection Matrix
GL.gluPerspective(45.0f, aspect_ratio, 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
GL.glMatrixMode(GL.GL_MODE LVIEW); // Select The Modelview Matrix
GL.glLoadIdentity(); // Reset The Modelview Matrix
}
/************************* ********** ********** ********** ********** *********
* glDrawCube
* - Description:
* - Contains the 3 loops for generating the 27 individual cublets.
* - Parameters:(None)
* - Local Variables
* - xMark = x coordinate; yMark = y coordinate; zMark = z coordinate
* -Returns:(void)
************************** ********** ********** ********** ********** ********
*/
public void glDrawCube()
{
float xMark = -1.0f;
float yMark = -1.0f;
float zMark = 1.0f;
for (int i = 0; i < 3; i++)
//moves back one unit on z-axis
{
for (int j = 0; j < 3; j++)
//moves up one unit on y-axis
{
for (int k = 0; k < 3; k++)
//builds 3 cubes along x-axis
{
buildCubeSolid(xMark, yMark, zMark);
buildCubeWire(xMark, yMark, zMark);
xMark++;
}
xMark = -1.0f;
yMark++;
}
yMark = -1.0f;
zMark--;
}
}
/************************* ********** ********** ********** *****
* buildCubeSolid
* - Description:
* - Draws the cublet using the OpenGL method GL_QUADS.
* - Parameters:
* - x: x coordinate to start drawing from.
* - y: y coordinate to start drawing from.
* - z: z coordinate to start drawing from.
* - Local Varibles:(none)
* - Returns(void)
************************** ********** ********** ********** *****
*/
public void buildCubeSolid(float x, float y, float z)
{
//draws a cube based on the center given
GL.glBegin(GL.GL_QUADS);
//TOP - GREEN
GL.glColor3f(0.0f, 1.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
//BOTTOM - ORANGE
GL.glColor3f(1.0f, 0.5f, 0.0f);
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
//FRONT - RED
GL.glColor3f(1.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
//BACK - YELLOW
GL.glColor3f(1.0f, 1.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
//LEFT - BLUE
GL.glColor3f(0.0f, 0.0f, 1.0f);
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
//RIGHT - VIOLET
GL.glColor3f(1.0f, 0.0f, 1.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
}
/************************* ********** ********** ********** ********** ********** ****
* buildCubeWire
* - Description:
* - Draws the outline of the cublet using the OpenGL method GL_LINE_LOOP.
* - Parameters:
* - x: x coordinate to start drawing from.
* - y: y coordinate to start drawing from.
* - z: z coordinate to start drawing from.
* - Local Varibles:(none)
* - Returns(void)
************************** ********** ********** ********** ********** ********** ***
*/
public void buildCubeWire(float x, float y, float z)
{
//draw black lines on all edges of the minicubes
//TOP
GL.glBegin(GL.GL_LINE_LOOP );
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glEnd();
//BOTTOM
GL.glBegin(GL.GL_LINE_LOOP );
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
//FRONT
GL.glBegin(GL.GL_LINE_LOOP );
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
//BACK
GL.glBegin(GL.GL_LINE_LOOP );
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glEnd();
//LEFT
GL.glBegin(GL.GL_LINE_LOOP );
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glEnd();
//RIGHT
GL.glBegin(GL.GL_LINE_LOOP );
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
}
/************************* ********** ********** ********** ********** ********** **
* OurView_OnKeyDown
* - Description:
* - Contains a switch statement to do something based upon which key
* the user presses.
* - Parameters:
* - Sender: refernce to the window object
* - kea: class that contains refernces to all the keys on the keyboard
* - Local Varibles:(none)
* - Returns(void)
************************** ********** ********** ********** ********** ********** *
*/
protected void OurView_OnKeyDown(object Sender, KeyEventArgs kea)
{
switch (kea.KeyCode)
{
case Keys.NumPad8:
xDeg += 10.0f;
this.Height += 1;
break;
case Keys.NumPad2:
xDeg -= 10.0f;
this.Height -= 1;
break;
case Keys.NumPad4:
yDeg -= 10.0f;
this.Width -= 1;
break;
case Keys.NumPad6:
yDeg += 10.0f;
this.Width += 1;
break;
case Keys.Escape:
Application.Exit();
break;
}
}
}
MAIN:
using System;
using System.Collections.Generic ;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using CsGL.OpenGL;
using System.Windows.Forms;
namespace cube
{
public partial class frmMain : Form
{
//Declarations
private cube.OurView view;
private about ab;
private static Thread thrOpenGL;
public frmMain()
{
InitializeComponent();
this.view = new cube.OurView();
this.view.Parent = this;
this.view.Dock = DockStyle.Fill ; // Will fill top of the form
thrOpenGL = new Thread(new ThreadStart(OpenGL_Start)) ;
thrOpenGL.Start();
}
private void OpenGL_Start()
{
// for (; ; ) // infinity loop for rendering
// {
this.view.glDraw();
// }
}
private void m_exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void m_about_Click(object sender, EventArgs e)
{
ab = new about();
ab.Show();
}
}
}
HERE'S what i have so far:
CUBE CLASS:
//**********************
// Namespace References
//**********************
using System;
using System.Drawing;
using System.Windows.Forms;
using CsGL.OpenGL;
namespace cube
{
public class OurView : OpenGLControl
{
//************************
//Global Variable Declaration and Instantiation
//************************
float xDeg = 0.0f;
float yDeg = 0.0f;
public OurView()
: base()
{
//Creates our own Keyboard event.
this.KeyDown += new KeyEventHandler(OurView_On
}
public override void glDraw()
{
// Clear the buffers before drawing the cube.
GL.glClear(GL.GL_COLOR_BUF
GL.glLoadIdentity();
// Translate into the screen.
GL.glTranslatef(0.0f, 0.0f, -10.0f);
GL.glRotatef(xDeg, 1.0f, 0.0f, 0.0f);
GL.glRotatef(yDeg, 0.0f, 1.0f, 0.0f);
this.glDrawCube();
}
protected override void InitGLContext()
{
GL.glShadeModel(GL.GL_SMOO
//GL.glClear(GL.GL_COLOR_B
GL.glClearColor(0.4f, 0.4f, 0.4f, 0.0f); // BackGround Color
GL.glClearDepth(1.0f); // Depth buffer setup
GL.glEnable(GL.GL_DEPTH_TE
GL.glDepthFunc(GL.GL_LEQUA
GL.glHint(GL.GL_PERSPECTIV
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
Size s = Size;
double aspect_ratio = (double)s.Width / (double)s.Height;
GL.glMatrixMode(GL.GL_PROJ
GL.glLoadIdentity(); // Reset The Projection Matrix
GL.gluPerspective(45.0f, aspect_ratio, 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
GL.glMatrixMode(GL.GL_MODE
GL.glLoadIdentity(); // Reset The Modelview Matrix
}
/*************************
* glDrawCube
* - Description:
* - Contains the 3 loops for generating the 27 individual cublets.
* - Parameters:(None)
* - Local Variables
* - xMark = x coordinate; yMark = y coordinate; zMark = z coordinate
* -Returns:(void)
**************************
*/
public void glDrawCube()
{
float xMark = -1.0f;
float yMark = -1.0f;
float zMark = 1.0f;
for (int i = 0; i < 3; i++)
//moves back one unit on z-axis
{
for (int j = 0; j < 3; j++)
//moves up one unit on y-axis
{
for (int k = 0; k < 3; k++)
//builds 3 cubes along x-axis
{
buildCubeSolid(xMark, yMark, zMark);
buildCubeWire(xMark, yMark, zMark);
xMark++;
}
xMark = -1.0f;
yMark++;
}
yMark = -1.0f;
zMark--;
}
}
/*************************
* buildCubeSolid
* - Description:
* - Draws the cublet using the OpenGL method GL_QUADS.
* - Parameters:
* - x: x coordinate to start drawing from.
* - y: y coordinate to start drawing from.
* - z: z coordinate to start drawing from.
* - Local Varibles:(none)
* - Returns(void)
**************************
*/
public void buildCubeSolid(float x, float y, float z)
{
//draws a cube based on the center given
GL.glBegin(GL.GL_QUADS);
//TOP - GREEN
GL.glColor3f(0.0f, 1.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
//BOTTOM - ORANGE
GL.glColor3f(1.0f, 0.5f, 0.0f);
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
//FRONT - RED
GL.glColor3f(1.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
//BACK - YELLOW
GL.glColor3f(1.0f, 1.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
//LEFT - BLUE
GL.glColor3f(0.0f, 0.0f, 1.0f);
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
//RIGHT - VIOLET
GL.glColor3f(1.0f, 0.0f, 1.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
}
/*************************
* buildCubeWire
* - Description:
* - Draws the outline of the cublet using the OpenGL method GL_LINE_LOOP.
* - Parameters:
* - x: x coordinate to start drawing from.
* - y: y coordinate to start drawing from.
* - z: z coordinate to start drawing from.
* - Local Varibles:(none)
* - Returns(void)
**************************
*/
public void buildCubeWire(float x, float y, float z)
{
//draw black lines on all edges of the minicubes
//TOP
GL.glBegin(GL.GL_LINE_LOOP
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glEnd();
//BOTTOM
GL.glBegin(GL.GL_LINE_LOOP
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
//FRONT
GL.glBegin(GL.GL_LINE_LOOP
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
//BACK
GL.glBegin(GL.GL_LINE_LOOP
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glEnd();
//LEFT
GL.glBegin(GL.GL_LINE_LOOP
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x - .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x - .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x - .5f), (y - .5f), (z + .5f));
GL.glEnd();
//RIGHT
GL.glBegin(GL.GL_LINE_LOOP
GL.glColor3f(0.0f, 0.0f, 0.0f);
GL.glVertex3f((x + .5f), (y + .5f), (z + .5f));
GL.glVertex3f((x + .5f), (y + .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z - .5f));
GL.glVertex3f((x + .5f), (y - .5f), (z + .5f));
GL.glEnd();
}
/*************************
* OurView_OnKeyDown
* - Description:
* - Contains a switch statement to do something based upon which key
* the user presses.
* - Parameters:
* - Sender: refernce to the window object
* - kea: class that contains refernces to all the keys on the keyboard
* - Local Varibles:(none)
* - Returns(void)
**************************
*/
protected void OurView_OnKeyDown(object Sender, KeyEventArgs kea)
{
switch (kea.KeyCode)
{
case Keys.NumPad8:
xDeg += 10.0f;
this.Height += 1;
break;
case Keys.NumPad2:
xDeg -= 10.0f;
this.Height -= 1;
break;
case Keys.NumPad4:
yDeg -= 10.0f;
this.Width -= 1;
break;
case Keys.NumPad6:
yDeg += 10.0f;
this.Width += 1;
break;
case Keys.Escape:
Application.Exit();
break;
}
}
}
MAIN:
using System;
using System.Collections.Generic
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using CsGL.OpenGL;
using System.Windows.Forms;
namespace cube
{
public partial class frmMain : Form
{
//Declarations
private cube.OurView view;
private about ab;
private static Thread thrOpenGL;
public frmMain()
{
InitializeComponent();
this.view = new cube.OurView();
this.view.Parent = this;
this.view.Dock = DockStyle.Fill ; // Will fill top of the form
thrOpenGL = new Thread(new ThreadStart(OpenGL_Start))
thrOpenGL.Start();
}
private void OpenGL_Start()
{
// for (; ; ) // infinity loop for rendering
// {
this.view.glDraw();
// }
}
private void m_exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void m_about_Click(object sender, EventArgs e)
{
ab = new about();
ab.Show();
}
}
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I will only award point for suggestions in C# on how to successfully move my cube. I'm sorry, but that's what i really need. Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
These two tutorials look like they may help me out a bunch. I will take a look at them in the next few hours and get back to you. Thanks.
ASKER
Those two tutorials helped somewhat. Is there anyone who is experienced with structures and arrays within structs that could help me out with some code or tutorials??
Just explain in more detail what you want to know and I will tell you.
ASKER
Okay. Here's what I'm going after right now.
1.) I am starting to make a struct for each of the 27 cublets. The struct will have a unique ID, an array that stores that face colors for the cube. and an array for all the points of the cube.
2.) I'm having trouble wrapping my mind around the array that needs to store all the points and then manipulating the points.
3.) I plan on using the face color array and the points array to move the slices of the cube just like you are playing the game.
Thanks for all of your help by the way!
1.) I am starting to make a struct for each of the 27 cublets. The struct will have a unique ID, an array that stores that face colors for the cube. and an array for all the points of the cube.
2.) I'm having trouble wrapping my mind around the array that needs to store all the points and then manipulating the points.
3.) I plan on using the face color array and the points array to move the slices of the cube just like you are playing the game.
Thanks for all of your help by the way!
ASKER