Ошибка при попытке создать класс сетки в openglC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Ошибка при попытке создать класс сетки в opengl

Сообщение Anonymous »

Я пытаюсь реализовать класс 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»