PDA

View Full Version : black flicker at triangle edges



coffeeaddict
06-17-2011, 09:38 AM
This is the cube I am trying to render (24 vertices with 12 tris):
http://i295.photobucket.com/albums/mm151/coffeeaddict21/glcube.jpg
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,&amp;vdataBufferID);
glBindBuffer(GL_ARRAY_BUFFER,vdataBufferID);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertexType)*ve rtexArray.size(),&amp;(vertexArray[0]),GL_STATIC_DRAW);

glGenBuffers(1,&amp;viBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,viBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLusho rt)*vertexIndex.size(),&amp;(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.0 1f;
cameraAngularY=float(m3dDegToRad(deltaMouseY))*0.0 1f;
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.GetProjectionM atrix());
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,tra nsformPipeline.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(&amp;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\n", glewGetErrorString(err));
return 1;
}
SetupRC();

glutMainLoop();
//delete VBO
glDeleteBuffers(1,&amp;vdataBufferID);
glDeleteBuffers(1,&amp;viBufferID);
return 0;
}

Suggestions? Thanks for any help.

carsten neumann
06-17-2011, 10:52 AM
You upload vertex data every time you draw, because your draw function contains:



glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof (vertexType),BUFFER_OFFSET(0));


Unless the data changes you only want to do the upload once and then only bind the buffer and draw from it.

Alfonse Reinheart
06-17-2011, 11:03 AM
You upload vertex data every time you draw, because your draw function contains:

glVertexAttribPointer does no data uploading.

carsten neumann
06-17-2011, 11:19 AM
Oops, sorry, got confused :(

I'd really like to make up for that mistake by spotting the real issue, but I can't seem to see any problem with the code, sorry.

coffeeaddict
06-18-2011, 11:06 AM
Thanks for looking at the code. It might just be the video card driver or the shader. Sorry to use up your time. I'm going to push ahead with lighting the cube and applying textures.