[英]Terrain will draw alone, but won't render with other objects in scene OpenGL
编辑:想通了,但如果有人对我的代码有一些指示,将不胜感激! 太疯狂了,这么小的错误会花费你几天的时间。
在 OpenGL 中创建地形后,我注意到当场景中有其他对象时它会拒绝渲染,但如果我自己渲染,它渲染得很好。 我有一个单独的 VAO、VBO、IBO,所以我不确定为什么会这样。
这是我的地形课
#include "Terrain.h"
#include <stb_image.h>
unsigned int terrainTexture;
Texture texture(terrainTexture);
Terrain::Terrain(const char* imagePath) {
this->imagePath = imagePath;
this->TERRAIN_WIDTH = 20.0f;
this->TERRAIN_LENGTH = 20.0f;
this->shader = new Shader("..\\..\\src\\shaders\\terrVert.glsl",
"..\\..\\src\\shaders\\terrFrag.glsl");
terrainTexture = texture.loadTexture("..\\..\\res\\rock.jpg");
}
void Terrain::setUniforms(glm::mat4 model, glm::mat4 view, glm::mat4 projection) {
GLint modelLoc = glGetUniformLocation(shader->Program, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
GLint viewLoc = glGetUniformLocation(shader->Program, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
GLint projLoc = glGetUniformLocation(shader->Program, "projection");
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
}
void Terrain::setupTerrain() {
createVertexData();
createIndexData();
checkHeightMapLoaded();
//generate & bind vao
glGenVertexArrays(1, &terrVao);
glBindVertexArray(terrVao);
//specify vertex buffer
glGenBuffers(1, &vbufferid);
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices.front(),
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//specify index buffer
glGenBuffers(1, &ibufferid);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibufferid);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(short), &indices.front(),
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Terrain::draw() {
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (GLvoid*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibufferid);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, terrainTexture);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
}
void Terrain::createVertexData() {
unsigned char* image = stbi_load(imagePath, &heightMapWidth, &heightMapHeight,
&numOfChannels, 0);
cout << "\033[31mHeight Map width: \033[0m" << heightMapWidth << "\033[31m Height Map
height: \033[0m" << heightMapHeight << endl << endl;
for (int row = 0; row < heightMapHeight; row++) {
for (int col = 0; col < heightMapWidth; col++) {
unsigned char* pixelOffset = image + (row + heightMapHeight * col) *
numOfChannels;
unsigned char red = pixelOffset[0];
float x = ((float)col / (float)(heightMapWidth - 1)) /*- 0.5f*/;
float y = (float)red / 255.0;
float z = ((float)row / (float)(heightMapHeight - 1)) /*- 0.5f*/;
vertices.push_back(glm::vec3(x, y, z));
}
}
delete image;
}
void Terrain::createIndexData() {
for (int row = 0; row < heightMapHeight - 1; row++) {
for (int col = 0; col < heightMapWidth - 1; col++) {
int TL = (int)(row * heightMapWidth + col);
int TR = (int)(row * heightMapWidth + col + 1);
int BL = (int)((row + 1) * heightMapWidth + col);
int BR = (int)((row + 1) * heightMapWidth + col + 1);
indices.push_back(TL);
indices.push_back(BL);
indices.push_back(TR);
indices.push_back(TR);
indices.push_back(BL);
indices.push_back(BR);
}
}
}
void Terrain::checkHeightMapLoaded() {
if (heightMapWidth == 0 || heightMapHeight == 0) {
cout << "\033[31mHeight Map failed to load\033[0m\n";
return;
}
else if (heightMapWidth > 255 || heightMapHeight > 255) {
cout << "\033[31mHEIGHT MAP SIZE GREATER THAN 255x255! RESIZE DOWN!!\033[0m" << endl;
}
else {
cout << "\033[32mHeight Map loaded successfully\033[0m\n";
}
}
glm::mat4 Terrain::getModelMatrix() {
glm::mat4 terrModel = glm::scale(glm::mat4(1.0f), glm::vec3(this->TERRAIN_WIDTH, 1.0f,
this->TERRAIN_LENGTH));
return terrModel;
}
Shader* Terrain::getShader() {
return shader;
}
Terrain::~Terrain()
{
glDeleteBuffers(1, &vbufferid);
glDeleteBuffers(1, &ibufferid);
delete shader;
}
就在我的主循环之前,我调用了terrain.setupTerrain(); 并在循环中生病了
terrain.getShader()->use();
terrain.setUniforms(terrain.getModelMatrix(), view, projection);
terrain.draw();
我认为我设置 VAO、VBO 和 IBO 的方式有问题,但经过几天的尝试,我完全不知道是什么原因造成的。
发帖5分钟后搞定
对于遇到同样问题的人来说,我在设置地形时绑定了 vao,但我没有在每个绘制调用中绑定它。
添加
glBindVertexArray(terrVao);
在 draw 方法中修复了问题!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.