I am absolutely new to OpenGL.
I am getting the following output -
Please, remember that, this output is only visible when I use gl.Rotate()
. That means, the cube needs to be placed away from the viewer.
However, I am unable to do that.
- How can I place the cube at a proper location and rotate it around Y-axis so that it is visible all the time?
My source code:
public static class OpenGLhelper
{
public static void Init(OpenGL gl)
{
gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
gl.ClearDepth(1.0f); // Set background depth to farthest
gl.Enable(OpenGL.GL_DEPTH_TEST); // Enable depth testing for z-culling
gl.DepthFunc(OpenGL.GL_LEQUAL); // Set the type of depth-test
gl.ShadeModel(OpenGL.GL_SMOOTH); // Enable smooth shading
gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST); // Nice perspective corrections
}
public static void Display(OpenGL gl)
{
gl.Translate(-1.0f, 0.0f, -1.0f); // Move into the screen
gl.Begin(OpenGL.GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
gl.Color(0.0f, 1.0f, 0.0f); // Green
gl.Vertex(1.0f, 1.0f, -1.0f);
gl.Vertex(-1.0f, 1.0f, -1.0f);
gl.Vertex(-1.0f, 1.0f, 1.0f);
gl.Vertex(1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
gl.Color(1.0f, 0.5f, 0.0f); // Orange
gl.Vertex(1.0f, -1.0f, 1.0f);
gl.Vertex(-1.0f, -1.0f, 1.0f);
gl.Vertex(-1.0f, -1.0f, -1.0f);
gl.Vertex(1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
gl.Color(1.0f, 0.0f, 0.0f); // Red
gl.Vertex(1.0f, 1.0f, 1.0f);
gl.Vertex(-1.0f, 1.0f, 1.0f);
gl.Vertex(-1.0f, -1.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
gl.Color(1.0f, 1.0f, 0.0f); // Yellow
gl.Vertex(1.0f, -1.0f, -1.0f);
gl.Vertex(-1.0f, -1.0f, -1.0f);
gl.Vertex(-1.0f, 1.0f, -1.0f);
gl.Vertex(1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
gl.Color(0.0f, 0.0f, 1.0f); // Blue
gl.Vertex(-1.0f, 1.0f, 1.0f);
gl.Vertex(-1.0f, 1.0f, -1.0f);
gl.Vertex(-1.0f, -1.0f, -1.0f);
gl.Vertex(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
gl.Color(1.0f, 0.0f, 1.0f); // Magenta
gl.Vertex(1.0f, 1.0f, -1.0f);
gl.Vertex(1.0f, 1.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, 1.0f);
gl.Vertex(1.0f, -1.0f, -1.0f);
gl.End(); // End of drawing color-cube
gl.Flush();
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
public static void Reshape(OpenGL gl, int width, int height)
{ // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
float aspect = (float)width / (float)height;
// Set the viewport to cover the new window
gl.Viewport(0, 0, width, height);
// Set the aspect ratio of the clipping volume to match the viewport
gl.MatrixMode(OpenGL.GL_PROJECTION); // To operate on the Projection matrix
gl.LoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gl.Perspective(4.0f, aspect, 0.1f, 10.0f);
}
}
WinForms code:
public partial class SharpGLForm : Form
{
private float rotation = 0.0f;
public SharpGLForm()
{
InitializeComponent();
}
private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
OpenGLhelper.Display(gl);
rotation = 3.0f;
}
private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
OpenGLhelper.Init(gl);
}
private void openGLControl_Resized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
OpenGLhelper.Reshape(gl, Width, Height);
}
}
CodePudding user response:
Matrix multiplications are not Commutative. The order maters. gl.Rotate()
and gl.Translate()
do not set a rotation and translation. This functions define a matrix and multiply the current matrix with the new matrix. If you want to rotate the model around a local axis, you need to call gl.Translate()
before gl.Rotate()
:
public partial class SharpGLForm : Form
{
// [...]
private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.MatrixMode(OpenGL.GL_MODELVIEW);
gl.LoadIdentity();
gl.Translate(-1.0f, 0.0f, -1.0f); // <-- INSERT
gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
OpenGLhelper.Display(gl);
rotation = 3.0f;
}
public static class OpenGLhelper
{
// [...]
public static void Display(OpenGL gl)
{
// DELETE
// gl.Translate(-1.0f, 0.0f, -1.0f); // Move into the screen