微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我一直在尝试使用现代 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
    };

    //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,sizeof(vertices) / 4 / 2);

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

void ellipse(Shader shader,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],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,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,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};

  // 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,sizeof(vertices) / 4 / 2);

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

void ellipse(Shader shader,*/ 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],vertexes);

  // draw
  glDrawArrays(GL_POLYGON,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,1.0f);

    // render here
    ellipse(shader,{1.0,0.0,1.0,1.0});
    // rectangle(shader,0.5,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,所以当程序超过它时,它会在未初始化列表的默认值中绘制顶点

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。