Saturday, June 23, 2012

OpenGL Camera Class Tutorial Part 5: Getting a Picking Ray

Introduction

This tutorial is really short. I am not going to describe generally how to get a picking ray, but a good reference can be found here. I will show how the FreeCamera class can easily implement a GetPickRay method

The GetPickRay Method

This method takes in normalized x and y coordinates of a mouse click on the screen. Normalized means that the center of the screen is (0, 0), the upper right corner is (1, 1) and the lower left is (-1,-1). The return value is a Ray, which has two vector components, an initial position and a normalized vector direction. Basically, this method finds the position on the near plane the mouse clicked and makes a vector from there straight into the screen (if it were drawn, it would look like a point). Here is the implementation:
public Ray GetPickRay(float x, float y)
{
  Vector3 vector = ( ( N * -1 ) * m_near) + (U * m_right * x) + (V * m_top * y);
  Vector3 pos = vector + Position;
  vector.Normalize();
  return new Ray(pos, vector);
}

Conclusion

The pick ray is extremely useful for "selecting" elements in an OpenGL scene with the mouse. The only thing to do is test whether the picking ray collides (extended) or intersects with an element. Abstracting an OpenGL camera into the FreeCamera class has made it extremely intuitive for me to render and interact with the scene. Writing these tutorials has given me a much better understanding of OpenGL and how it works. If there are misleading statements in any of these tutorials, please, kindly leave a comment. I would like to fix any errors and learn from those mistakes!

Friday, June 22, 2012

OpenGL Camera Class Tutorial Part 4: Projection and Modelview Matrices

Introduction

This tutorial will be fairly short, but it is what makes the FreeCamera class work. A lot of the variables I defined in the previous tutorials will be used here to set the OpenGL modelview and projection matrices.

The Projection Matrix

The first method, LoadProjectionMatrix, sets the projection matrix and defines the view volume in OpenGL as the FreeCamera class represents it. It is very simple. It has no arguments and no return value. It simply sets the matrix mode to the projection matrix, loads the identity matrix, and calls the GLFrustum function which multiplies the matrix by another that represents the frustum view volume. I set the matrix mode and load the identity for convenience here, but, if I wanted more control, I could remove the GLMatrixMode and GLLoadIdentity commands. Here is the implementation:
public void LoadProjectionMatrix()
{
  GL.MatrixMode(MatrixMode.Projection);
  GL.LoadIdentity();
  GL.Frustum(m_left, m_right, m_bottom, m_top, m_near, m_far);
}

The Modelview Matrix

The second method, LoadModelviewMatrix, sets the modelview matrix and defines how objects are rendered relative to the camera in OpenGL. For more information about how this works, look at this link about the modelview matrix (I've formatted the code below to look similar to a matrix definition. Because I enter the values in the matrix constructor serially from 1-16, the rows and columns are switched and it looks mirrored down the diagonal compared to the modelview matrix link). The method is also very simple. I define a modelview matrix based on the U, V, and N vectors, set the matrix mode to the modelview matrix, and I load the matrix. Once again, I could remove the command to set the matrix mode if I wanted more control, but I like setting it in this method for convenience. Here is the implementation:
public void LoadModelviewMatrix()
{
Matrix4 m;
  m = new Matrix4(
    U.X, V.X, N.X, 0.0f,
    U.Y, V.Y, N.Y, 0.0f,
    U.Z, V.Z, N.Z, 0.0f,
    -Vector3.Dot(Position, U), -Vector3.Dot(Position, V), -Vector3.Dot(Position, N), 1.0f);
  GL.MatrixMode(MatrixMode.Modelview);
  GL.LoadMatrix(ref m);
}

FreeCamera Example Usage

What's better than having a FreeCamera class? Using it! I have a C# Windows Forms application that I'm working on with OpenTK. I use a series of event handlers to control the OpenGL scene. Here are the event handlers:
Form Load: First, I've declared a FreeCamera instance to be used for all of these methods. This method initializes the OpenGL and camera states. I set some temporary values for things I don't know, but in the SetViewVolume I know I want the near plane distance to be 0.1 and the far plane to be 100 with a perspective of 30 degrees. I also initialize the position to be near, but off of the origin and have it look at the origin.
private FreeCamera freeCamera = new FreeCamera();

private void Form_Load(object sender, EventArgs e)
{
  freeCamera.SetViewVolume(new System.Drawing.Size(800, 600), 0.1f, 100.0f, 30.0f);
  freeCamera.Position = new Vector3(0.5f, 1, 1);
  freeCamera.LookAt(new Vector3(0, 0, 0), new Vector3(0, 1, 0));
}
Application Idle: This method renders the scene. I just clear the color and depth buffers, load the modelview matrix from the FreeCamera, then swap the buffers.

void Application_Idle(object sender, EventArgs e)
{
  GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
  freeCamera.LoadModelViewMatrix();
  //Draw Scene


  //End Draw Scene
  glControl.SwapBuffers();
}
GLControl Resize: This method gets called when the OpenGL control gets resized. I want to reset the viewport when this happens and set the projection matrix due to changes in the size of the screen. It is pretty simple: I set the window size, load the viewport, and then load the projection matrix.
private void glControl_Resize(object sender, EventArgs e)
{
  freeCamera.SetWindowSize(new System.Drawing.Size(glControl.Width, glControl.Height));
  freeCamera.LoadViewport();
  freeCamera.LoadProjectionMatrix();
}
GLControl KeyDown: This is where it gets fun. I've added a handler for when a user presses keys. I have the standard W-A-S-D controls for looking around using the FreeCamera Pitch and Yaw methods, supplemented with Q and E for barrel-rolling using the FreeCamera Roll method.
private void glControl_KeyDown(object sender, KeyEventArgs e)
{
  switch (e.KeyCode)
  {
  case Keys.A:
    freeCamera.Yaw(-1.0f);
    break;
  case Keys.D:
    freeCamera.Yaw(1.0f);
    break;
  case Keys.S:
    freeCamera.Pitch(-1.0f);
    break;
  case Keys.W:
    freeCamera.Pitch(1.0f);
    break;
  case Keys.Q:
    freeCamera.Roll(1.0f);
    break;
  case Keys.E:
    freeCamera.Roll(-1.0f);
    break;
  }
}
GLControl PreviewKeyDown: I would have placed these in the previous method, but C# Windows Forms doesn't call KeyDown when special keys are called that can navigate on the forms, such as the arrow keys. I can still capture those keys with the PreviewKeyDown method, however. I've added moving forward and backward with the Up / Down arrow keys and moving left and right with the Left / Right arrow keys. All of this is accomplished with the FreeCamera.Slide method.
private void glControl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
  switch (e.KeyCode)
  {
  case Keys.Down:
    freeCamera.Slide(new Vector3(0, 0, 0.05f));
    break;
  case Keys.Up:
    freeCamera.Slide(new Vector3(0, 0, -0.05f));
    break;
  case Keys.Left:
    freeCamera.Slide(new Vector3(-0.05f, 0, 0));
    break;
  case Keys.Right:
    freeCamera.Slide(new Vector3(0.05f, 0, 0));
    break;
  }
}

Conclusion

The methods above provide all the interfaces I need to position and orient a camera in an OpenGL scene in almost any way imaginable. Using the FreeCamera that I've described and built in these tutorials has helped me get over many of the initial hurdles OpenGL throws at beginners (I include myself in that group). Hopefully these tutorials can help get others off the ground and running. I have one more tutorial, and that is an additional utility to the FreeCamera class: getting a pick ray. See the next tutorial: Part 5.

Thursday, June 21, 2012

OpenGL Camera Class Tutorial Part 3: View Volume and Viewport

Introduction

This tutorial covers setting the viewport and the view volume, or frustum. This can be considered as defining the perspective angle of the camera lens and the size of the screen to draw on.

Member Variables

The first thing I will do is define a bunch of member variables. These will maintain the state of viewport and view volume for the camera.
  1. Aspect: The aspect ratio of the display window (can be changed for stretching effects).
  2. Perspective: The vertical viewing angle, in degrees(not radians) that can be seen through the camera (can be changed for zooming effects).
  3. Near: The near plane distance away from the eye of the camera (must be greater than 0).
  4. Far: The far plane distance away from the eye of the camera (should be greater than the near distance).
  5. Top: The y coordinate the top of the near plane.
  6. Bottom: The y coordinate of the bottom of the near plane.
  7. Left: The x coordinate of the left of the near plane.
  8. Right: The x coordinate of the right of the near plane.
  9. Window Size: The size (in pixels) of the display window.
This is how I've defined them these value (with temporary defaults):
private float m_aspect = 320.0f / 240.0f;
private float m_perspective = 30.0f;
private float m_near = 1.0f;
private float m_far = 100.0f;
private float m_top = 1.0f;
private float m_bottom = -1.0f;
private float m_left = -1.0f;
private float m_right = 1.0f;
private Size m_windowSize = new Size(320,240);

View Volume

The easiest way to manipulate the viewing volume / viewing frustum is to define a SetViewVolume method. This method will take the window size, the near plane distance, the far plane distance, and perspective as parameters. These parameters will be broken down and stored into all of the variables defined above.

The first step is to save of the near and far plane values.

The top and bottom variables are derived from the perspective by taking the tangent of the perspective angle and multiplying it by the distance to the near plane.

The window size is stored and the aspect ratio is automatically extracted. Then the left and right variables are set based aspect ratio multiplied by the top and bottom variables.

Here is my implementation:
public void SetViewVolume(Size windowSize, float near, float far, float perspective)
{
  //Z-clipping
  m_near = near;
  m_far = far;

  //Top / bottom (based on perspective)
  m_perspective = perspective;
  m_top = (float)Math.Tan(perspective * Math.PI / 360.0f) * near;
  m_bottom = -m_top;

  //Left / right (based on aspect of windowSize)
  m_windowSize = windowSize;
  m_aspect = (float)windowSize.Width / (float)m_windowSize.Height;
  m_left = m_aspect * m_bottom;
  m_right = m_aspect * m_top;
}

Helper Methods

While the SetViewVolume method sets all of the camera's view volume variables, it is also nice to tweak just a few of them. Here are some helper functions and my uses for them:

  • SetPerspective: Sets the perspective. This is useful for zooming effects. Ever wonder how they make a sniper rifle zoom? This is one way.
  • SetClippingPlanes: Different types of scenes need very different clipping planes. An indoor scene might have a relatively close far plane while an outdoor scene might warrant a much further far plane.
  • SetWindowSize: For windowed applications especially, if the user resizes the window, this is a great way to scale to new window sizes.
Here are my implementations (they just re-use SetViewVolume):
public void SetPerspective(float angle)
{
  SetViewVolume(m_windowSize, m_near, m_far, angle);
}

public void SetClippingPlanes(float near, float far)
{
  SetViewVolume(m_windowSize, near, far, m_perspective);
}

public void SetWindowSize(Size windowSize)
{
  SetViewVolume(windowSize, m_near, m_far, m_perspective);
}

Viewport Loader

Up until now, everything I've written in these tutorials has been about representation of a camera in OpenGL. This next method is the first in a series of methods that actually allow me to use them in code. This simply calls the GLViewport function and should be used any time the screen size is changed or SetViewVolume is called (on application startup and before the first render, and any time the window is resized).
public void LoadViewport()
{
  GL.Viewport(new Point(0, 0), m_windowSize);
}

Conclusion

This tutorial completes all of the fields and variables that are needed to represent the FreeCamera. The only thing for me to do now is write some methods that allow me to use the camera in a scene by manipulating matrices. The next tutorial will focus on loading matrices and using the camera to help render a simple scene: Part 4.

Wednesday, June 20, 2012

OpenGL Camera Class Tutorial Part 2: Manipulating the Camera

Introduction

This tutorial covers sliding and arbitrarily rotating the camera relative to its local coordinate system.

Sliding the Camera

Sliding the camera is just moving the camera some distance from its current location. It would be easy to use a formula such as: Position = Position + SlidingVector. Unfortunately this only moves the camera in world coordinates. What I want to do is slidethe camera around using a vector relative to the camera's local coordinates. This can give the effect of strafing, moving forward and backward, moving up and down, or in a straight line in any direction from the camera's origin.

To slide relative to the camera's local coordinate system, I'll use the U, V, and N vectors defined in the previous tutorial.  The math is simple:
  1. Take in input vector, i, and current position, p.
  2. p.x = p.x(original) + i.x * u.x + i.y * v.x + i.z * n.x
  3. p.y = p.y(original) + i.x * u.y + i.y * v.y + i.z * n.y
  4. p.z = p.z(original) + i.x * u.z + i.y * v.z + i.z * n.z
This can be written as a slide method in the FreeCamera class:
public void Slide(Vector3 vector)
{
  Position += new Vector3(
    vector.X * U.X + vector.Y * V.X + vector.Z * N.X,
    vector.X * U.Y + vector.Y * V.Y + vector.Z * N.Y,
    vector.X * U.Z + vector.Y * V.Z + vector.Z * N.Z
    );
}

Rotating: Pitch, Yaw, and Roll

I'm not going to define Pitch, Yaw, and Roll, but here is a good, quick reference of flight dynamics. To accomplish rotating, the U, V, and N vectors will be transformed by an angle in degrees. I'm not going to describe the math for rotations, as it is out of the scope of this tutorial. Getting familiar with rotations will help in understanding the following methods.

Pitch is rotating around the local X-axis (or U-vector). This means that U will not be transformed, but the V and N vectors will be rotated around U. It is really just a bit of trigonometry; here is the method:
public void Pitch(float angle)
{
  float cosVal = (float)Math.Cos(MathHelper.DegreesToRadians(angle));
  float sinVal = (float)Math.Sin(MathHelper.DegreesToRadians(angle));

  Vector3 tempN = new Vector3(N);
  N = new Vector3(
    cosVal * tempN.X + sinVal * V.X,
    cosVal * tempN.Y + sinVal * V.Y,
    cosVal * tempN.Z + sinVal * V.Z
    );
  V = new Vector3(
    cosVal * V.X - sinVal * tempN.X,
    cosVal * V.Y - sinVal * tempN.Y,
    cosVal * V.Z - sinVal * tempN.Z
    );
}
Yaw is rotating around the local Y-axis (or V-vector). This means that V will not be transformed, but the U and N vectors will be rotated around V. The method is similar to Pitch:
public void Yaw(float angle)
{
  float cosVal = (float)Math.Cos(MathHelper.DegreesToRadians(angle));
  float sinVal = (float)Math.Sin(MathHelper.DegreesToRadians(angle));

  Vector3 tempU = new Vector3(U);
  U = new Vector3(
    cosVal * tempU.X + sinVal * N.X,
    cosVal * tempU.Y + sinVal * N.Y,
    cosVal * tempU.Z + sinVal * N.Z
    );
  N = new Vector3(
    cosVal * N.X - sinVal * tempU.X,
    cosVal * N.Y - sinVal * tempU.Y,
    cosVal * N.Z - sinVal * tempU.Z
    );
}
Roll is rotating around the local Z-axis (or N-vector). This means that N will not be transformed, but the V and U vectors will be rotated around N. The method is similar to Pitch and Yaw:
public void Roll(float angle)
{
  float cosVal = (float)Math.Cos(MathHelper.DegreesToRadians(angle));
  float sinVal = (float)Math.Sin(MathHelper.DegreesToRadians(angle));

  Vector3 tempV = new Vector3(V);
  V = new Vector3(
    cosVal * tempV.X + sinVal * U.X,
    cosVal * tempV.Y + sinVal * U.Y,
    cosVal * tempV.Z + sinVal * U.Z
    );
  U = new Vector3(
    cosVal * U.X - sinVal * tempV.X,
    cosVal * U.Y - sinVal * tempV.Y,
    cosVal * U.Z - sinVal * tempV.Z
    );
}

Rotating: An Arbitrary Axis

Rotating the camera about an arbitrary axis is not a simple task. I'm not going to go into detail about how this method works (I haven't even found a good use for it other than saying, "Hey, check this out. This is cool!"). This method transforms the U, V, and N, vectors by an arbitrary axis defined as a vector (think of it as a ray from the camera's local origin).
public void Rotate(Vector3 axis, float angle)
{
  float cosVal = (float)Math.Cos(MathHelper.DegreesToRadians(angle));
  float sinVal = (float)Math.Sin(MathHelper.DegreesToRadians(angle));

  float a = 1 + (1 - cosVal) * (axis.X * axis.X - 1);
  float b = (1 - cosVal) * axis.X * axis.Y - axis.Z * sinVal;
  float c = (1 - cosVal) * axis.X * axis.Z + axis.Y * sinVal;
  float e = (1 - cosVal) * axis.X * axis.Y + axis.Z * sinVal;
  float f = 1 + (1 - cosVal) * (axis.Y * axis.Y - 1);
  float g = (1 - cosVal) * axis.Y * axis.Z - axis.X * sinVal;
  float i = (1 - cosVal) * axis.X * axis.Z - axis.Y * sinVal;
  float j = (1 - cosVal) * axis.Y * axis.Z + axis.X * sinVal;
  float k = 1 + (1 - cosVal) * (axis.Z * axis.Z - 1);

  Vector3 tu = new Vector3(U);
  Vector3 tv = new Vector3(V);
  Vector3 tn = new Vector3(N);

  U = new Vector3(
    tu.X * a + tv.X * b + tn.X * c,
    tu.Y * a + tv.Y * b + tn.Y * c,
    tu.Z * a + tv.Z * b + tn.Z * c
    );
  V = new Vector3(
    tu.X * e + tv.X * f + tn.X * g,
    tu.Y * e + tv.Y * f + tn.Y * g,
    tu.Z * e + tv.Z * f + tn.Z * g
    );
  N = new Vector3(
    tu.X * i + tv.X * j + tn.X * k,
    tu.Y * i + tv.Y * j + tn.Y * k,
    tu.Z * i + tv.Z * j + tn.Z * k
    );
}

Conclusion

With these methods, an instance of the FreeCamera can now describe a camera's position and orientation, and manipulate the position and orientation in a pretty intuitive way. Keep in mind that every operation performed on the camera (slide, pitch, yaw, roll, rotate) is done from the perspective of the camera. Sliding the camera to the right slides the camera to the right of the camera . In the next tutorial I'll cover how to model the viewport and view volume: Part 3.

Monday, May 28, 2012

OpenGL Camera Class Tutorial Part 1: An Object Model

Introduction

I've taken classes, searched the internet, and never found exactly what I wanted in an OpenGL Camera class / tutorial. So here it goes: yet another camera class tutorial.

I've used a camera class in all of my OpenGL projects. It has been extremely useful and has provided shortcuts to a lot of other necessary components of a graphic system. My camera class has evolved from its beginnings as a homework assignment, to the point that it provides many miscellaneous features. It honestly is just a hodge-podge of useful features, and never had a specific purpose or structure. So, I've decided to re-write it, and document the process.

Goals

There are three goals of this tutorial:
  1. A tutorial for myself. Computer graphics is not my day job, but I love to tinker around with OpenGL and have a bunch of half-finished projects. With that in mind, I would love to more fully understand the concepts so my time tinkering isn't just time debugging and being confused.
  2. A tutorial for others. If I can get through this, maybe I can show others so they don't have to make the same mistakes as I.
  3. Show code that works. I don't want to show only a portion of the code, or pseudo code. I want to show code that can be easily used and compiled. I will not provide source files, but all the code will be shown in the tutorials. One merely must copy and paste the code into a syntactically correct C# class.

Camera Features

The following features are what I want in my camera, with each visited by its own tutorial:
  1. An object model representation of the position and orientation of my camera (this tutorial).
  2. The ability to slide and rotate my object model relative to its local coordinate system.
  3. An object model representation of the OpenGL viewport / frustum.
  4. The ability to use the object model to configure the model-view and projection matrices.
  5. Acquire a picking ray from the camera.

Development Environment

  • I am using Visual C# 2010 as my development environment. This should not prevent anyone from using this class in Java or C++. As a matter of fact, I have a version written in Java for Android's implementation of OpenGL ES, and a version in C++.
  • How do I use OpenGL in C#? A very nifty library I found called OpenTK. Besides providing an interface to OpenGL, it also provides matrices, vectors, and other helpful 3D constructs and math utilities.

The FreeCamera Class

The class is named FreeCamera because of its ability to model an arbitrary orientation and position in 3-D space (not because it is free as in freedom nor because it is free as in no cost; though, it does comply with these definitions as well). Many camera classes only allow orientation defined as an azimuth / elevation (strict pitch / yaw), or only rotation on one or two axis -- to me, that is defined as an AxisRestrictedCamera. Not only will this class allow pitch, yaw and roll of the camera, it will also allow rotation of the camera on an arbitrarily defined axis. To do this, meet the beginning code for the camera:
public class FreeCamera
{
  public Vector3 U;
  public Vector3 V;
  public Vector3 N;
  public Vector3 Position;
}
The class contains 3 public structure instances: U,V,N, and Position. The Position field provides the camera's position. U,V, and N, on the other hand, need some explaining. Each axis provides a vector in the positive direction of each of the camera's local axis. Now, this is where I got lost when I was learning this the first time. So, I want to explain this a bit more.

Consider a representation of 3-D space:
World Coordinate System.
I have an X-axis, Y-axis, Z-axis and an origin marked with a big black dot. I can simply find or define positions anywhere in this space knowing the X, Y, and Z components of a point. For my camera, this is the space that the camera lives in (and anything the camera looks at) -- the world coordinate system.

Now I'll define a camera's position with a big orange dot and define its orientation. A simple way to define a camera's orientation is to give it something to look at and tell it which way is up. So, I'll define a camera with a position, a "look," and an "up." The camera's position will be at about (1.5,0,1.5) in world coordinates, will look at the world coordinate system origin (0,0,0), and the camera will point up in the direction of the world coordinate system Y-axis(0,1,0):
World Coordinate System with Camera.
I have the camera defined in the world. What I want to do, though, is just look at the camera itself:
Camera, alone.
The camera can be described by its position (orange dot), a specific position it is looking at (black dot), and the direction known to be "up" for the camera (magenta vector arrow). The next trick is to find a way to represent the camera's local coordinate system. Why is this important? I already have a position, know what I'm looking at, and could easily move it toward that point, at an angle, etc., using fundamental math operations. But, I can think of two reasons why I want a local coordinate system, instead:
  1. Convenience. If I want to move forward, great, I'll know exactly which way is forward (or any other direction). If I want pitch, yaw, or roll, then I will know exactly how to rotate and model my new position. The previous two statements have been from a camera perspective, not from the world coordinate perspective -- I wouldn't say, "I'm going to move 8 units from the center of my house toward the front door and 6 units to the east wall," just to describe my intent to walk forward 1 step.
  2. OpenGL doesn't really use a position / look / up model of a camera. It does have a utility function, glLookAt, that takes these parameters, but I won't be using that here. Eventually, what I'll do is use the U,V,N representation of the camera's local system to set the model-view matrix of OpenGL.
So, I'll redefine the camera's model with a local U,V,N system (analogous to X,Y,Z). Imagine a line coming straight out of the screen, behind the camera; this is the positive N-axis. So, the Camera will always be pointing down the negative N-axis. Looking to the right of the camera will be the positive U-axis, and looking up will be the positive V-axis:
Camera with U,V,N.

Why is the U,V,N system defined this way? It follows the right-hand rule and, using this model, it is easy to populate the modelview matrix. When put together, the world coordinate system contains the camera which has its own personal coordinate system relative to its orientation. Here is a final diagram of the 3-D world and the camera:

World Coordinate System with Camera and U,V,N system.
How do I calculate the U,V, and N axis? It is actually quite simple with the look / up vectors. The N-axis vector is behind the camera, so subtracting the look from the position will give the positive N-axis vector. U is the cross product of the up vector and N (again, see the right-hand rule). V could be the same as the up vector, but the up vector isn't guaranteed to be orthogonal to the look direction. Telling the camera which way is "up" is really more like a hint of what the orientation is. So, V is calculated as the cross product of N and U. This is the first method I'll add to the FreeCamera class:
public void LookAt(Vector3 look, Vector3 up)
{
  N = Position - look;
  N.Normalize();

  U = Vector3.Cross(up, N);
  U.Normalize();

  V = Vector3.Cross(N, U);
  V.Normalize();
}
I'll also add some constructors to the FreeCamera class to finish up this tutorial:
public FreeCamera()
{
  Position = new Vector3(0, 0, 0);
  LookAt(
    new Vector3(0, 0, -1),
    new Vector3(0, 1, 0));
}

public FreeCamera(Vector3 position)
{
  Position = position;
  LookAt(
    position + new Vector3(0, 0, -1),
    new Vector3(0, 1, 0));
}

Conclusion

This isn't a tutorial about OpenGL, C#, OpenTK, linear algebra, or mathematical concepts. I don't attempt to optimize any methods or operations. This tutorial is about creating a camera class to use in OpenGL. If hints of any other topic than a camera class are provided, that is only as a bonus. It is an assignment for the reader to learn any other concepts needed to utilize this tutorial. In the next tutorial, I'll cover sliding and rotating the camera: Part 2.

Friday, February 4, 2011

Update -- End Of January 2011

I've accomplished some milestones this year.  A test application is available on the android market with a quick search for "Ascent" or using the application code shown below.

What started out as an accelerometer-controlled nightmare has turned into a much easier-to-use on-screen interface.  Even this needs a lot of tweaking, but the results are much, much better.  Currently, the application allows a user to navigate through a cave-type level, with some minimal collision detection that throws a user back to the middle of the room they were in.  Certain areas of a level have difficulty rendering at decent frame-rates due to the un-optimized nature of the game, so far.

Please see some of the current screenshots and temporary graphic art below, or visit the current application webpage on the market: Ascent.

Logo

Screenshot - 1

Screenshot - 2




Friday, July 30, 2010

Searching for Answers

I've made great strides in learning the architecture of the Android platform, and the applications that it runs.  Even so, creating a game for Android is much less documented.  I thought I'd post some links of other blogs and tutorials that have led me thus far.  Despite being inspired by their ideas, designs, and code, I maintain that I have only created my own, unique code and architecture.  The following proved very useful:

Insanity Design for Android ports of OpenGL to OpenGL ES: http://insanitydesign.com/wp/projects/nehe-android-ports/

Nehe for OpenGL tutorials: http://nehe.gamedev.net/

Jayway.com for fullscreen info: http://blog.jayway.com/2009/12/03/opengl-es-tutorial-for-android-part-i/

Androgames blog for accelerometer sensor management: http://blog.androgames.net/85/android-accelerometer-tutorial/

Robert Green for details on 3-D android engine building: http://www.rbgrn.net/content/54-getting-started-android-game-development

Enfis for alternate OpenGL implementation: http://www.enfis.it/archives/14

I have read many sources indicating that the best way to develop a 3D game includes using multiple sets of threads, writing native code (in C), or using some other game engine (re-inventing the wheel is always frowned upon.  I usually respond that the wheel doesn't fit my car, the wheel is square, or that Firestone tires needed some reinventing).  My goal for this game (3D at that) is to build an efficient, simple, fully 3D game built using only the Android and OpenGL ES APIs supported by Android.