0
votes

i'm trying to make a simple program that rotates a cube around the window. when i run it, it looks like the cube faces are being rendered in the correct order at first, but once they spin around to the back they show through the front instead of the other ones. I am using glEnable(GL_DEPTH_TEST), glenable(GL_CULL_FACE) and glcullface(GL_BACK) which i thought would take care of the depth testing but it's still not working. here is my script,`

int windowwidth = 1920;
int windowheight = 1080;
GLfloat aspectratio = 16 / 9.0;
double horizontalposition = 0;
double verticalposition = 0;
double depthposition = 0;

GLfloat projTop = 1;
GLfloat projBottom = 0;
GLfloat floatOne = 1.0;
GLfloat oneFourth = 1.0 / 4;
GLfloat projLeft = 0;
GLfloat projRight = 1;
GLfloat zNear = .1;
GLfloat zFar = 1;
GLfloat zRange = zNear - zFar;
GLuint puddletexture;
GLuint sampler = 0;
GLuint samplerUniform;
GLuint shaderProgram;
GLuint textureunit = 0;
GLuint positionUniform, colourUniform,  rotationViewUniform, projectionUniform,translationUniform, rotationUniform, timeUniform, transformUniform;
GLuint colourAttribute,secondColourAttribute, positionAttribute, textureAttribute, indexAttribute;
GLuint vertexArrayObject,
vertexBuffer;
GLuint vao, vbo[3];
GLuint triangleVao, triangleVbo[2];
GLuint elementbuffer;
GLuint triangleArrayObject, triangleVertexBuffer;

GLfloat diamond[] = {
    -1,  1,  1, // vertex[0]
    1,  1,  1, // vertex[1]
    1, -1,  1, // vertex[2]
    -1, -1,  1, // vertex[3]
    -1,  1, -1, // vertex[4]
    1,  1, -1, // vertex[5]
    1, -1, -1, // vertex[6]
    -1, -1, -1, // vertex[7]
};

GLuint cubeindicies[] = {
    0, 1, 2, 2, 3, 0, // front face
    3, 2, 6, 6, 7, 3, // top face
    7, 6, 5, 5, 4, 7, // back face
    4, 0, 3, 3, 7, 4, // left face
    0, 1, 5, 5, 4, 0, // bottom face
    1, 5, 6, 6, 2, 1,
};


GLfloat colors[4][4] = {
    { 1.0,  0.0,  0.0, 0.0}, /* Red */
    { 1.0,  1.0,  0.0, 0.0}, /* Green */
    { 0.0,  0.0,  1.0, 0.0}, /* Blue */
    { 1.0,  1.0,  1.0, 0.0},

};

GLfloat picturetexturecoordinates[] = {
    0,1,0,
    0,0,0,
    1,0,0,
    1,1,0,
};



GLuint loadTexture(Image* image) {
    GLuint textureId;
    glGenTextures(1, &textureId); //Make room for our texture
    glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D,                //Always GL_TEXTURE_2D
        0,                            //0 for now
        GL_RGB,                       //Format OpenGL uses for image
        image->width, image->height,  //Width and height
        0,                            //The border of the image
        GL_RGB, //GL_RGB, because pixels are stored in RGB format
        GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
                          //as unsigned numbers
        image->pixels);               //The actual pixel data
    return textureId; //Returns the id of the texture
}

void reshape(int w, int h) {
    glViewport(0, 0, w, h);
    gluPerspective(45.0f, (float)w / (float)h, 1.0f, 100.0f);

    windowwidth = glutGet(GLUT_WINDOW_WIDTH);
    windowheight = glutGet(GLUT_WINDOW_HEIGHT);
    aspectratio = (double)windowwidth / windowheight;
}

void animate() {
    glutPostRedisplay();
}

void visible(int vis) {
    if (vis == GLUT_VISIBLE)
        glutIdleFunc(animate);
    else
        glutIdleFunc(0);
}

void loadShader();
void display();


void loadShader() {
    shaderProgram = InitShader("beelsebob.vert", "beelsebob.frag", "fragColour");
    positionUniform = glGetUniformLocation(shaderProgram, "p");
    if (positionUniform < 0) {
        std::cerr << "Shader did not contain the 'p' uniform" << std::endl;
    }
    colourUniform = glGetUniformLocation(shaderProgram, "c");
    if (colourUniform < 0) {
        std::cerr << "Shader did not contain the 'c' uniform" << std::endl;
    }
    timeUniform = glGetUniformLocation(shaderProgram, "timer");
    if (timeUniform < 0) {
        std::cerr << "Shader did not contain the 'timer' uniform" << std::endl;
    }
    samplerUniform = glGetUniformLocation(shaderProgram, "textSampler");
    if (samplerUniform < 0) {
        std::cerr << "Shader did not contain the 'textSampler' uniform" << std::endl;
    }
    projectionUniform = glGetUniformLocation(shaderProgram, "projectionMatrix");
    if (projectionUniform < 0) {
        std::cerr << "Shader did not contain the 'projectMatrix' uniform" << std::endl;
    }
    rotationViewUniform = glGetUniformLocation(shaderProgram, "rotationViewMatrix");
    if (rotationViewUniform < 0) {
        std::cerr << "Shader did not contain the 'rotationViewMatrix' uniform" << std::endl;
    }
    transformUniform = glGetUniformLocation(shaderProgram, "transformMatrix");
    if (transformUniform < 0) {
        std::cerr << "Shader did not contain the 'transformMatrix' uniform" << std::endl;
    } 
    translationUniform = glGetUniformLocation(shaderProgram, "translationMatrix");
    if (translationUniform < 0) {
        std::cerr << "Shader did not contain the 'translationMatrix' uniform" << std::endl;
    }
    translationUniform = glGetUniformLocation(shaderProgram, "translationMatrix");
    if (translationUniform < 0) {
        std::cerr << "Shader did not contain the 'translationMatrix' uniform" << std::endl;
    }
    colourAttribute = glGetAttribLocation(shaderProgram, "colour");
    if (colourAttribute < 0) {
        std::cerr << "Shader did not contain the 'colour' attribute." << std::endl;
    }
    secondColourAttribute = glGetAttribLocation(shaderProgram, "secondColour");
    if (secondColourAttribute < 0) {
        std::cerr << "Shader did not contain the 'secondColour' attribute." << std::endl;
    }
    positionAttribute = glGetAttribLocation(shaderProgram, "position");
    if (positionAttribute < 0) {
        std::cerr << "Shader did not contain the 'position' attribute." << std::endl;
    }
    textureAttribute = glGetAttribLocation(shaderProgram, "textcoord");
    if (textureAttribute < 0) {
        std::cerr << "Shader did not contain the 'textcoord' attribute." << std::endl;
    }

}


void display() {
    glClearColor(0.0, 0.0, .2, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GLUT_MULTISAMPLE);
    glLoadIdentity();
    const float timeScale = 0.0008f;

    glUseProgram(shaderProgram);
    GLfloat timeValue = glutGet(GLUT_ELAPSED_TIME)*timeScale;
    vec3 p3(.5f*sin(timeValue)  ,0  , 0.5f*cosf(timeValue));
    //vec4 c4(.5f*sinf(timeValue), .1f*sinf(timeValue), 9*cosf(timeValue), 1.0);
    vec4 c4(.7f, .5f, 0.01, 0.0);
    mat4 rotationMat(
    { cos(timeValue), sin(timeValue), 0,0 },

    { 0,1,0,0 },
    { -sin(timeValue), cos(timeValue), 1,0 },
    { 0,0,0,1 }
    );
    mat4 transMat(
    {1,0,0,0},
    {0,1,0,0},
    {0,0,(GLfloat)(windowheight*1.0/windowwidth),0},
    {0,0,0,1}
    );
    mat4 projMat(
    {zFar/aspectratio, 0, 0, 0 },
    { 0, zFar, 0, 0 },
    { 0,0, (zFar+zNear)/(zNear-zFar), (2*zFar*zNear)/(zNear-zFar) },
    { 0,0,0,1}
    );

    mat4 completeTransformMatrix = projMat*transMat*rotationMat;
    glUniformMatrix4fv(projectionUniform, 1, GL_FALSE, projMat);
    glUniformMatrix4fv(rotationViewUniform, 1, GL_FALSE, rotationMat);
    glUniformMatrix4fv(translationUniform, 1, GL_FALSE, transMat);
    glUniformMatrix4fv(transformUniform, 1, GL_FALSE, completeTransformMatrix);
    glUniform3fv(positionUniform,1,(const GLfloat*)&p3);
    glUniform4fv(colourUniform, 1, (const GLfloat*)&c4);
    glUniform1i(samplerUniform, 0);
    glUniform1fv(timeUniform, 1, (const GLfloat*)&timeValue);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, squareTexture);
    glGenSamplers(1, &sampler);
    glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindSampler(0, sampler);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[3]);
    glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, sizeof(cubeindicies)/sizeof(GLuint), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glUseProgram(0);
    glutSwapBuffers();

}


double r = 0;
void loadBufferData() {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GLUT_MULTISAMPLE);
    glEnable(GL_PERSPECTIVE_CORRECTION_HINT);
    Image* squareImage = loadBMP("puddletexture.bmp");
    squareTexture = loadTexture(squareImage);
    delete squareImage;

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glGenBuffers(4, vbo);

    glEnableVertexAttribArray(positionAttribute);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(diamond), diamond, GL_STATIC_DRAW);
    glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(colourAttribute);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
    glVertexAttribPointer(colourAttribute, 4, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(textureAttribute);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(picturetexturecoordinates), picturetexturecoordinates, GL_STATIC_DRAW);
    glVertexAttribPointer(textureAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(indexAttribute);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[3]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeindicies), cubeindicies, GL_STATIC_DRAW);

}


int main(int argc, char* argv[])
{
    glutInit(&argc, argv);

    glutInitContextVersion(3, 2);
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutSetOption(
        GLUT_ACTION_ON_WINDOW_CLOSE,
        GLUT_ACTION_GLUTMAINLOOP_RETURNS
    );
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
    glutCreateWindow("02561");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutVisibilityFunc(visible);
    glutIdleFunc(animate);
    glutReshapeWindow(600, 400);

    glewExperimental = GL_TRUE;
    GLint GlewInitResult = glewInit();
    if (GlewInitResult != GLEW_OK) {
        printf("ERROR: %s\n", glewGetErrorString(GlewInitResult));
    }

    loadShader();
    loadBufferData();
    glutMainLoop();
}

vertex shader:

    #version 330

uniform vec3 p;
uniform mat4 transformMatrix;
uniform vec4 c;
in vec4 position;
in vec4 colour;
out vec4 colourV;
in vec4 secondColour;
out vec4 secondColourV;
in vec2 textcoord;
out vec2 textcoordV;


void main (void)
{
    colourV = colour;
    colourV += c;
    textcoordV = textcoord;
    gl_Position = transformMatrix*position + vec4(p, 3.0);
}

and fragment shader:

    #version 330

uniform sampler2D textSampler;
in vec4 colourV;
in vec4 secondColourV;
out vec4 fragColour;
in vec2 textcoordV;
out vec2 fragTexture;
void main(void)
{
    fragColour = colourV*texture(textSampler, textcoordV);
}

here is an image that shows a couple of frames in the window when i run it,

windowframes so now i'm stuck, does anyone know what could be the problem?

1

1 Answers

1
votes

All your matrices seems to be wrong.

rotationMat is not a valid rotation matrix. All of them have in common that the row and the column that corresponds to the rotation axis are untouched. (x-rotation has first row and first column set to [1,0,0,0], y-rotation has second row and second column set to [0,1,0,0]). In your matrix the second row and the third column are unset. Source

transMat is not definitely a translation matrix although the usage looks as if it it should be one. Currently a scaling along the z-axis is performed.

projMat is completely wrong. Currently this is some kind of weird orthographic projection but somehow projects the x and y axis depending on the far-plane value? If you wanted to write a perspective projection matrix, then zFar in the first two rows should have been cotan(field_of_view / 2) and the forth line should be [0, 0, -1, 0]. Source

Since you seem to have a lot of problems with writing correct matrices, I would highly recommend you to use a library for that (for example glm).

Additionally, you are setting uniforms that don't exist in your shader (for example translationMatrix), you check in the setup code whether these uniforms exist, but then try to set them in display regardless of this check, which should result in an OpenGL error (check glGetError()).