简体   繁体   English

OpenGL上传贴图很慢

[英]Uploading texture is very slow in OpenGL

I have a list of images that I want to display, using OpenGL textures (Android NDK/SDK).我有一个要显示的图像列表,使用 OpenGL 纹理 (Android NDK/SDK)。 I have put the image data into an array to be used by glTexImage2D .我已将图像数据放入一个数组中以供glTexImage2D使用。 I initialized the variables and ran glDeleteTextures(1, &hedy);我初始化变量并运行glDeleteTextures(1, &hedy); for uploading and displaying each image.用于上传和显示每张图片。

Everything is OK but it works slowly (2.5ms for loading a texture).一切正常,但运行缓慢(加载纹理需要 2.5 毫秒)。 How can I improve the app's performance?如何提高应用程序的性能? Can I upload the image data into GPU memory once and use it many times?可以把图片数据上传到GPU memory一次,多次使用吗? Do you have any solution or recommendation to display images at high speed?您对高速显示图像有什么解决方案或建议吗?

glGenTextures(1, &hedy);  
glBindTexture(GL_TEXTURE_2D, hedy);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glPixelStorei(GL_PACK_ALIGNMENT, 1);  
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);  
glBindTexture(GL_TEXTURE_2D, 0);

You only need to Generate a Texture once.您只需要生成一次纹理。

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}

Now we can keep using texture with the call现在我们可以继续在调用中使用纹理

glBindTexture(GL_TEXTURE_2D, texture);

The same goes for shaders we need to compile them only once.着色器也是如此,我们只需要编译一次。

Shader loadShaderFromFile(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile)
{
    // 1. Retrieve the vertex/fragment source code from filePath
    std::string vertexCode;
    std::string fragmentCode;
    std::string geometryCode;
    try
    {
        // Open files
        std::ifstream vertexShaderFile(vShaderFile);
        std::ifstream fragmentShaderFile(fShaderFile);
        std::stringstream vShaderStream, fShaderStream;
        // Read file's buffer contents into streams
        vShaderStream << vertexShaderFile.rdbuf();
        fShaderStream << fragmentShaderFile.rdbuf();
        // close file handlers
        vertexShaderFile.close();
        fragmentShaderFile.close();
        // Convert stream into string
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
        // If geometry shader path is present, also load a geometry shader
        if (gShaderFile != nullptr)
        {
            std::ifstream geometryShaderFile(gShaderFile);
            std::stringstream gShaderStream;
            gShaderStream << geometryShaderFile.rdbuf();
            geometryShaderFile.close();
            geometryCode = gShaderStream.str();
        }
    }
    catch (std::exception e)
    {
        QMessageBox message;
        message.setText("ERROR::SHADER: Failed to read shader files");
        message.exec();

    }
    const GLchar *vShaderCode = vertexCode.c_str();
    const GLchar *fShaderCode = fragmentCode.c_str();
    const GLchar *gShaderCode = geometryCode.c_str();
    // 2. Now create shader object from source code
    Shader shader;
    shader.Compile(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr);
    return shader;
}

Now you can keep bind this shader when you need it with this call.现在您可以在需要时通过此调用保持绑定此着色器。

glUseProgram(ShaderId);

Generate all the textures and Compile the shaders when your application initializes and than keep using them.当您的应用程序初始化并继续使用它们时,生成所有纹理并编译着色器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM