gpt4 book ai didi

c++ - 网格类中损坏的顶点数据

转载 作者:行者123 更新时间:2023-12-04 13:05:15 25 4
gpt4 key购买 nike

我正在尝试实现模型加载,但我遇到了一个问题。当我出于某种原因尝试绘制网格(为了测试目的而手工编写的单个纹理四边形)时,与第一个顶点关联的重复数据将传递给顶点着色器
( RenderDoc screen )。
这是一个使用我的类的精简版本的示例,它仍然表现出这种行为:

#define TEST_MESH

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <vector>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);

struct Vertex {
float position[3];
float color[3];
};

class Mesh {
public:
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices);
~Mesh();
Mesh(const Mesh&) = delete;
Mesh& operator=(const Mesh&) = delete;
Mesh(Mesh&& other);
Mesh& operator=(Mesh&& other);

void Draw(unsigned int program_id);

std::vector<Vertex> m_Vertices;
std::vector<unsigned int> m_Indices;

private:
unsigned int m_VAO, m_VBO, m_EBO;

void Setup();
void Release();
};

int main() {
//GLFW INIT
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

//GLFW Window setup
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Mesh Test", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}

glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

//GLAD INIT
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}

//Shader setup:
const char* vertex = "#version 460 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aCol;\n"
"out vec3 vColor;\n"
"void main() {\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
" vColor = aCol;\n"
"}\0";

const char* fragment = "#version 460 core\n"
"in vec3 vColor;\n"
"out vec4 FragColor;\n"
"void main() {\n"
" FragColor = vec4(vColor, 1.0);\n"
"}\0";

unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertex, NULL);
glCompileShader(vertexShader);

unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragment, NULL);
glCompileShader(fragmentShader);

unsigned int program;
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

//Data:
float floats[24] = {
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f,-0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f,-0.5f, 0.0f, 1.0f, 1.0f ,0.0f };

unsigned int uints[6] = { 0, 1, 2, 2, 3, 0 };

#ifdef TEST_MESH
//Mesh assembly
std::vector<Vertex> vertices;
for (int i = 0; i < 4; i++)
vertices.push_back(Vertex{ floats[6 * i], floats[6 * i + 1], floats[6 * i + 2],
floats[6 * i + 3], floats[6 * i + 4], floats[6 * i + 5] });

std::vector<unsigned int> indices{ 0, 1, 2, 2, 3, 0 };

Mesh mesh(vertices, indices);
#else
unsigned int VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(floats), &floats[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uints), &uints[0], GL_STATIC_DRAW);

//Positions
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//Colors
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
#endif

//Render loop
while (!glfwWindowShouldClose(window)) {
processInput(window);

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

#ifdef TEST_MESH
mesh.Draw(program);
#else
glUseProgram(program);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
#endif
glfwSwapBuffers(window);
glfwPollEvents();
}

glfwTerminate();
return 0;
}

Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices) {
m_Vertices = vertices;
m_Indices = indices;

Setup();
}

Mesh::Mesh(Mesh&& other)
: m_VAO(other.m_VAO), m_VBO(other.m_VBO), m_EBO(other.m_EBO)
, m_Vertices(other.m_Vertices), m_Indices(other.m_Indices)
{
other.m_VAO = 0;
other.m_VBO = 0;
other.m_EBO = 0;
}

Mesh& Mesh::operator=(Mesh&& other) {
if (this != &other) {
Release();

std::swap(m_VAO, other.m_VAO);
std::swap(m_VBO, other.m_VBO);
std::swap(m_EBO, other.m_EBO);

m_Vertices = other.m_Vertices;
m_Indices = other.m_Indices;
}
return *this;
}

Mesh::~Mesh() {
Release();
}

void Mesh::Release() {
glDeleteVertexArrays(1, &m_VAO);
glDeleteBuffers(1, &m_VBO);
glDeleteBuffers(1, &m_EBO);
}

void Mesh::Setup() {
glGenVertexArrays(1, &m_VAO);
glGenBuffers(1, &m_VBO);
glGenBuffers(1, &m_EBO);

glBindVertexArray(m_VAO);

glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW);

//Positions
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
//Colors
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, color));
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

void Mesh::Draw(unsigned int program_id) {
glUseProgram(program_id);

glBindVertexArray(m_VAO);
glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0);
}

void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}

void framebuffer_size_callback(GLFWwindow* window, int width, int
height) {
glViewport(0, 0, width, height);
}

最佳答案

在您的 Mesh::Setup你最后有这一行:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
这会解除您的 EBO 与 VAO 的绑定(bind)。您的实现似乎将未定义的读取视为零,因此您看到的只是复制了六次的第 0 个顶点。
绑定(bind) EBO 后,您无需解除绑定(bind)。
(注意:另一方面,解除绑定(bind) GL_ARRAY_BUFFER 是可以的。这是因为在您调用任何 *Pointer 函数时,VBO 已附加到 VAO,而不是在您将其绑定(bind)到 GL_ARRAY_BUFFER 时.)
(注意:由于您使用的是最新的 OpenGL 版本,我强烈建议您使用直接状态访问 (DSA) 功能。在这种情况下,您可以将 EBO 与
glVertexArrayElementBuffer(m_VAO, m_EBO);
调用,我认为这会使错误更加明显。见 a quick reference of VAO state and the recommended functions to use to manipulate it .)

关于c++ - 网格类中损坏的顶点数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69825043/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com