c++ - 试图绘制点云,只是 opengl 中心的一个点

标签 c++ algorithm opengl glfw glm-math

尝试在 2D 中创建随机点云。但是,我现在终于得到了这个:背景颜色 + 中心有 1 个“灰色”点。这里可能出了什么问题?

  • 我尝试编写自己的简单着色器。
  • 尝试自己编译shader。
  • 一切都应该是婴儿学步。
  • 还有什么调试这些问题的技巧?
#include <vector>
#include <algorithm>
#include <iostream>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

GLFWwindow* window;

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/norm.hpp>

/* SHADERS */

/* Vertex Shader */
const char *VertexShaderSource="#version 330 core\n"
"layout(location=0) in vec2 pos;\n"
"//layout(location=1) in vec2 da;//distance and angle \n"
"//layout(location=2) in vec4 color;\n"
"\n"
"out vec4 particle_color\n"
"uniform mat4 mvp;\n"
"int main(){\n"
"gl_Position = mvp*vec4(pos, 0.0,1.0));\n"
"//particle_color =;\n"
"}\n";
/* Fragment Shader*/
const char *FragmentShaderSource="#version 330 core\n"
"//in vec4 particle_color;\n"
"out vec4 color;\n"
"//layout(location=2) in vec4 color;\n"
"void main(){\n"
"color =  vec4(1.0f,0.0f,0.0f,1.0f);\n"
"}\n";
/* SHADERS END */



// Particle
struct Point{
    glm::vec2 pos;
    // Create random color in GPU
    // unsigned char r,g,b,a;
    float distance;
    float angle;
};
static const int max_point_number=1000;
Point PointContainer[max_point_number];

int main()
{
    // Start GLFW
    if(!glfwInit())
    {
        std::cout<<"Failed to start GLWF\n";
        getchar();
        return -1;
    }   

    glfwWindowHint(GLFW_SAMPLES, 4);
    //glfwWindowHint(GLFW_RESIZABLE,GL,FALSE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
    window = glfwCreateWindow(800, 600, "Rotating Points", NULL, NULL);
    if(window == NULL)
    {
        std::cout<<"Initialization of the window failed\n";
        getchar();
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Start GLEW;
    glewExperimental = true;
    if(glewInit() != GLEW_OK)
    {
        std::cout<<"Failed to start GLEW\n";
        getchar();
        return -1;
    }

    glfwPollEvents();

    glClearColor(.0f,0.5f,0.5f,0.0f); // Black is the new orange


    // Camera
    glm::mat4 Projection = glm::ortho(0.0f,800.0f, 0.0f,600.0f,-5.0f,5.0f); // In world coordinates
    glm::mat4 View = glm::lookAt(
    glm::vec3(0,0,-1), // Camera is at (0,0,-1), in World Space
    glm::vec3(0,0,0), // and looks at the origin
    glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
    );
    glm::mat4 Model = glm::mat4(1.0f);
    glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around
    // No need to have depth test

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // Build and compile shaders
    // Vertex Shader
    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &VertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // Fragment Shader
    int fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &FragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // Link Shaders
    int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);
    // Delete Shaders after Linking
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    for(auto &p:PointContainer)
    {
        p.pos.x =rand() % 800;
        p.pos.y =rand() % 600;
        std::cout<<p.pos.x<<" "<<p.pos.y<<"\n";
    }
    // Vertex Shader
    GLuint tPM = glGetUniformLocation(shaderProgram, "mvp");//mvp
    glUniformMatrix4fv(tPM, 1, GL_FALSE, &mvp[0][0]);


    GLuint pointsVertexBuffer;
    glGenBuffers(1, &pointsVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
    do
    {
        // Clear the screen
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );   
        //glDrawArraysInstanced(GL_POINTS, 0, 2, max_point_number);
        glBindBuffer( GL_ARRAY_BUFFER, pointsVertexBuffer );
        glEnableClientState( GL_VERTEX_ARRAY );
        //glEnableClientState( GL_COLOR_ARRAY );
        glVertexPointer( 4, GL_FLOAT, sizeof( Point ), (void*)offsetof( Point, pos ) );
        //glColorPointer( 4, GL_FLOAT, sizeof( Vertex ), (void*)offsetof( Vertex, color ) );
        glDrawArrays( GL_POINTS, 0, max_point_number);
        glDisableClientState( GL_VERTEX_ARRAY );
        //glDisableClientState( GL_COLOR_ARRAY );
        glBindBuffer( GL_ARRAY_BUFFER, 0 );     // Swap buffers

        glfwSwapBuffers(window);
        glfwPollEvents();

    } // Check if the ESC key was pressed or the window was closed
    while( glfwWindowShouldClose(window) == 0 );
    return 0;
}

enter image description here

编辑:

我修改了代码,结果还是一样。

#include <vector>
#include <algorithm>
#include <iostream>`

#include <GL/glew.h>
#include <GLFW/glfw3.h>

GLFWwindow* window;

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/norm.hpp>

/* SHADERS */

/* Vertex Shader */
const char *VertexShaderSource=R"(
#version 330 core
layout(location=0) in vec2 pos;

uniform mat4 mvp;

int main(){
gl_Position = mvp*vec4(pos, 0.0,1.0);
}
)";
/* Fragment Shader*/
const char *FragmentShaderSource = R"(
#version 330 core
out vec4 color;

void main(){
    color =  vec4(1.0f);
}
)";
/* SHADERS END */

// Particle
struct Point{
    glm::vec2 pos;
    // Create random color in GPU
    // unsigned char r,g,b,a;
    float distance;
    float angle;
};
static const int max_point_number=1000;
Point PointContainer[max_point_number];

int main()
{
    // Start GLFW
    if(!glfwInit())
    {
        std::cout<<"Failed to start GLWF\n";
        getchar();
        return -1;
    }   

    glfwWindowHint(GLFW_SAMPLES, 4);
    //glfwWindowHint(GLFW_RESIZABLE,GL,FALSE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
    window = glfwCreateWindow(800, 600, "Rotating Points", NULL, NULL);
    if(window == NULL)
    {
        std::cout<<"Initialization of the window failed\n";
        getchar();
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Start GLEW;
    glewExperimental = true;
    if(glewInit() != GLEW_OK)
    {
        std::cout<<"Failed to start GLEW\n";
        getchar();
        return -1;
    }

    glfwPollEvents();

    glClearColor(.0f,0.0f,0.0f,0.0f); // Black is the new orange


    // Camera
    glm::mat4 Projection = glm::ortho(0.0f,800.0f, 0.0f,600.0f,-5.0f,5.0f); // In world coordinates
    glm::mat4 View = glm::lookAt(
    glm::vec3(0,0,1), // Camera is at (0,0,-1), in World Space
    glm::vec3(0,0,0), // and looks at the origin
    glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
    );
    glm::mat4 Model = glm::mat4(1.0f);
    glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around
    // No need to have depth test

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // Build and compile shaders
    // Vertex Shader
    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &VertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // Fragment Shader
    int fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &FragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // Link Shaders
    int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);
    // Delete Shaders after Linking
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    for(auto &p:PointContainer)
    {
        p.pos.x =(rand() % 800)*-1;
        p.pos.y =rand() % 600;
        std::cout<<p.pos.x<<" "<<p.pos.y<<"\n";
    }
    // Vertex Shader
    GLuint tPM = glGetUniformLocation(shaderProgram, "mvp");//mvp
    glUniformMatrix4fv(tPM, 1, GL_FALSE, &mvp[0][0]);


    GLuint pointsVertexBuffer;
    glGenBuffers(1, &pointsVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;

    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );
    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0 );
    glEnableVertexAttribArray( 0 );

    do
    {
        // Clear the screen
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );   

        glDrawArrays( GL_POINTS, 0, max_point_number);


        glfwSwapBuffers(window);
        glfwPollEvents();

    } // Check if the ESC key was pressed or the window was closed
    while( glfwWindowShouldClose(window) == 0 );
        return 0;
}

最佳答案

顶点着色器甚至无法编译。 ;out vec4 particle_color 之后丢失,main 的返回类型必须是 void 并且在最后gl_Position = mvp*vec4(pos, 0.0,1.0)); 有一个 ) 到很多。

我建议使用 Raw string literal :

const char *VertexShaderSource = R"(
#version 330 core
layout(location=0) in vec2 pos;
uniform mat4 mvp;

void main(){
    gl_Position = mvp*vec4(pos, 0.0,1.0);
}
)";

由于您使用核心配置文件 Context你必须使用 Vertex Array Object .例如:

GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;

GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0 );
glEnableVertexAttribArray( 0 );

do
{
    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );   

    glDrawArrays( GL_POINTS, 0, max_point_number);


    glfwSwapBuffers(window);
    glfwPollEvents();

} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );

你有一个从 (0, 0) 到 (600, 800) 的正交投影,所以 View 矩阵必须是

glm::mat4 View = glm::lookAt(
    glm::vec3(0,0,1), // Camera is at (0,0,-1), in World Space
    glm::vec3(0,0,0), // and looks at the origin
    glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
);

请注意,在您的 View 矩阵中,点绘制在视口(viewport)的左侧,因此您看不到它们。该点将绘制在从 (0, 0) 到 (-800, 600) 的矩形中。


改变片段着色器中点的颜色。绿色地面上几乎看不到红色:

const char *FragmentShaderSource = R"(
#version 330 core
out vec4 color;

void main(){
    color =  vec4(1.0f);
}
)";

我建议通过 glGetShaderiv 验证着色器是否成功编译.例如:

glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
    GLint logLen;
    glGetShaderiv( vertexShader, GL_INFO_LOG_LENGTH, &logLen );
    std::vector< char >log( logLen );
    GLsizei written;
    glGetShaderInfoLog( vertexShader, logLen, &written, log.data() );
    std::cout << "compile error:" << std::endl << log.data() << std::endl;
}

程序通过 glGetProgramiv 成功链接.例如:

glGetProgramiv( shaderProgram, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
    GLint logLen;
    glGetProgramiv( shaderProgram, GL_INFO_LOG_LENGTH, &logLen );
    std::vector< char >log( logLen );
    GLsizei written;
    glGetProgramInfoLog( shaderProgram, logLen, &written, log.data() );
    std::cout  << "link error:" << std::endl << log.data() << std::endl;
}

关于c++ - 试图绘制点云,只是 opengl 中心的一个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58348670/

相关文章:

c++ - 我可以创建一个 auto_ptr 数组吗?

database - 通过分布式数据库聚合作业优化网络带宽

java - JOGL 阴影贴图

java - 短路评估可以触发竞争条件吗?

c++ - 从数组中获取一个 block

c++ - 多少 STL 是太多了?

algorithm - 如果模式字符串中的所有字符都是唯一/不同的,那么 KMP 如何采用 O(m+n)

c# - 将 n xor 表达式翻译成 CNF?

c++ - 第一次尝试 - 图形程序

opengl - 如何使一个部分的颜色在 3D 对象上不同