OpenGL在sprite上渲染多个纹理

时间:2016-01-18 03:01:37

标签: c++ opengl graphics 2d

我正在从MakingGamesWithBen系列中学习OpenGL,而我正在根据他的引擎编写一个简单的小行星射击游戏。我创建了一个随机定位小行星精灵的系统,并从std :: vector中选择一个随机纹理路径,并将路径传递给小行星构造函数。绘制精灵,但只绘制第一个纹理。我已经读过我需要绑定这些纹理并切换到相关的glActiveTexture;从我下面的代码中,我将如何解决这个问题?

void MainGame::prepareTextures() {
//compile shaders and get Texlocations
initShaders("Shaders/background.vert", "Shaders/background.frag");
GLint TexLoc = _colorProgram.getUniformLocation("bgTexture");
glActiveTexture(GL_TEXTURE0);
}

m_asteroid [I] .draw():

glm::vec4 uv(0.0f, 0.0f, 1.0f, 1.0f);

//convert m_imgNum to string and remove trailing zeros
std::string strImgNum = std::to_string(m_imgNum);
strImgNum.erase(strImgNum.find_last_not_of('0') + 1, std::string::npos);
//construct filpath
std::string filePath = m_dir + strImgNum + ".png";

static Engine::GLTexture texture = Engine::ResourceManager::GetTexture(filePath, 0, 0, 32, 4);

Engine::Color color;
color.r = 255;
color.g = 255;
color.b = 255;
color.a = 255;

glm::vec4 posAndSize = glm::vec4(m_posX, m_posY, m_width, m_height);

spriteBatch.Draw(posAndSize, uv, texture.id, 0.0f, color);

引擎::的ResourceManager :: GetTexture():

GLTexture texture = {};

    unsigned char *imageData = stbi_load(filePath.c_str(), &width, &height, &bitsPerPixel, forceBpp);

    if (imageData == NULL) {
        const char *loadError = stbi_failure_reason();
        stbi_image_free(imageData);
        fatalError(loadError);
    }

    //Create the texture in opengl
    glGenTextures(1, &(texture.id));

    glBindTexture(GL_TEXTURE_2D, texture.id);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

    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_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    glGenerateMipmap(GL_TEXTURE_2D);

    stbi_image_free(imageData);

    glBindTexture(GL_TEXTURE_2D, 0);

    texture.width = width;
    texture.height = height;

    return texture;

renderbatch():

void SpriteBatch::renderbatch() {

    glBindVertexArray(m_vao);

    for (unsigned int i = 0; i < m_renderBatches.size(); i++) {
        glBindTexture(GL_TEXTURE_2D, m_renderBatches[i].texture);

        glDrawArrays(GL_TRIANGLES, m_renderBatches[i].offset, m_renderBatches[i].numVertices);
    }

    glBindVertexArray(0);
}

我可以提供可能需要的任何其他代码/说明!

1 个答案:

答案 0 :(得分:0)

通常当并非所有纹理都出现时,它可能与通过OpenGL上传纹理有关。你可以尝试通过检查你的纹理是否都正确上传来调试这个;

std::uint32_t textureId = Engine::ResourceManager::GetTexture(filePath, 0, 0, 32, 4).id;
std::cout << "texture id, should not be 0 :" << textureId << std::endl;

如果您不是从具有OpenGL上下文的线程调用此函数,则可能发生这种情况。

编辑: 有没有理由在这里使用静态对象?

static Engine::GLTexture texture = Engine::ResourceManager::GetTexture(filePath, 0, 0, 32, 4);

尝试将其更改为

Engine::GLTexture texture = Engine::ResourceManager::GetTexture(filePath, 0, 0, 32, 4);

更新:  我刚用Ben的github替换你的spitebatch.cpp / .h并在你的MainGame.cpp中进行了一个简单的测试;

m_spriteBatch.begin();

asteroids.draw(m_spriteBatch);
ship.draw(m_spriteBatch);

m_spriteBatch.end();
m_spriteBatch.renderBatch();

_colorProgram.unuse();
_window.SwapBuffers();

我可以正确渲染两个上传的纹理;

HTH。