Camera and model frame issues

Started by
1 comment, last by Lex224 11 years, 12 months ago
Hi all.

So I'm trying to load in an md2 model to use as the controllable character. I have loaded it in just fine, but I'm facing issues when trying to move the model along with the camera.

I'm using the SuperBible (5th edition) for my OpenGL, and this project is based on one of the examples.

The project isn't OO, so all the code is jammed into one main file, so you can see the code HERE.

I've tried to set both the camera and the model's origin, but then neither of them move for some reason. If I set the camera origin, and not the model's origin, the model is able to move, and visa versa.

Setting neither of their origins works but then ofc, I can't see the model as they're both at (0, 0, 0).

What am I doing wrong here?

Also, how can I change the controls so that the model moves along with the camera? The way I have it at the moment, the model rotates with 'a' and 'd' and doesn't move to the left of right. Do I need to move the camera behind the model around the model's axis? How do I do this?

There's a lot here, I understand, but I can't seem to find out how to solve this!

Many, many thanks for any help!
Advertisement
OK, I've stripped the project down to just some simple geometry. I now have a floor and a cylinder object which should be controllable. Again, when I set the cylinder's origin, it's unable to move, yet when I comment out it's origin, it can move. I need to set it's origin in front of the camera so that I can see it, so this is a problem.

Here is the stripped down code:


// Based on SphereWorld4
#include <GLTools.h>
#include <GLShaderManager.h>
#include <GLFrustum.h>
#include <GLBatch.h>
#include <GLFrame.h>
#include <GLMatrixStack.h>
#include <GLGeometryTransform.h>
#include <StopWatch.h>
#include <math.h>
#include <stdio.h>
//#ifdef __APPLE__
//#include <glut/glut.h>
//#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
//#endif
#define NUM_SPHERES 50
GLFrame spheres[NUM_SPHERES];

GLShaderManager shaderManager; // Shader Manager
GLMatrixStack modelViewMatrix; // Modelview Matrix
GLMatrixStack projectionMatrix; // Projection Matrix
GLFrustum viewFrustum; // View Frustum
GLGeometryTransform transformPipeline; // Geometry Transform Pipeline
GLBatch floorBatch;
GLFrame cameraFrame;
GLTriangleBatch cylinderBatch;
GLFrame cylinderFrame;

//////////////////////////////////////////////////////////////////
// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Initialze Shader Manager
shaderManager.InitializeStockShaders();

glEnable(GL_DEPTH_TEST);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

// This makes a cylinder
gltMakeCylinder(cylinderBatch, 0.1f, 0.0f, 0.4f, 24, 6);
// Floor
floorBatch.Begin(GL_LINES, 324);
for(GLfloat x = -20.0; x <= 20.0f; x+= 0.5)
{
floorBatch.Vertex3f(x, -0.55f, 20.0f);
floorBatch.Vertex3f(x, -0.55f, -20.0f);

floorBatch.Vertex3f(20.0f, -0.55f, x);
floorBatch.Vertex3f(-20.0f, -0.55f, x);
}
floorBatch.End();
}
///////////////////////////////////////////////////
// Screen changes size or is initialized
void ChangeSize(int nWidth, int nHeight)
{
glViewport(0, 0, nWidth, nHeight);

// Create the projection matrix, and load it on the projection matrix stack
viewFrustum.SetPerspective(35.0f, float(nWidth)/float(nHeight), 1.0f, 100.0f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());

// Set the transformation pipeline to use the two matrix stacks
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}

// Called to draw scene
void RenderScene(void)
{
// Color values
static GLfloat vFloorColor[] = { 0.0f, 1.0f, 0.0f, 1.0f};
static GLfloat vCylColor[] = { 0.2f, 1.0f, 1.0f, 1.0f };

// Clear the color and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Save the current modelview matrix (the identity matrix)
modelViewMatrix.PushMatrix();

M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.PushMatrix(mCamera);
// Transform the light position into eye coordinates
M3DVector4f vLightPos = { 0.0f, 10.0f, 5.0f, 1.0f };
M3DVector4f vLightEyePos;
m3dTransformVector4(vLightEyePos, vLightPos, mCamera);
// Draw the ground
shaderManager.UseStockShader(GLT_SHADER_FLAT,
transformPipeline.GetModelViewProjectionMatrix(),
vFloorColor);
floorBatch.Draw();
// Draw cylinder
modelViewMatrix.PushMatrix();
modelViewMatrix.MultMatrix(cylinderFrame);
shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(),
transformPipeline.GetProjectionMatrix(), vLightEyePos, vCylColor);
cylinderFrame.SetOrigin(0.0f, 0.0f, -2.0f);
cylinderFrame.SetForwardVector(0.0f, 0.0f, 1.0f);
cylinderBatch.Draw();
modelViewMatrix.PopMatrix();

// Restore the previous modleview matrix (the identity matrix)
modelViewMatrix.PopMatrix();
modelViewMatrix.PopMatrix();
// Do the buffer Swap
glutSwapBuffers();

// Tell GLUT to do it again
glutPostRedisplay();
}

// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
{
float linear = 0.1f;
float angular = float(m3dDegToRad(5.0f));

if(key == GLUT_KEY_UP)
cameraFrame.MoveForward(linear);

if(key == GLUT_KEY_DOWN)
cameraFrame.MoveForward(-linear);

if(key == GLUT_KEY_LEFT)
cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);

if(key == GLUT_KEY_RIGHT)
cameraFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);
}
void Keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case('w'):
{
cylinderFrame.MoveForward(0.1f);
break;
}
case('s'):
{
cylinderFrame.MoveForward(-0.1f);
break;
}
case('a'):
{
cylinderFrame.RotateLocalY(30.0f);
break;
}
case('d'):
{
cylinderFrame.RotateLocalY(-30.0f);
break;
}
}
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800,600);

glutCreateWindow("OpenGL SphereWorld");

glutSpecialFunc(SpecialKeys);
glutKeyboardFunc(Keyboard);
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);

GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}

SetupRC();
glutMainLoop();
return 0;
}


Is there a way to set it's origin and for it to move around? When I do set the origin and try to move it, it stays in place but flickers, showing that it is trying to move.
OK, disregard this.

I doubt anybody else will have this same issue, but if they do, all I did was change where I put the SetOrigin from inside the RenderScene function, to the SetupRC function. Silly me.

This topic is closed to new replies.

Advertisement