【问题标题】:OpenGL rendering multiple textures on spritesOpenGL在精灵上渲染多个纹理
【发布时间】:2016-01-18 03:01:37
【问题描述】:

我正在从 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);

Engine::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;

渲染批处理():

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);
}

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

【问题讨论】:

  • 您可以使用 glBendTexture() 在 OpenGL 中切换纹理。第二个参数应该是你从 glGenTextures 得到的纹理的 ID。您的示例未显示调用的位置。
  • 也许texture atlas 会是更好的方法。
  • @moof2k,我正在关注的教程将所有内容都转储到 Engine::ResourceManager::GetTexture(filePath, 0, 0, 32, 4); 调用的 LoadImage 函数中,我将该代码添加到我原来的问题中。

标签: c++ opengl graphics 2d


【解决方案1】:

通常当不是所有的纹理都显示出来时,这可能与通过 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 中的那些替换了你的 evilbatch.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。

【讨论】:

  • 我使用了你的调试代码,但没有一个纹理 ID 为 0(耶!)。我还进入了图像加载器功能并计算了图像是否已加载。一切都正确加载,但 OpenGL 没有使用正确的纹理进行绘制...
  • 有什么理由使用静态 Engine::GLTexture 纹理吗?这意味着纹理对象对整个应用程序都是全局的,我认为这不是您需要的,对吗?
  • 我的错 :P 不过还是没区别,我还是好好看看sprite批处理类中的draw函数看看有没有bug。
  • 如果您的代码像在 github 上一样公开托管,那么我可以尝试查看您的代码。您在上面发布的代码应该可以按预期正常工作,因此错误可能在其他地方。
  • 这是一个link 。我很确定问题将在“Bengine”文件夹(主引擎)中。射击游戏(“AsteroidShooter”)基本上使用它的功能。随意下载解决方案(如果您这样做,只需在 MainGame.h 中注释掉第 5-7 行以禁用内存泄漏检查器)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多