homemade engine issues

hi! this is my first time visiting these forums and i thought i might be able to get some help with an issue i’m facing in my 3d engine/thing. :slight_smile:

the issue i’m facing is that objects seem to be vibrating when they are moving. in the engine i have a mouse controlled camera with keyboard controlled movement (like a normal fps setup). so when i’m strafing and looking at an object (so that it stays centered on the screen) it appears to be vibrating very quickly. there is also an issue with the keyboard input being a little delayed (but i have learned how to fix that from a post over at gamedev.net’s forums).

i have spent many hours trying to figure out what i’m doing wrong and also searching the internet for examples of how to do it right. unfortunately i haven’t really found anything that i can point to that is the issue, but i’m fairly new at this and figure some more experienced users could be able to help me.

i generally don’t like posting code out there and saying “fix this”, but i have reached a point where i really have no clue what to do. i posted it at gamedev.net after a couple of days working it and seeing if anyone had had the same problem. unfortunately no one said they had so i posted the code hopeing that someone would be kind enough to compile it, run it, and help me figure out the issue. i’m not asking for someone to solve my problem, but any help would be most appreciated. thanks!

//  6/7/06
//  Andrew
//  OpenGL 3d engine using glut

#include <GL/glut.h>
#include <cmath>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;

// window global variables
int WINDOW_WIDTH = 800;
int WINDOW_HEIGHT = 600;
int windowids[1];  // can be used to store multiple window ids in case there are multiple windows
char title[13] = "test engine";

// call back functions to be used
void initializecallbacks();
void displaycallback();
void keyboardcallback(unsigned char key, int x, int y);
void passivemotioncallback(int x, int y);
void reshapecallback(int w, int h);
void timercallback(int time);

// setup visual requirments
void initializevisuals();

// variables used for movement
const float piover180 = 0.0174532925f;  // pi / 180, for degree to radian transform
float heading; // direction character is facing
float xpos; // x-axis position of the player
float zpos; // z-axis position of the player
float ypos = 0.5; // y-axis position of the player
GLfloat	yrot; // y-axis rotation
GLfloat lookupdown = 0.0f; // value to look up or down
GLfloat	z=0.0f;				// Depth Into The Screen
int mousebasex = WINDOW_WIDTH/2;
int mousebasey = WINDOW_HEIGHT/2;

int main(int argc, char* argv[])
{
  glutInit(&argc, argv);
  initializevisuals();
  initializecallbacks();
  
  glutMainLoop();
  
  return 0;
}

//----------------------------------------------------------------------------//
//                              call back section                             //
//----------------------------------------------------------------------------//
void initializecallbacks()
{
  // setting up the call back functions
  glutDisplayFunc(displaycallback);  // display call back
  glutKeyboardFunc(keyboardcallback);  //  keyboard call back
  glutPassiveMotionFunc(passivemotioncallback);  // passive mouse motion call back
  glutReshapeFunc(reshapecallback); // screen reshape call back
  glutTimerFunc(15, timercallback, 0);  // timer call back
}

void keyboardcallback(unsigned char key, int x, int y)
{
  switch (key)
  {
    // miscellaneous input
    case 27: // 'esc'
      exit(0); // end the program
      break;
    
    // movement input
    case 'a':
      xpos -= (float)sin(heading*piover180 + 90.0f*piover180) * 0.05f;
      zpos -= (float)cos(heading*piover180 + 90.0f*piover180) * 0.05f;
			break;
		case 'd':
      xpos += (float)sin(heading*piover180 + 90.0f*piover180) * 0.05f;
      zpos += (float)cos(heading*piover180 + 90.0f*piover180) * 0.05f;
      break;
    case 'w':
      xpos -= (float)sin(heading*piover180) * 0.05f;
			zpos -= (float)cos(heading*piover180) * 0.05f;
			break;
		case 's':
      xpos += (float)sin(heading*piover180) * 0.05f;
      zpos += (float)cos(heading*piover180) * 0.05f;
  }
  
  int dims[4];
  glGetIntegerv(GL_VIEWPORT, dims);
  
  int dx = x - mousebasex;
  int dy = y - mousebasey;
  mousebasex = x;
  mousebasey = y;
  
//  if (x < 20)
//  {
//    glutWarpPointer(dims[2]/2, y);
//    mousebasex = dims[2]/2;
//  }
//  if (x > (dims[2]/2 - 20))
//  {
//    glutWarpPointer(dims[2]/2, y);
//    mousebasex = dims[2]/2;
//  }
  
  lookupdown += dy * 0.5f;
  heading -= dx * 0.5f;
  if(heading < 0.0f)
    heading = heading + 360.0f;
  else if(heading > 360.0f)
    heading = heading - 360.0f;
  yrot = heading;
}

void passivemotioncallback(int x, int y)
{
  int dims[4];
  glGetIntegerv(GL_VIEWPORT, dims);
  
  int dx = x - mousebasex;
  int dy = y - mousebasey;
  mousebasex = x;
  mousebasey = y;
  
  if (x < 20)
  {
    glutWarpPointer(dims[2]/2, y);
    mousebasex = dims[2]/2;
  }
  if (x > (dims[2] - 20))
  {
    glutWarpPointer(dims[2]/2, y);
    mousebasex = dims[2]/2;
  }
  
  lookupdown += dy * 0.5f;
  heading -= dx * 0.5f;
  if(heading < 0.0f)
    heading = heading + 360.0f;
  else if (heading > 360.0f)
    heading = heading - 360.0f;
  yrot = heading;
}

void reshapecallback(int w, int h)
{
  glViewport(0, 0, w, h);
 
 	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
	glLoadIdentity();									// Reset The Modelview Matrix
}

void timercallback(int time)
{
  glutPostRedisplay();
  glutTimerFunc(10, timercallback, 0);
}

void displaycallback()
{
  int dims[4];
  glGetIntegerv(GL_VIEWPORT, dims);
  
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();									// Reset The View

	GLfloat xtrans = -xpos;
	GLfloat ztrans = -zpos;
	GLfloat ytrans = 0; // -walkbias-0.25f;
	GLfloat sceneroty = 360.0f - yrot;
	
  glRotatef(lookupdown,1.0f,0,0);
	glRotatef(sceneroty,0,1.0f,0);
	glTranslatef(xtrans, ytrans, ztrans);
	
	glBegin(GL_QUADS);
		glColor3f(0.0f,1.0f,0.0f);			// Set The Color To Green
		glVertex3f( 0.5f, 0.5f,-0.5f);			// Top Right Of The Quad (Top)
		glVertex3f(-0.5f, 0.5f,-0.5f);			// Top Left Of The Quad (Top)
		glVertex3f(-0.5f, 0.5f, 0.5f);			// Bottom Left Of The Quad (Top)
		glVertex3f( 0.5f, 0.5f, 0.5f);			// Bottom Right Of The Quad (Top)
		
		glColor3f(1.0f,0.5f,0.0f);			// Set The Color To Orange
		glVertex3f( 0.5f,-0.5f, 0.5f);			// Top Right Of The Quad (Bottom)
		glVertex3f(-0.5f,-0.5f, 0.5f);			// Top Left Of The Quad (Bottom)
		glVertex3f(-0.5f,-0.5f,-0.5f);			// Bottom Left Of The Quad (Bottom)
		glVertex3f( 0.5f,-0.5f,-0.5f);			// Bottom Right Of The Quad (Bottom)
		
		glColor3f(1.0f,0.0f,0.0f);			// Set The Color To Red
		glVertex3f( 0.5f, 0.5f, 0.5f);			// Top Right Of The Quad (Front)
		glVertex3f(-0.5f, 0.5f, 0.5f);			// Top Left Of The Quad (Front)
		glVertex3f(-0.5f,-0.5f, 0.5f);			// Bottom Left Of The Quad (Front)
		glVertex3f( 0.5f,-0.5f, 0.5f);			// Bottom Right Of The Quad (Front)
		
		glColor3f(1.0f,1.0f,0.0f);			// Set The Color To Yellow
		glVertex3f( 0.5f,-0.5f,-0.5f);			// Bottom Left Of The Quad (Back)
		glVertex3f(-0.5f,-0.5f,-0.5f);			// Bottom Right Of The Quad (Back)
		glVertex3f(-0.5f, 0.5f,-0.5f);			// Top Right Of The Quad (Back)
		glVertex3f( 0.5f, 0.5f,-0.5f);			// Top Left Of The Quad (Back)
		
		glColor3f(0.0f,0.0f,1.0f);			// Set The Color To Blue
		glVertex3f(-0.5f, 0.5f, 0.5f);			// Top Right Of The Quad (Left)
		glVertex3f(-0.5f, 0.5f,-0.5f);			// Top Left Of The Quad (Left)
		glVertex3f(-0.5f,-0.5f,-0.5f);			// Bottom Left Of The Quad (Left)
		glVertex3f(-0.5f,-0.5f, 0.5f);			// Bottom Right Of The Quad (Left)
		
		glColor3f(1.0f,0.0f,1.0f);			// Set The Color To Violet
		glVertex3f( 0.5f, 0.5f,-0.5f);			// Top Right Of The Quad (Right)
		glVertex3f( 0.5f, 0.5f, 0.5f);			// Top Left Of The Quad (Right)
		glVertex3f( 0.5f,-0.5f, 0.5f);			// Bottom Left Of The Quad (Right)
		glVertex3f( 0.5f,-0.5f,-0.5f);			// Bottom Right Of The Quad (Right)
	glEnd();						// Done Drawing The Quad
	
	glFlush();
	glutSwapBuffers();
}


void initializevisuals()
{
  // creating the window and drawing buffers  
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); // create double buffer and z-depth buffer
  glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); // create window using predetermined window sizes
  glutInitWindowPosition(0,0);
  windowids[0]=glutCreateWindow(title);
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // set background color to white
	glClearDepth(1.0); // enables clearing of the depth buffer
  glEnable(GL_DEPTH_TEST); // enable depth testing
	glDepthFunc(GL_LESS);	// the type of depth test to do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// really nice perspective calculations, got from NeHe tutorial 10

  int dims[4];
  glGetIntegerv(GL_VIEWPORT, dims);

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)dims[2]/(GLfloat)dims[3],0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
	glLoadIdentity();									// Reset The Modelview Matrix
}

again, sorry to just dump the code, but i’m not sure my explanation is ever good enough to describe what is really happening. so i figure seeing it for yourself is the best. in dev-c++ (which i’m using) the linker uses:

-lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32

thanks ahead of time for any help!

okay, double post i know, but this is pretty cool – i got the problem fixed! it ends up that both the issues with the engine were connected (i’m figuring this is probably more common than i realize). i knew that there was a key delay because glut will either ignore immediate key repeats or entirely ignore them (based on the glutIgnoreKeyRepeat setting). after discussing on gamedev.net ways to remove this delay i kinda figured out how to do it but figured i would put it on the back burner because it was a lesser problem than that of the jumpy visuals.

however, tonight when i got frustrated not knowing what to do with the visuals i decided to implement the delay-less input.

bingo!

turns out that because glut was poling the keyboard every cycle it created some crazy drawing issues. so now it is smooth as butter (and a better frame rate too no less).

needless to say, i’m pretty happy. :slight_smile:

oh, and i implemented some basic jump physics while i was at it. fun stuff trying to apply all 5 of my physics/dynamics classes (architectural engineering ftw!) and messing up the basic constant acceleration equations. don’t tell my profs. :slight_smile: