c++visual-studioopenglglfwvertex-array-object

GL_POLYGONS does not work how do i get my function to work


I have been experimenting with modern OpenGL and I am trying to make draw functions to automate drawing basic shapes I have done quads successfully but I can't get circles to work my code is good because when you change the drawing mode to GL_POINTS you will see the right pattern it just doesn't work with other modes I'm suspicious of me using the default OpenGL coordinates but I'm not sure

here is my code

#include <GL\glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <Windows.h>
#include <string>
#include <array>
#include "Logging.h"
#include "VertexBuffer.h"
#include "VertexArray.h"
#include "Index Buffer.h"

using namespace std;

// define width and height of our window
int width = 600;
int height = 600;

//define pi
const double pi = 3.14159265359;
const double phi = (1 + sqrt(5) / 2);

// class for creating Shaders
class Shader
{
    string vertex_source;
    string fragment_source;
    unsigned int shader;
    int color_location;

    unsigned int CompileShader(unsigned int type, string& source)
    {
        unsigned int id = glCreateShader(type);
        const char* src = source.c_str();
        glShaderSource(id, 1, &src, nullptr);
        glCompileShader(id);


        //error handling
        int result;
        glGetShaderiv(id, GL_COMPILE_STATUS, &result);
        if (result == GL_FALSE)
        {
            int length;
            glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);

            char* message = (char*)_malloca(length * sizeof(char));

            glGetShaderInfoLog(id, length, &length, message);

            error(message);

            glDeleteShader(id);

            return 0;
        }

        return id;
    }

    unsigned int CreateShader(string& vertexShader, string& fragmentShader)
    {
        unsigned int Program = glCreateProgram();
        unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
        unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);

        glAttachShader(Program, vs);
        glAttachShader(Program, fs);
        glLinkProgram(Program);
        glValidateProgram(Program);

        glDeleteShader(vs);
        glDeleteShader(fs);

        return Program;
    }

    public:
        Shader(const string& file_path)
        {

            enum class ShadeType
            {
                NONE = -1, VERTEX = 0, FRAGMENT = 1
            };

            ifstream stream(file_path);

            string line;
            stringstream ss[2];

            ShadeType type = ShadeType::NONE;

            while (getline(stream, line))
            {
                if (line.find("#shader") != string::npos)
                {

                    if (line.find("vertex") != string::npos)
                    {
                        type = ShadeType::VERTEX;
                    }

                    else if (line.find("fragment") != string::npos)
                    {
                        type = ShadeType::FRAGMENT;
                    }

                }
                else
                {
                    ss[(int)type] << line << "\n";
                }
            }

            vertex_source = ss[0].str();
            fragment_source = ss[1].str();
            shader = CreateShader(vertex_source, fragment_source);
        }

        void useShader()
        {
            glUseProgram(shader);
        }

        void setColor(float red, float green, float blue, float alpha)
        {
            int color_location = glGetUniformLocation(shader, "u_Color");
            glUniform4f(color_location, red, green, blue, alpha);
        }

        void deleteShader()
        {
            glDeleteProgram(shader);
        }
};


void rectangle(Shader shader, VertexArray vertexArray, double x, double y, double width, double height, array <float, 4> color)
{
    //creating a vertex buffer object
    VertexBuffer VBuff;

    //creating a vertex array
    float vertices[] = {
         x + width / 2, y + height / 2,
         x + width / 2, y - height / 2,
         x - width / 2, y - height / 2,
         x - width / 2, y + height / 2
    };

    //writing a vertex array to our vertex buffer
    VBuff.write(vertices, sizeof(vertices));

    shader.setColor(color[0], color[1], color[2], color[3]);

    // bind buffers, ...
    VBuff.bind();
    vertexArray.bind();
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    // draw
    glDrawArrays(GL_POLYGON, 0, sizeof(vertices) / 4 / 2);

    // unbind buffers, ...
    VBuff.unbind();
    vertexArray.unbind();
}

void ellipse(Shader shader, VertexArray vertexArray, array <float, 4> color)
{
    VertexBuffer VBuff;

    float vertexes[700];

    int i = 0;
    double a = 0;

    while (a < pi*2)
    {
        if ((i % 2) == 0){ vertexes[i] = cos(a); }
        
        else { vertexes[i] = sin(a); }
        
        a += 0.01;
        i += 1;
    }

    //writing a vertex array to our vertex buffer
    VBuff.write(vertexes, sizeof(vertexes));

    shader.setColor(color[0], color[1], color[2], color[3]);

    // bind buffers, ...
    VBuff.bind();
    vertexArray.bind();
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    // draw
    glDrawArrays(GL_POLYGON, 0, sizeof(vertexes) / 4 / 2);

    // unbind buffers, ...
    VBuff.unbind();
    vertexArray.unbind();
}


// main
int main(void)
{
    //making a window object
    GLFWwindow* window;

    //initialize glfw
    if (!glfwInit())
    {
        error("could not initialize glfw");
        return -1;
    }
    else
    {
        info("glfw initialized successfully");
    }

    //setting opengl to opengl 4.0 COMPATIBILITY PROFILE
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

    //Create a windowed mode window and its OpenGL context
    window = glfwCreateWindow(width, height, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        error("could not create window");
        return -1;
    }

    //Make the window's context current
    glfwMakeContextCurrent(window);

    // initialize glew
    if (glewInit() != GLEW_OK)
    {
        error("could not initialize glew");
        return -1;
    }
    else
    {
        info("glew initialized successfully");
    }

    //creating a shader using the shader file from that path
    Shader shader("C:/Users/FMalt/source/repos/C++/res/basic.shader");
    
    //using the before created shader
    shader.useShader();

    //creating a vertex array object this is for all objects
    VertexArray vao;

    //code here

    //Loop until the user closes the window
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.25f, 0.25f, 0.25f, 1.0f);

        //render here
        ellipse(shader, vao, {1.0, 0.0, 1.0, 1.0});

        //end of rendering

        // Swap front and back buffers
        glfwSwapBuffers(window);
        //Poll for and process events
        glfwPollEvents();

    }
    info("code ran successfully");

    shader.deleteShader();

    glfwTerminate();
    info("Window closed");
}

info error functions are functions I implemented in other files as well as vertex buffer, index buffer, and vertex array creating


Solution

  • i acually found the problem i made my vertexes list with 700 * 4 bytes of memory (700*float)but i only use 620 so when the program goes above that it draws the vertex in the default value for an uninitialized list