Anonymous
Ошибка при попытке создать класс сетки в opengl
Сообщение
Anonymous » 09 янв 2025, 16:01
Я пытаюсь реализовать класс Mesh в своем приложении OpenGL.
Цель — создать простой ландшафт, применяя сетчатые текстуры и шейдеры. Однако текстуры отображаются неправильно; они выглядят искаженными или не отображаются должным образом.
Сначала я подозревал проблему с шейдером, но это кажется маловероятным, поскольку текстуры начали работать неправильно только после того, как я представил сетку. реализация класса.
изображение как должно быть изображение с ошибкой
вот мой код:
основной.cpp:
Код: Выделить всё
#include
#include
#include
#include
#include
#include "FastNoise.h"
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#define STB_IMAGE_IMPLEMENTATION
#include "Texture.h"
#include "Shader.h"
#define RENDER_DISTANCE 70
bool running = false;
#define CHUNK_SIZE 5
#include
#include "Mesh.h"
struct Chunk
{
int x, z;
};
struct Block {
float x, z, height;
};
glm::vec3 camPos = glm::vec3(0.0, 6.0, 10.0);
glm::vec3 camFront = glm::vec3(0.0, 0.0, -1.0);
glm::vec3 camUp = glm::vec3(0.0, 1.0, 0.0);
glm::mat4 model = glm::mat4(1.0f), view, proj;
glm::vec3 lightColor = glm::vec3(1.0, 1.0, 1.0);
glm::vec3 lightPos = glm::vec3(0.0, 100.0, 0.0);
FastNoise noise;
float lastX = 0, lastY = 0, yaw = -90.0f, pitch = 0;
bool firstMove = true;
std::vector chunks;
int SCR_WIDTH, SCR_HEIGHT;
Shader* shader;
Texture* texture;
unsigned int VAO, VBO, idTexture;
std::vector vertices ={
{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(0.0f, 0.0f) },
{glm::vec3(0.5f, -0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(1.0f, 0.0f) },
{glm::vec3(0.5f, 0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(1.0f, 1.0f)},
{glm::vec3(0.5f, 0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(1.0f, 1.0f)},
{glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(0.0f, 1.0f)},
{glm::vec3(-0.5f, -0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(0.0f, 0.0f)},
{glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f),glm::vec2(0.0f, 0.0f)},
{glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(1.0f, 1.0f)},
{glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f),glm::vec2(1.0f, 1.0f)},
{glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(0.0f, 0.0f)},
{glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 1.0f)},
{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f)},
{glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 1.0f)},
{glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) },
{glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(1.0f, 1.0f)},
{glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(0.0f, 0.0f)},
{glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
{glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 1.0f)},
{glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 0.0f)},
{glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.0f, 0.0f)},
{glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.0f, 1.0f)},
};
Mesh* mesh;
void loadTexture()
{
glGenTextures(1, &idTexture);
glBindTexture(GL_TEXTURE_2D, idTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, BPP;
const void* data = stbi_load("C:/Users/User/Downloads/terra.png", &width, &height, &BPP, 4);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
void mouse_callback(GLFWwindow* window, double xPos, double yPos)
{
if (firstMove)
{
lastX = xPos;
lastY = yPos;
firstMove = false;
}
float xOffset = xPos - lastX;
float yOffset = lastY - yPos;
lastX = xPos;
lastY = yPos;
float sensibility = 0.1f;
xOffset *= sensibility;
yOffset *= sensibility;
yaw += xOffset;
pitch += yOffset;
glm::vec3 front;
front.x = glm::cos(glm::radians(yaw)) * glm::cos(glm::radians(pitch));
front.y = glm::sin(glm::radians(pitch));
front.z = glm::sin(glm::radians(yaw)) * glm::cos(glm::radians(pitch));
camFront = glm::normalize(glm::radians(front));
}
void keyboardInput(GLFWwindow* window)
{
float camSpeed = 1.0f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
camPos += camFront * camSpeed;
}
else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
camPos -= camFront * camSpeed;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
{
camPos += glm::normalize(glm::cross(camFront, camUp)) * camSpeed;
}
else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
camPos -= glm::normalize(glm::cross(camFront, camUp)) * camSpeed;
}
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
exit(0);
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
{
camPos += camUp * camSpeed;
}
else if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
{
camPos -= camUp * camSpeed;
}
}
void generateChunksAroundCamera(std::vector& chunks)
{
float startX = (int)(camPos.x - RENDER_DISTANCE) / CHUNK_SIZE;
float startZ = (int)(camPos.z - RENDER_DISTANCE) / CHUNK_SIZE;
float endX = (int)(camPos.x + RENDER_DISTANCE) / CHUNK_SIZE;
float endZ = (int)(camPos.z + RENDER_DISTANCE) / CHUNK_SIZE;
chunks.clear();
for(int x = startX; x < endX; x++)
{
for(int z = startZ; z < endZ; z++)
{
Chunk chunk;
chunk.x = x;
chunk.z = z;
chunks.push_back(chunk);
}
}
}
bool isChunkVisible(Chunk& chunk)
{
float chunkCenterX = (chunk.x * CHUNK_SIZE) - CHUNK_SIZE / 2;
float chunkCenterZ = (chunk.z * CHUNK_SIZE) - CHUNK_SIZE / 2;
float distance = glm::distance(glm::vec2(camPos.x, camPos.z), glm::vec2(chunkCenterX, chunkCenterZ));
return distance < RENDER_DISTANCE;
}
void renderChunk(Chunk& chunk)
{
Block block;
for(int x = 0; x < CHUNK_SIZE; x++)
{
for(int z = 0; z < CHUNK_SIZE; z++)
{
block.x = chunk.x * CHUNK_SIZE + x;
block.z = chunk.z * CHUNK_SIZE + z;
block.height = noise.GetNoise(block.x * 0.01, block.z * 0.01) * 5.0f;
block.height = std::round(block.height);
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(block.x, block.height, block.z));
shader->um4("model", model);
glBindVertexArray(VAO);
mesh->Draw();
}
}
}
void renderTerrain(std::vector& chunks)
{
for(Chunk& chunk: chunks)
{
if(isChunkVisible(chunk))
{
renderChunk(chunk);
}
}
}
void update(GLFWwindow* window)
{
glfwGetWindowSize(window, &SCR_WIDTH, &SCR_HEIGHT);
glViewport(100, 0, SCR_WIDTH - 100, SCR_HEIGHT - 100);
view = glm::lookAt(camPos, camPos + camFront, camUp);
proj = glm::perspective(glm::radians(90.0f), (float)(SCR_WIDTH / SCR_HEIGHT), 0.1f, 100.0f);
keyboardInput(window);
glfwPollEvents();
if(running)
{
shader->um4("proj", proj);
shader->um4("view", view);
shader->um4("model", model);
texture->Active();
shader->u1i("material.diffuse", 0);
lightPos = glm::vec3(camPos.x - 100, lightPos.y, camPos.z - 100);
shader->u3f("light.position", lightPos);
}
else {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImVec2 btnSize = ImVec2(0, 0);
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(SCR_WIDTH, SCR_HEIGHT));
ImGui::Begin("Exemplo ImGui");
ImGui::SetCursorPos(ImVec2((SCR_WIDTH - btnSize.x) / 2, (SCR_HEIGHT - btnSize.y) / 2));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(30, 10));
if (ImGui::Button("Entrar")) {
running = true;
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
btnSize = ImGui::GetItemRectSize();
}
ImGui::SetCursorPos(ImVec2((SCR_WIDTH - btnSize.x) / 2, (SCR_HEIGHT - btnSize.y + 120) / 2));
if(ImGui::Button("Sair"))
{
exit(0);
}
ImGui::PopStyleVar();
ImGui::End();
}
}
void render(GLFWwindow* window)
{
if(running)
{
mesh->Draw();
generateChunksAroundCamera(chunks);
renderTerrain(chunks);
}
else
{
// Renderização da interface
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
}
int main()
{
glfwInit();
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
GLFWwindow* window = glfwCreateWindow(1, 1, "Default", nullptr, nullptr);
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetWindowPos(window, 1, 1);
glfwSetWindowSize(window, mode->width, mode->height);
mesh = new Mesh(vertices);
shader = new Shader("basic.shader");
texture = new Texture("C:/Users/User/Downloads/terra.png");
shader->u3f("light.position", lightPos);
shader->u3f("light.ambient", lightColor * 0.4f);
shader->u3f("light.diffuse", lightColor * 0.5f);
shader->u3f("light.specular", lightColor * 0.3f);
shader->u3f("material.specular", lightColor * 0.3f);
shader->u1f("material.shininess", 0.1);
shader->u3f("viewPos", camPos);
noise.SetNoiseType(FastNoise::Perlin);
noise.SetFrequency(1.5);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, 400, 400);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void)io;
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330 core");
while (!glfwWindowShouldClose(window))
{
update(window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
render(window);
glfwSwapBuffers(window);
}
return 0;
}
mesh.cpp:
Код: Выделить всё
#include "Mesh.h"
Mesh::Mesh(std::vector vertices, std::vector indices) : vertices(vertices), indices(indices)
{
setupMesh();
for(const auto& vertex: vertices)
{
if (vertex.texCoords != glm::vec2(0.0, 0.0) )
{
hasTexCoords = true;
break;
}
}
for(const auto& normal : vertices)
{
if (normal.normal != glm::vec3(0.0, 0.0, 0.0))
{
hasNormal = true;
break;
}
}
this->vertices = vertices;
this->indices = indices;
}
void Mesh::setupMesh()
{
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
if(!indices.empty())
{
glGenBuffers(1, &EBO);
}
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
if (!indices.empty())
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
}
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
if(hasNormal)
{
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));
}
if(hasTexCoords)
{
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoords));
}
}
void Mesh::Draw()
{
glBindVertexArray(VAO);
if(!indices.empty())
{
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
}else
{
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
}
glBindVertexArray(0);
}
the mesh.h:
#pragma once
#include
#include
#include
#include
#include
class Mesh
{
private:
unsigned int VBO, EBO, VAO;
bool hasTexCoords, hasNormal;
public:
struct Vertex {
glm::vec3 position;
glm::vec3 normal;
glm::vec2 texCoords;
};
std::vector vertices;
std::vector indices;
Mesh(std::vector vertices, std::vectorindices = {});
void setupMesh();
void Draw();
};
Я потратил несколько часов на рефакторинг кода, но ничего из того, что я сделал, не решило проблему, я не понимаю, что происходит
Подробнее здесь:
https://stackoverflow.com/questions/793 ... -in-opengl
1736427697
Anonymous
Я пытаюсь реализовать класс Mesh в своем приложении OpenGL. Цель — создать простой ландшафт, применяя сетчатые текстуры и шейдеры. Однако текстуры отображаются неправильно; они выглядят искаженными или не отображаются должным образом. Сначала я подозревал проблему с шейдером, но это кажется маловероятным, поскольку текстуры начали работать неправильно только после того, как я представил сетку. реализация класса. изображение как должно быть изображение с ошибкой вот мой код: основной.cpp: [code]#include #include #include #include #include #include "FastNoise.h" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #define STB_IMAGE_IMPLEMENTATION #include "Texture.h" #include "Shader.h" #define RENDER_DISTANCE 70 bool running = false; #define CHUNK_SIZE 5 #include #include "Mesh.h" struct Chunk { int x, z; }; struct Block { float x, z, height; }; glm::vec3 camPos = glm::vec3(0.0, 6.0, 10.0); glm::vec3 camFront = glm::vec3(0.0, 0.0, -1.0); glm::vec3 camUp = glm::vec3(0.0, 1.0, 0.0); glm::mat4 model = glm::mat4(1.0f), view, proj; glm::vec3 lightColor = glm::vec3(1.0, 1.0, 1.0); glm::vec3 lightPos = glm::vec3(0.0, 100.0, 0.0); FastNoise noise; float lastX = 0, lastY = 0, yaw = -90.0f, pitch = 0; bool firstMove = true; std::vector chunks; int SCR_WIDTH, SCR_HEIGHT; Shader* shader; Texture* texture; unsigned int VAO, VBO, idTexture; std::vector vertices ={ {glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(0.0f, 0.0f) }, {glm::vec3(0.5f, -0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(1.0f, 0.0f) }, {glm::vec3(0.5f, 0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(1.0f, 1.0f)}, {glm::vec3(0.5f, 0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(1.0f, 1.0f)}, {glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(0.0f, 1.0f)}, {glm::vec3(-0.5f, -0.5f, -0.5f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec2(0.0f, 0.0f)}, {glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f),glm::vec2(0.0f, 0.0f)}, {glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, {glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f),glm::vec2(1.0f, 1.0f)}, {glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(0.0f, 0.0f)}, {glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 1.0f)}, {glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f)}, {glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 1.0f)}, {glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) }, {glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(1.0f, 1.0f)}, {glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec2(0.0f, 0.0f)}, {glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, {glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 1.0f)}, {glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(1.0f, 0.0f)}, {glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.0f, 0.0f)}, {glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.0f, 1.0f)}, }; Mesh* mesh; void loadTexture() { glGenTextures(1, &idTexture); glBindTexture(GL_TEXTURE_2D, idTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, BPP; const void* data = stbi_load("C:/Users/User/Downloads/terra.png", &width, &height, &BPP, 4); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } void mouse_callback(GLFWwindow* window, double xPos, double yPos) { if (firstMove) { lastX = xPos; lastY = yPos; firstMove = false; } float xOffset = xPos - lastX; float yOffset = lastY - yPos; lastX = xPos; lastY = yPos; float sensibility = 0.1f; xOffset *= sensibility; yOffset *= sensibility; yaw += xOffset; pitch += yOffset; glm::vec3 front; front.x = glm::cos(glm::radians(yaw)) * glm::cos(glm::radians(pitch)); front.y = glm::sin(glm::radians(pitch)); front.z = glm::sin(glm::radians(yaw)) * glm::cos(glm::radians(pitch)); camFront = glm::normalize(glm::radians(front)); } void keyboardInput(GLFWwindow* window) { float camSpeed = 1.0f; if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { camPos += camFront * camSpeed; } else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { camPos -= camFront * camSpeed; } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { camPos += glm::normalize(glm::cross(camFront, camUp)) * camSpeed; } else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { camPos -= glm::normalize(glm::cross(camFront, camUp)) * camSpeed; } if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { exit(0); } if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { camPos += camUp * camSpeed; } else if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) { camPos -= camUp * camSpeed; } } void generateChunksAroundCamera(std::vector& chunks) { float startX = (int)(camPos.x - RENDER_DISTANCE) / CHUNK_SIZE; float startZ = (int)(camPos.z - RENDER_DISTANCE) / CHUNK_SIZE; float endX = (int)(camPos.x + RENDER_DISTANCE) / CHUNK_SIZE; float endZ = (int)(camPos.z + RENDER_DISTANCE) / CHUNK_SIZE; chunks.clear(); for(int x = startX; x < endX; x++) { for(int z = startZ; z < endZ; z++) { Chunk chunk; chunk.x = x; chunk.z = z; chunks.push_back(chunk); } } } bool isChunkVisible(Chunk& chunk) { float chunkCenterX = (chunk.x * CHUNK_SIZE) - CHUNK_SIZE / 2; float chunkCenterZ = (chunk.z * CHUNK_SIZE) - CHUNK_SIZE / 2; float distance = glm::distance(glm::vec2(camPos.x, camPos.z), glm::vec2(chunkCenterX, chunkCenterZ)); return distance < RENDER_DISTANCE; } void renderChunk(Chunk& chunk) { Block block; for(int x = 0; x < CHUNK_SIZE; x++) { for(int z = 0; z < CHUNK_SIZE; z++) { block.x = chunk.x * CHUNK_SIZE + x; block.z = chunk.z * CHUNK_SIZE + z; block.height = noise.GetNoise(block.x * 0.01, block.z * 0.01) * 5.0f; block.height = std::round(block.height); glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(block.x, block.height, block.z)); shader->um4("model", model); glBindVertexArray(VAO); mesh->Draw(); } } } void renderTerrain(std::vector& chunks) { for(Chunk& chunk: chunks) { if(isChunkVisible(chunk)) { renderChunk(chunk); } } } void update(GLFWwindow* window) { glfwGetWindowSize(window, &SCR_WIDTH, &SCR_HEIGHT); glViewport(100, 0, SCR_WIDTH - 100, SCR_HEIGHT - 100); view = glm::lookAt(camPos, camPos + camFront, camUp); proj = glm::perspective(glm::radians(90.0f), (float)(SCR_WIDTH / SCR_HEIGHT), 0.1f, 100.0f); keyboardInput(window); glfwPollEvents(); if(running) { shader->um4("proj", proj); shader->um4("view", view); shader->um4("model", model); texture->Active(); shader->u1i("material.diffuse", 0); lightPos = glm::vec3(camPos.x - 100, lightPos.y, camPos.z - 100); shader->u3f("light.position", lightPos); } else { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); ImVec2 btnSize = ImVec2(0, 0); ImGui::SetNextWindowPos(ImVec2(0, 0)); ImGui::SetNextWindowSize(ImVec2(SCR_WIDTH, SCR_HEIGHT)); ImGui::Begin("Exemplo ImGui"); ImGui::SetCursorPos(ImVec2((SCR_WIDTH - btnSize.x) / 2, (SCR_HEIGHT - btnSize.y) / 2)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(30, 10)); if (ImGui::Button("Entrar")) { running = true; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); btnSize = ImGui::GetItemRectSize(); } ImGui::SetCursorPos(ImVec2((SCR_WIDTH - btnSize.x) / 2, (SCR_HEIGHT - btnSize.y + 120) / 2)); if(ImGui::Button("Sair")) { exit(0); } ImGui::PopStyleVar(); ImGui::End(); } } void render(GLFWwindow* window) { if(running) { mesh->Draw(); generateChunksAroundCamera(chunks); renderTerrain(chunks); } else { // Renderização da interface ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); } } int main() { glfwInit(); GLFWmonitor* monitor = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(monitor); GLFWwindow* window = glfwCreateWindow(1, 1, "Default", nullptr, nullptr); glfwMakeContextCurrent(window); gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); glfwSetCursorPosCallback(window, mouse_callback); glfwSetWindowPos(window, 1, 1); glfwSetWindowSize(window, mode->width, mode->height); mesh = new Mesh(vertices); shader = new Shader("basic.shader"); texture = new Texture("C:/Users/User/Downloads/terra.png"); shader->u3f("light.position", lightPos); shader->u3f("light.ambient", lightColor * 0.4f); shader->u3f("light.diffuse", lightColor * 0.5f); shader->u3f("light.specular", lightColor * 0.3f); shader->u3f("material.specular", lightColor * 0.3f); shader->u1f("material.shininess", 0.1); shader->u3f("viewPos", camPos); noise.SetNoiseType(FastNoise::Perlin); noise.SetFrequency(1.5); glEnable(GL_DEPTH_TEST); glViewport(0, 0, 400, 400); IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 330 core"); while (!glfwWindowShouldClose(window)) { update(window); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); render(window); glfwSwapBuffers(window); } return 0; } [/code] mesh.cpp: [code]#include "Mesh.h" Mesh::Mesh(std::vector vertices, std::vector indices) : vertices(vertices), indices(indices) { setupMesh(); for(const auto& vertex: vertices) { if (vertex.texCoords != glm::vec2(0.0, 0.0) ) { hasTexCoords = true; break; } } for(const auto& normal : vertices) { if (normal.normal != glm::vec3(0.0, 0.0, 0.0)) { hasNormal = true; break; } } this->vertices = vertices; this->indices = indices; } void Mesh::setupMesh() { glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glGenBuffers(1, &VBO); if(!indices.empty()) { glGenBuffers(1, &EBO); } glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); if (!indices.empty()) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); } glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); if(hasNormal) { glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal)); } if(hasTexCoords) { glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoords)); } } void Mesh::Draw() { glBindVertexArray(VAO); if(!indices.empty()) { glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); }else { glDrawArrays(GL_TRIANGLES, 0, vertices.size()); } glBindVertexArray(0); } the mesh.h: #pragma once #include #include #include #include #include class Mesh { private: unsigned int VBO, EBO, VAO; bool hasTexCoords, hasNormal; public: struct Vertex { glm::vec3 position; glm::vec3 normal; glm::vec2 texCoords; }; std::vector vertices; std::vector indices; Mesh(std::vector vertices, std::vectorindices = {}); void setupMesh(); void Draw(); }; [/code] Я потратил несколько часов на рефакторинг кода, но ничего из того, что я сделал, не решило проблему, я не понимаю, что происходит Подробнее здесь: [url]https://stackoverflow.com/questions/79341928/error-when-trying-to-create-a-mesh-class-in-opengl[/url]