簡體   English   中英

地形將單獨繪制,但不會與場景 OpenGL 中的其他對象一起渲染

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM