[英]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.