尝试在 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;
}
编辑:
我修改了代码,结果还是一样。
#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/