XnossisX
XnossisX

Reputation: 57

The "hello triangle" is not showing. Is there some function not correctly used?

My goal is to reach the point where I can reach the end result of this video: https://www.youtube.com/watch?v=ZpAeH0SpR5Y&list=PL6xSOsbVA1eYSZTKBxnoXYboy7wc4yg-Z&index=13. However, whenever I have ran this code, it only gives me a black screen, even though it does not give errors.

I've tried using all versions from 4.4 to 4.6, with all not working. The VAO, VBO, and EBO are all defined, and changing the specifics of each function haven't worked. The only clue I have is that the core_program and VAO are only 3 and 1 respectively, which is suspicious, because they should be containing more data (at line 224). When I downloaded GLFW, the tutorial stated that the way that the file to use from the zip is one version below the version of Visual Studio you're using, but I saw a glfw2019 folder, so I used that. Perhaps that changes something? I used GLAD by the way, rather than GLEW, which was used in the tutorial. Also, sorry about the amount of code here, but I can't isolate the issue enough. (and i do weird names, too)

libs.h:

#pragma once

#include <iostream>
#include <glad.h>
#include <glfw3.h>
#include <glm.hpp>
#include <vec2.hpp>
#include <vec3.hpp>
#include <vec4.hpp>
#include <mat4x4.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>

struct Vertex
{
    glm::vec3 position;
    glm::vec3 color;
    glm::vec2 texcoord;
};

vertexium.glsl:

#version 450
layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec2 vertex_texcoord;

out vec3 vs_position;
out vec3 vs_color;
out vec2 vs_texcoord;

void main()
{
    vs_position = vertex_position;
    vs_color = vertex_color;
    vs_texcoord = vec2(vertex_texcoord.x, vertex_texcoord.y * -1.f);

    gl_Position = vec4(vertex_position, 1.f);
}

fragmentium.glsl:

#version 450

in vec3 vs_position;
in vec3 vs_color;
in vec2 vs_texcoord;

out vec4 fs_color;

void main()
{
    fs_color = vec4(vs_color, 1.f);
}

And finally, main.cpp:

#include "libs.h"
#include <fstream>
#include <string>

#include <vector>


//makes window size known
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

//loads shaders, obviously
bool loadShaders(GLuint& program)
{
    bool didItWork = true;
    char infoLog[512];
    GLint success;
    std::string temp = "";
    std::string src = "";
    std::ifstream in_file;

    //Vertexium, Activate!
    in_file.open("vertexium.glsl");
    if (in_file.is_open())
    {
        while (std::getline(in_file, temp))
            src += temp + "\n";
    }
    else
    {
        std::cout << "The program could not open the vertexium.";
        didItWork = false;
    }

    in_file.close();
    //replace with unsigned int if needed
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    const GLchar* vertSrc = src.c_str();
    glShaderSource(vertexShader, 1, &vertSrc, NULL);
    glCompileShader(vertexShader);

    //make sure it's good
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "The vertexium was not successfully compiled." << "\n";
        std::cout << infoLog << "\n";
        didItWork = false;
    }


    //Fragmentium, Activate!
    temp = "";
    src = "";

    in_file.open("fragmentium.glsl");
    if (in_file.is_open())
    {
        while (std::getline(in_file, temp))
            src += temp + "\n";
    }
    else
    {
        std::cout << "The program could not open the fragmentium.";
        didItWork = false;
    }

    in_file.close();
    //replace with unsigned int if needed
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    const GLchar* fragSrc = src.c_str();
    glShaderSource(fragmentShader, 1, &fragSrc, NULL);
    glCompileShader(fragmentShader);

    //make sure it's good
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "The fragmentium was not successfully compiled." << "\n";
        std::cout << infoLog << "\n";
        didItWork = false;
    }

    //program thingio
    program = glCreateProgram();

    //attach
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);

    glLinkProgram(program);

    //make sure
    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if (!success)
    {
        glGetProgramInfoLog(program, 512, NULL, infoLog);
        std::cout << "The omega program was not successfully linked." << "\n";
        std::cout << infoLog << "\n";
        didItWork = false;
    }

    //end
    //start usin'
    glUseProgram(0);
    //yeetus deletus: we didn't need you
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    return didItWork;
}
//for escaping the system
void processInput(GLFWwindow* window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GLFW_TRUE);
}
//triangle
Vertex vertices[] = 
{
    glm::vec3(0.0f, 0.5f, 0.f),         glm::vec3(1.f, 0.f, 0.f),       glm::vec2(0.f, 1.f),
    glm::vec3(-0.5f, -0.5f, 0.f),       glm::vec3(0.f, 1.f, 0.f),       glm::vec2(0.f, 0.f),
    glm::vec3(-0.5f, 0.5f, 0.f),        glm::vec3(0.f, 0.f, 1.f),       glm::vec2(1.f, 0.f)
};
//number = nr
unsigned nrOfVertices = sizeof(vertices) / sizeof(Vertex);

GLuint indices[] =
{
    0, 1, 2
};
unsigned nrOfIndices = sizeof(indices) / sizeof(GLuint);

//inputs

int main()
{
    //instantiation for window (is my favorite word)
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    //time for windows bois


    GLFWwindow* window = glfwCreateWindow(800, 600, "yoyleoscopy", NULL, NULL);
    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "Failed to initialise GLAD" << std::endl;
    }
    //make look good and stable sizing
    glViewport(0, 0, 800, 600);

    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    //stock options

    glEnable(GL_DEPTH_TEST);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    //here is a program
    GLuint core_program;
    //load things
    if (!loadShaders(core_program))
    {
        glfwTerminate();
    }

    //model

    //VAO and binding
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    //VBO and binding
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //EBO and binding
    GLuint EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //vertexattribpointers and enabling extras (INPUT ASSEMBLY)
    //position
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
    glEnableVertexAttribArray(0);
    //color
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
    glEnableVertexAttribArray(1);
    //texcoord
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texcoord));
    glEnableVertexAttribArray(2);

    //bind VAO 0
    if (core_program)
    {
        std::cout << nrOfIndices;
    }
    glBindVertexArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    //VERY IMPORTANT
    //THIS IS THE RENDER LOPP
    //LOPP IS A MISSPELLING (but i don't care, this makes it more noticeable)
    while (!glfwWindowShouldClose(window))
    {
        //input and stuff
        processInput(window);

        //RENDER STUFF
        //nice color there, chartreuse
        glClearColor(0.f, 0.f, 0.f, 1.f);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        //programme
        glUseProgram(core_program);
        //bind vertex array object
        glBindVertexArray(VAO);
        //draw
        //glDrawElements(GL_TRIANGLES, nrOfIndices, GL_UNSIGNED_INT, 0);
        glDrawArrays(GL_TRIANGLES, 0, 3);


        //gl background stuff i don't care about
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    //we're over it
    glfwDestroyWindow(window);
    glfwTerminate();

    //delete program
    glDeleteProgram(core_program);

    return 0;
}

Again, there should be a rainbow-like triangle on the window this opens, but this shows a blank, black screen. There are no error messages though, not even warnings, during compiling and running. So hopefully, someone can actually see what messes up here.

Upvotes: 3

Views: 108

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

The issue is caused by Face Culling.

The winding order of the triangle is clockwise:

Vertex vertices[] = 
{
   glm::vec3(0.0f, 0.5f, 0.f),         glm::vec3(1.f, 0.f, 0.f),       glm::vec2(0.f, 1.f),
   glm::vec3(-0.5f, -0.5f, 0.f),       glm::vec3(0.f, 1.f, 0.f),       glm::vec2(0.f, 0.f),
   glm::vec3(-0.5f, 0.5f, 0.f),        glm::vec3(0.f, 0.f, 1.f),       glm::vec2(1.f, 0.f)
};
2      0
 +----+
 |   /
 |  /
 | /
 |/
 +
1

But you've defined that back faces are culled and front faces a counter-clockwise:

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);

There are many possibilities to solve the issue.

1 possibility is to change define front faces to be clockwise:

glFrontFace(GL_CW);

An other possibility is keep glFrontFace(GL_CWW), but to use the indices to define a counter-clockcwise triangle:

GLuint indices[] = { 0, 2, 1 };

And to draw the triangle by the indices:

glDrawElements(GL_TRIANGLES, nrOfIndices, GL_UNSIGNED_INT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 3);

Upvotes: 4

Related Questions