This is the cube I am trying to render (24 vertices with 12 tris):
I couldn’t get a screen shot of it, but whenever I move the camera (or I guess more precisely move the whole scene around the camera), I get a black flicker at the edges between the sides of the cube. I think it might be that the sides are being drawn too slow and can’t keep up with the camera movement. I know that I could render it more efficiently with 8 vertices but then the cube will look weird once I light it (not enough normals). Here is my code (about 230 lines long):
#define BUFFER_OFFSET(i)((char*)NULL+(i))
#include <GLTools.h> // OpenGL toolkit
#include <GLShaderManager.h> // Shader Manager Class
#include <GLFrustum.h>
#include <GLMatrixStack.h>
#include <GLGeometryTransform.h>
#include <GL/glut.h> // Windows FreeGlut equivalent
#include <vector>
struct vertexType
{
GLfloat xPos,yPos,zPos;
GLfloat rColor,bColor,gColor,aColor;
};
GLShaderManager shaderManager;
std::vector<vertexType> vertexArray;
std::vector<GLushort> vertexIndex;
GLuint vdataBufferID; //vertex data
GLuint viBufferID; //vertex index buffer
GLFrame cameraFrame;
GLFrame modelFrame;
bool rightMouseDown;
int oldMouseX,oldMouseY;
int deltaMouseX,deltaMouseY;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrustum frustum;
GLGeometryTransform transformPipeline;
void loadVertexArray(GLfloat x,GLfloat y,GLfloat z,GLfloat r,GLfloat g,GLfloat b,GLfloat a)
{
vertexType tempVertex;
tempVertex.xPos=x;
tempVertex.yPos=y;
tempVertex.zPos=z;
tempVertex.rColor=r;
tempVertex.gColor=g;
tempVertex.bColor=b;
tempVertex.aColor=a;
vertexArray.push_back(tempVertex);
}
void initTriCube(float xPos,float yPos,float zPos)
{
loadVertexArray(-0.5f,0.5f,0.0f, 1.0f,0.0f,0.0f,1.0f); //0 (0.0) RED
loadVertexArray(-0.5f,0.5f,0.0f, 0.0f,0.0f,1.0f,1.0f); //1 (0.1) GREEN
loadVertexArray(-0.5f,0.5f,0.0f, 0.0f,0.0f,0.5f,1.0f); //2 (0.2) DARK GREEN
loadVertexArray(-0.5f,-0.5f,0.0f, 1.0f,0.0f,0.0f,1.0f); //3 (1.0) RED
loadVertexArray(-0.5f,-0.5f,0.0f, 1.0f,0.0f,1.0f,1.0f); //4 (1.1) YELLOW
loadVertexArray(-0.5f,-0.5f,0.0f, 0.0f,0.0f,0.5f,1.0f); //5 (1.2) DARK GREEN
loadVertexArray(0.5f,-0.5f,0.0f, 1.0f,0.0f,0.0f,1.0f); //6 (2.0) RED
loadVertexArray(0.5f,-0.5f,0.0f, 1.0f,0.0f,1.0f,1.0f); //7 (2.1) YELLOW
loadVertexArray(0.5f,-0.5f,0.0f, 0.0f,1.0f,0.0f,1.0f); //8 (2.2) BLUE
loadVertexArray(0.5f,0.5f,0.0f, 1.0f,0.0f,0.0f,1.0f); //9 (3.0) RED
loadVertexArray(0.5f,0.5f,0.0f, 0.0f,0.0f,1.0f,1.0f); //10 (3.1 GREEN
loadVertexArray(0.5f,0.5f,0.0f, 0.0f,1.0f,0.0f,1.0f); //11 (3.2) BLUE
loadVertexArray(-0.5f,0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f); //12 (4.0) BLUE
loadVertexArray(-0.5f,0.5f,1.0f, 0.0f,0.0f,1.0f,1.0f); //13 (4.1) GREEN
loadVertexArray(-0.5f,0.5f,1.0f, 0.0f,0.0f,0.5f,1.0f); //14 (4.2) DARK GREEN
loadVertexArray(-0.5f,-0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f); //15 (5.0) BLUE
loadVertexArray(-0.5f,-0.5f,1.0f, 1.0f,0.0f,1.0f,1.0f); //16 (5.1) YELLOW
loadVertexArray(-0.5f,-0.5f,1.0f, 0.0f,0.0f,0.5f,1.0f); //17 (5.2) DARK GEEN
loadVertexArray(0.5f,-0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f); //18 (6.0) BLUE
loadVertexArray(0.5f,-0.5f,1.0f, 1.0f,0.0f,1.0f,1.0f); //19 (6.1) YELLOW
loadVertexArray(0.5f,-0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f); //20 (6.2) BLUE
loadVertexArray(0.5f,0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f); //21 (7.0) BLUE
loadVertexArray(0.5f,0.5f,1.0f, 0.0f,0.0f,1.0f,1.0f); //22 (7.1) GREEN
loadVertexArray(0.5f,0.5f,1.0f, 0.0f,1.0f,0.0f,1.0f); //23 (7.2) BLUE
//front
vertexIndex.push_back(12); vertexIndex.push_back(15); vertexIndex.push_back(18);
vertexIndex.push_back(18); vertexIndex.push_back(21); vertexIndex.push_back(12);
//back
vertexIndex.push_back(6); vertexIndex.push_back(3); vertexIndex.push_back(0);
vertexIndex.push_back(0); vertexIndex.push_back(9); vertexIndex.push_back(6);
//top
vertexIndex.push_back(22); vertexIndex.push_back(10); vertexIndex.push_back(1);
vertexIndex.push_back(1); vertexIndex.push_back(13); vertexIndex.push_back(22);
//bottom
vertexIndex.push_back(7); vertexIndex.push_back(19); vertexIndex.push_back(16);
vertexIndex.push_back(16); vertexIndex.push_back(4); vertexIndex.push_back(7);
//left side
vertexIndex.push_back(17); vertexIndex.push_back(14); vertexIndex.push_back(2);
vertexIndex.push_back(2); vertexIndex.push_back(5); vertexIndex.push_back(17);
//right side
vertexIndex.push_back(8); vertexIndex.push_back(11); vertexIndex.push_back(23);
vertexIndex.push_back(23); vertexIndex.push_back(20); vertexIndex.push_back(8);
glGenBuffers(1,&vdataBufferID);
glBindBuffer(GL_ARRAY_BUFFER,vdataBufferID);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertexType)*vertexArray.size(),&(vertexArray[0]),GL_STATIC_DRAW);
glGenBuffers(1,&viBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,viBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLushort)*vertexIndex.size(),&(vertexIndex[0]),GL_STATIC_DRAW);
modelFrame.SetOrigin(xPos,yPos,zPos);
modelFrame.SetUpVector(0.0f,1.0f,0.0f);
modelFrame.SetForwardVector(0.0f,0.0f,1.0f);
}
void drawTriCube()
{
glBindBuffer(GL_ARRAY_BUFFER,vdataBufferID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(vertexType),BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,4,GL_FLOAT,GL_FALSE,sizeof(vertexType),BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,viBufferID);
glDrawElements(GL_TRIANGLES,vertexIndex.size(),GL_UNSIGNED_SHORT,BUFFER_OFFSET(0));
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
void MouseMoved(int x,int y)
{
float cameraAngularX=0.0f;
float cameraAngularY=0.0f;
if(rightMouseDown)
{
deltaMouseX=x-oldMouseX;
deltaMouseY=y-oldMouseY;
cameraAngularX=float(m3dDegToRad(deltaMouseX))*0.01f;
cameraAngularY=float(m3dDegToRad(deltaMouseY))*0.01f;
cameraFrame.RotateWorld(cameraAngularX,0.0f,1.0f,0.0f);
cameraFrame.RotateWorld(cameraAngularY,1.0f,0.0f,0.0f);
}
}
void MouseClicked(int button, int state, int x, int y)
{
if(state==GLUT_DOWN)
{
if(button==GLUT_RIGHT_BUTTON)
{
rightMouseDown=true;
oldMouseX=x;
oldMouseY=y;
}
else
rightMouseDown=false;
}
}
void SpecialKeys(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_UP: modelFrame.RotateLocalX(0.1f);
break;
case GLUT_KEY_DOWN: modelFrame.RotateLocalX(-0.1f);
break;
case GLUT_KEY_LEFT: modelFrame.RotateLocalY(-0.1f);
break;
case GLUT_KEY_RIGHT: modelFrame.RotateLocalY(0.1f);
break;
default: break;
}
}
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
frustum.SetPerspective(35.0f,float(w)/float(h),1.0f,100.0f);
projectionMatrix.LoadMatrix(frustum.GetProjectionMatrix());
transformPipeline.SetMatrixStacks(modelViewMatrix,projectionMatrix);
}
void SetupRC()
{
glClearColor(255.0f, 255.0f, 255.0f, 1.0f );
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
shaderManager.InitializeStockShaders();
initTriCube(0.0f,0.0f,-8.0f);
}
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
modelViewMatrix.PushMatrix(); //save identity matrix
M3DMatrix44f cameraMatrix;
cameraFrame.GetCameraMatrix(cameraMatrix);
modelViewMatrix.PushMatrix(cameraMatrix);
modelViewMatrix.PushMatrix();
modelViewMatrix.MultMatrix(modelFrame);
shaderManager.UseStockShader(GLT_SHADER_SHADED,transformPipeline.GetModelViewProjectionMatrix());
drawTriCube();
modelViewMatrix.PopMatrix();
modelViewMatrix.PopMatrix();
modelViewMatrix.PopMatrix(); //restore identity matrix
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
rightMouseDown=false;
oldMouseX=0;
oldMouseY=0;
deltaMouseX=0;
deltaMouseY=0;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("Triangle");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
glutMotionFunc(MouseMoved);
glutMouseFunc(MouseClicked);
GLenum err = glewInit();
if (GLEW_OK != err)
{
fprintf(stderr, "GLEW Error: %s
", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
//delete VBO
glDeleteBuffers(1,&vdataBufferID);
glDeleteBuffers(1,&viBufferID);
return 0;
}
Suggestions? Thanks for any help.