GL_POLYGONS 不工作 我如何让我的功能工作

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

我一直在试验现代 OpenGL,我正在尝试制作绘图函数来自动绘制基本形状我已经成功地绘制了四边形,但是我无法让圆圈工作我的代码很好,因为当你改变绘图模式时GL_POINTS 你会看到正确的模式它只是不适用于其他模式我怀疑我使用默认的 OpenGL 坐标但我不确定

这是我的代码

#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错误函数是我在其他文件中实现的函数 以及顶点缓冲区、索引缓冲区和顶点数组创建

使用这段代码对我来说效果很好。

我停用了你的 vao、vbo ...
我使用 i 作为尺寸 (glDrawArrays(GL_POLYGON, 0, i / 2);).

检查您的 vao、vbo 和 ibo 实现。

#include <GL/glew.h>
#include <GLFW/glfw3.h>
// #include <Windows.h>
#include <array>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// #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 *)malloc(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, vertices);

  // 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, vertexes);

  // draw
  glDrawArrays(GL_POLYGON, 0, i / 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, {1.0, 0.0, 1.0, 1.0});
    // rectangle(shader, 0, 0, 0.5, 0.5, {1.0, 0.0, 1.0, 1.0});

    // end of rendering

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

  shader.deleteShader();

  glfwTerminate();
}

我确实发现了问题,我用 700 * 4 字节的内存(700 * 浮点数)制作了我的顶点列表,但我只使用 620,所以当程序超出它时,它会以默认值绘制顶点以用于未初始化的名单