c++ - 无法使用FBO绘制多个元素

标签 c++ opengl vbo freeglut

我正在尝试编辑this教程,以便在FBO中渲染多个圆。我简化了本教程,以便节省要通过FBO发送的内存:我仅发送x和y坐标,以及确定节点颜色的浮点数。该信息是从this文本文件中读取的。即使我试图绘制约660个节点,我的代码也不会全部显示。我的应用程序应该按比例放大,并可能绘制输入中读取的节点的任何可能大小。
我提供了一个图形化的插图,说明我希望通过R中的绘图获得什么:

library(ggplot2)
t <-read.table("pastebin_file.txt", header = T)
ggplot(t, aes(x, y)) + geom_point(aes(colour = factor(col)))

在OpenGL中,我得到的顶点数量较少(我知道颜色是倒置的,但这与我无关):

我想问题可能出在VBO上,或者我忘了正确设置所有参数。在这个阶段,我不知道问题出在哪里。如何解决此问题,以便在OpenGL上复制R的输出?我在问题的最后一部分为MWE提供了所有着色器:
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "utils/shaders.h"


size_t n = 0;
void render(void)
{
    // Clear the screen to black
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // I want to render exactly all the vertices that were loaded on the VBO.
    glDrawArrays(GL_POINTS, 0, n); 
    glutSwapBuffers();  // Update the rendering
}

program programma;

void set_shader()
{
    // Loading the shaders using a custom class. Nevertheless, the code is exactly the same as the one in https://open.gl/content/code/c7_final.txt, that is loading and compiling the three shaders, and then linking them together in one single program
    programma.add_shader(shader_t::vertex,   "shaders/vertexShader3.txt");
    programma.add_shader(shader_t::fragment, "shaders/fragmentShader3.txt");
    programma.add_shader(shader_t::geometry, "shaders/geometryShader3.txt");
    programma.compile();
}


GLuint vbo;
GLuint vao;

#include <regex>
#include <iostream>

size_t fbo(const std::string& filename) {
    // Create VBO with point coordinates
    glGenBuffers(1, &vbo);
    std::fstream name{filename};
    std::string line;
    std::getline(name, line); // Skipping the first line, that just contains the header
    std::vector<GLfloat> points; // Storage for all the coordinates
    n = 0;

    std::regex rgx ("\\s+");
    while (std::getline(name, line)) {
        std::sregex_token_iterator iter(line.begin(), line.end(), rgx, -1);
        std::sregex_token_iterator end;
        points.emplace_back(std::stof(*iter++)/20); // x, rescaled, so it can fit into screen
        points.emplace_back(std::stof(*iter++)/20); // y, rescaled, so it can fit into screen
        int i = std::stoi(*iter++);
        points.emplace_back(i);                         // determining the color
        n++;
    }
    std::cout << n << std::endl;                        // number of vertices
    std::cout << sizeof(float) * 3 * n << std::endl;    // expected size in B = 7992

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, points.size(), points.data(), GL_STATIC_DRAW);

    // Create VAO
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // Specify the layout of the node data: just two floats for the (x,y) pairs
    GLint posAttrib = glGetAttribLocation(programma.id, "pos");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);

    // Determining the color of the circle with one single float parameter
    GLint sidesAttrib = glGetAttribLocation(programma.id, "sides");
    glEnableVertexAttribArray(sidesAttrib);
    glVertexAttribPointer(sidesAttrib, 1, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*) (2 * sizeof(GLfloat)));

    return points.size()/3;
}



int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(200, 200);
    glutCreateWindow("Stuff");
    glutIdleFunc(render);

    glewInit();
    if (!glewIsSupported("GL_VERSION_2_0")) {
        fprintf(stderr, "GL 2.0 unsupported\n");
        return 1;
    }

    set_shader();
    fbo("pastebin_file.txt");
    glutMainLoop();
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);

    return 0;
}
#endif
shaders / vertexShader3.txt
#version 150 core

in vec2 pos;     // input vertex position
in float sides;  // determines the output color
out vec3 vColor;

void main() {
        gl_Position = vec4(pos, 0.0, 1.0);
        if (sides == 1.0) { // determining the color
            vColor = vec3(1.0,0.0,0.0);
        } else {
            vColor = vec3(0.0,1.0,0.0);
        }
}
shaders / geometryShader3.txt
#version 150 core

layout(points) in;
layout(line_strip, max_vertices = 640) out;

in vec3 vColor[];
out vec3 fColor;

const float PI = 3.1415926;
const float lati = 10;

void main() {
        fColor = vColor[0];

        // Safe, GLfloats can represent small integers exactly
        for (int i = 0; i <= lati; i++) {
            // Angle between each side in radians
            float ang = PI * 2.0 / lati * i;

            // Offset from center of point
            vec4 offset = vec4(cos(ang) * 0.3/20, -sin(ang) * 0.4/20, 0.0, 0.0);
            gl_Position = gl_in[0].gl_Position + offset;

            EmitVertex();

        }

        EndPrimitive();
}
shaders / fragmentShader3.txt
#version 150 core
in vec3 fColor;
out vec4 outColor;

void main() {
        outColor = vec4(fColor, 1.0); // Simply returning the color
}

最佳答案

glBufferData 的第二个参数必须是缓冲区的大小,以字节为单位:glBufferData(GL_ARRAY_BUFFER, points.size(), points.data(), GL_STATIC_DRAW);

glBufferData(GL_ARRAY_BUFFER, 
    points.size() * sizeof(points[0]), points.data(), GL_STATIC_DRAW);

关于c++ - 无法使用FBO绘制多个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62922651/

相关文章:

c - 无法在 OpenGL 中显示 VBO

c++ - 如何确保我的代码是 ansi C,不涉及 C++。是否可以设置像gcc这样的编译器在遇到C++的特性时提示错误?

c++ - SetFocus() 因有效的窗口句柄而失败

c++ - 通过OpenGL中的纹理传递数组数据

c - 仅使用 VAO id 检索链接到 VAO 的 VBO 数量及其 id,这可能吗?

c++ - 如何使用静态 TexCoords 和动态顶点调用 glDrawElements

c++ - QGraphicsView Qt 的点击事件

C++ 与性能指标的持续集成

OpenGL 阴影贴图

windows - Windows 上的 OpenGL 1.0 和 1.1 函数指针