2
\$\begingroup\$

I'm testing on OpenGL and I've created a cube that rotates, but everytime I launch it some weird bugs happens and sometimes opengl gives priority to the back faces and other times it just break and increase screen size.

Here a video showing what happens to me: https://i.gyazo.com/881e352dbf56d4df5b0cefb671e7ebf4.mp4

What can be happening??

I use Glew with GLM for GL, SDL2 for interface and Soil2 for image loading

Vertex Shader:

#version 330 core

layout (location = 0) in vec3 position; layout (location = 2) in vec2 texCoord;

out vec2 TexCoord;

uniform mat4 model; uniform mat4 view; uniform mat4 projection;

void main() {
    gl_Position = projection * view * model * vec4(position, 1.0f);
    TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); }

Fragment Shader:

#version 330 core

in vec2 TexCoord;

uniform sampler2D ourTexture1;

void main()
{
    gl_FragColor = texture(ourTexture1, TexCoord);
}

Main.cpp:

#include <iostream>
#include <fstream>
#include <string>
#include <glew\include\GL\glew.h>
#include <glm\glm\glm.hpp>
#include <glm\glm\gtc\matrix_transform.hpp>
#include <glm\glm\gtc\type_ptr.hpp>
#include <SDL2\include\SDL.h>
#include <soil2\include\SOIL2.h>
const GLint WIDTH = 800, HEIGHT = 600;
SDL_Window* m_window;
SDL_GLContext m_glContext;
GLuint m_shaders[2];
GLuint m_program;
GLuint m_texture;
static std::string LoadShader(const std::string& fileName) {
    std::ifstream file;
    file.open((fileName).c_str());
    std::string output;
    std::string line;
    if (file.is_open()) {
        while (file.good()) {
            getline(file, line);
            output.append(line + "\n");
        }
    }
    else {
        std::cerr << "Unable to load shader: " << fileName << std::endl;
    }
    return output;
}
static GLuint CreateShader(const std::string& loc, GLenum shaderType) {
    std::string text = LoadShader(loc);
    GLuint shader = glCreateShader(shaderType);
    if (shader == 0)
        std::cerr << "Error creating shader" << std::endl;
    const GLchar* shaderSourceStrings[1];
    GLint shaderSourceStringsLength[1];
    shaderSourceStrings[0] = text.c_str();
    shaderSourceStringsLength[0] = (GLint)text.length();
    glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringsLength);
    glCompileShader(shader);
    return shader;
}
int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_EVERYTHING);
    //From V3.3 to V3.3 with no compat to older versions
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); //Color Size
    m_window = SDL_CreateWindow("Test",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        WIDTH,
        HEIGHT,
        SDL_WINDOW_OPENGL);
    SDL_SetWindowResizable(m_window, SDL_TRUE); //Allow resize
    m_glContext = SDL_GL_CreateContext(m_window); //Set GL Context
    glewExperimental = GL_TRUE;
    //Allow textures alpha
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //Allow Depth
    glEnable(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    if (glewInit() != GLEW_OK) {
        std::cerr << "Failed to init Glew" << std::endl;
    }
    m_program = glCreateProgram();
    //Load Vertex and Fragment Shaders
    m_shaders[0] = CreateShader("core.vs", GL_VERTEX_SHADER);
    m_shaders[1] = CreateShader("core.fs", GL_FRAGMENT_SHADER);
    for (unsigned int i = 0; i < 2; i++)
        glAttachShader(m_program, m_shaders[i]);
    glLinkProgram(m_program);
    glValidateProgram(m_program);
    GLfloat vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };
    GLuint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2);
    glBindVertexArray(0); // Unbind VAO
    int width, height;
    unsigned char* image = SOIL_load_image("image1.jpg", &width, &height, 0, SOIL_LOAD_RGBA);
    if (image == nullptr)
        std::cerr << "Texture loading failed" << std::endl;
    glGenTextures(1, &m_texture);
    glBindTexture(GL_TEXTURE_2D, m_texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
    glGenerateMipmap(GL_TEXTURE_2D);
    SOIL_free_image_data(image);
    glBindTexture(GL_TEXTURE_2D, 0);
    ///Object DEPTH_______________________
    glm::mat4 projection;
    projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 1000.0f);
    ///Object DEPTH_______________________
    while (true) {
        glClearColor(0.55f, 0.55f, 0.55f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //Set Shader & texture
        glUseProgram(m_program);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_texture);
        glUniform1i(glGetUniformLocation(m_program, "ourTexture"), 0);

        ///Object DEPTH_______________________
        glm::mat4 model, view;
        model = glm::rotate(model, (GLfloat)SDL_GetTicks() * 0.001f, glm::vec3(0.5f, 1.0f, 0.0f));
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -1.9f));
        GLint modelLoc = glGetUniformLocation(m_program, "model");
        GLint viewLoc = glGetUniformLocation(m_program, "view");
        GLint projLoc = glGetUniformLocation(m_program, "projection");
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        ///Object DEPTH_______________________
        SDL_GL_SwapWindow(m_window);
        SDL_Event e;
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                return EXIT_SUCCESS;
            }
        }
    }
    ///TRIANGEL SHADER_______________________
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    ///TRIANGEL SHADER_______________________
    return EXIT_SUCCESS;
}

Reading on internet, I found out that faces can be placed to not let that happen... But I found out that the same happens with meshes imported from other places and those have no problem at the time of being rendered in other programs like Blender.

\$\endgroup\$
0
\$\begingroup\$

This looks to me like a depth buffer issue. Do you have a depth attachment in your FBO? IF so, I don't see where you're setting it up, though I don't know SDL very well. You're enabling depth testing and clearing the depth buffer, but you never set the depth test. That's OK if you want the default. But if you don't have a depth buffer attached, it won't matter.

One other thing you can do is to turn on back-face culling. That will eliminate the need (in this example case) for a depth buffer, though you will generally want a depth buffer for more complex geometry.

\$\endgroup\$
  • \$\begingroup\$ I did activated depth test in the past, and it kinda made the trick... Till you start using transparency, When you do it gives the transparent front texture priority over the one behind of it... which ends up with you looking the background of the window where you should bee seeing the object behind of it. So decided to deactivate it and try to find another way to solve that weird bug. I also tried with face culling back activated, but it break up 50% of the faces from any model you import. \$\endgroup\$ – Onelio Dec 29 '17 at 0:43
  • \$\begingroup\$ Yes, for transparency you need to either draw in depth order or use a technique like depth peeling or another order independent drawing method. If back-face culling breaks up your geometry, then you may have a problem with the winding order of your polygons. \$\endgroup\$ – user1118321 Dec 29 '17 at 0:53
  • \$\begingroup\$ Ok, So I finally fixed it with a little trick in the fragment shader discarding all the stuff with < 0.8f of alpha. Thanks for the advice! \$\endgroup\$ – Onelio Dec 29 '17 at 10:59
  • \$\begingroup\$ Do you think that this could bee a good approach to solve the problem? I noticed that now it looks better but with some distance some objects don't look as well as before... But it's just a minor problem. PD: I changed the number above to 0.7f cause it balance better the object look. \$\endgroup\$ – Onelio Dec 29 '17 at 11:53
  • \$\begingroup\$ If that's working for you, then go for it! \$\endgroup\$ – user1118321 Dec 29 '17 at 18:52
0
\$\begingroup\$

It looks like lack of depth buffer or depth test disabled issue, as previous answer said. I'll try to elaborate on cause of that issue.

OpenGL is just triangle (or other primitive) rasterizer. It is drawing triangles in order you send them to it (stored in the buffer), so they are sometimes overlaping. To solve that problem OpenGL has depth testing feature, which before fragment shader kicks in it is testing if something is already written in curent fragment already. if it is, it test (compares depths) if its "closer" to camera than currently drawing fragment.If it is not, than discards it and fragment shader is not firing.

Also a common optimization technique is to sort your scene (usually every frame, and usually objects, not primitives, triangles etc.) front to back, so opengl is mostly drawing triangles that will be visible in the final frame, so you hahe less, what it's called, overflow. Also worth noting that for transparent geometries sorting order must be reversed (back to front) or depth test must be disabled.

\$\endgroup\$
  • \$\begingroup\$ Isn't there a way of fixing this issue without using depth test? I don't really want to mess with transparency issues later. \$\endgroup\$ – Onelio Dec 30 '17 at 9:48
  • \$\begingroup\$ I don't know another way, but you can try enabling depth test for opaque geometry and disabling it for transparent geometry, but i'm not sure if it will work as intended. \$\endgroup\$ – Pirx Jan 2 '18 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.