首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenGL ES glTexImage2D优化

OpenGL ES glTexImage2D优化
EN

Stack Overflow用户
提问于 2018-02-02 02:36:13
回答 2查看 200关注 0票数 0

我的任务是展示几张照片。我将其实现为一个类来创建几个实例。每个实例表示一幅图片。它编译着色器,设置两个三角形,并在构造函数中加载图片数据。主程序创建实例,然后转到循环,为每个实例切换prigramid和调用render()方法。

代码语言:javascript
复制
while(true)
    for (uint g = 0; g < pictures.size(); g++){
        glUseProgram(pictures[g]->ProgramId);
        pictures[g]->render();
    }

它运行良好,并显示图片,但我不喜欢它。可以做得更好。

下面是类的部分代码

代码语言:javascript
复制
Picture::Picture(picPosition* pPosition, const char * fileName)
:BasePicture(pPosition)
{
    pos = glGetAttribLocation(ProgramId, "position");
    uv = glGetAttribLocation(ProgramId, "texture_vert");

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glGenBuffers(1, &uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);

    int n;
    textureData = stbi_load(fileName, &picWidth, &picHeight, &n, STBI_rgb_alpha);
    TextureID  = glGetUniformLocation(ProgramId, "myTextureSampler");
    glBindTexture(GL_TEXTURE_2D, TextureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glActiveTexture(GL_TEXTURE0);

    glDepthMask(GL_FALSE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    //calculating the vertex matrix using MVP calculated in parent class
    for (int i = 0; i < 6; i++)
        ModeledVerts.push_back(MVP * verts[i]);
    v = glm::value_ptr(ModeledVerts[0]);
}

Picture::~Picture()
{
    stbi_image_free(textureData);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &uvbuffer);
}

void Picture::render()
{
    glBufferData(GL_ARRAY_BUFFER, 96, v, GL_STATIC_DRAW);
    glVertexAttribPointer(pos, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*) 0);
    glEnableVertexAttribArray(pos);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesUV), verticesUV, GL_STATIC_DRAW);
    glVertexAttribPointer(uv, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) 0);
    glEnableVertexAttribArray(uv);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);

    glDrawArrays(GL_TRIANGLES, 0, 6);
}

我经常使用代码来使render()函数尽可能轻巧,但我不能使它比现在更轻。

最大的问题是每次发送textureData (glTexImage2D)。数据从未改变过。我试图将其移动到构造函数,但在本例中,所有图片对象都显示了最新加载的图片。看起来有一个实例覆盖了之前上传的纹理数据。我正在寻找一种方法来加载图片数据一次在构造函数,而不是每次它呈现。看起来这方面的OpenGL API中有一些东西,但我还不知道。

另一个改进是获取从render()中设置的顶点数据。数据永远不会变。但它并不像glTexImage2D在render()中调用的那样重要。

你能给我指一下OpenGL API来分离着色器的数据吗?或者告诉我我做错了什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-30 05:48:47

回答我自己的问题。解决办法是使用地图集地图。软件生成包含所有图片的地图集,上传一次(glTexImage2D)并对每幅图片使用坐标。这大大提高了性能,因为只调用了一次glTexImage2D。

票数 0
EN

Stack Overflow用户

发布于 2018-02-02 03:15:26

你说:

它运行良好,并显示图片,但我不喜欢它。可以做得更好。

从设计的角度来看,我认为这可能对你有帮助。

将打开、读取和解析纹理数据的图像文件的功能与实际的纹理结构或类分开。这将是一个示例伪代码:

代码语言:javascript
复制
struct Texture {
    unsigned int width;
    unsigned int height;
    bool         hasTransparency; 

    GLint id; // ID that is used by OpenGL to setActive, bind, and pass to shaders as either a uniform or sampler2D.
    std::string filenameAndPath; // Keep this filename associated with texture so you can prevent trying to reload the same file over and over.
    GLuchar*  data; // the actual color - pixel texture data. 
}

// This function will handle the opening and reading in of the texture data
// it would return back the ID value generated by OpenGL which will also be
// stored into the texture struct. The texture struct is returned by reference so that it can be populated with data.
GLuint loadTexture( const char* filenameAndPath, Texture& texture, /*loading parameters & flags*/ ) {
    // Check to see if file exists or is already loaded
    if ( fileanameAndPath already exists ) {
        // get the existing ID from the already loaded texture
        // and just return that. 
    } else {
        // Try to open the new file for reading.

        // parse the data for general purposes that will support
        // your application. You can simply use `stbi_load` as it is a fairly
        // decent third party library.

        // Check the internal formatting of how the data is stored
        // Compression, pixel orientation etc.

        // configure the data to your needs (color format),
        // (flipping the pixels either horizontally, vertically or both),

        // now copy the actual pixel data into your buffer.

        // close the file handle

        // save all the information into your struct

        // return the ID value that was generated by OpenGL
    }
}

render loop之前的主引擎代码中,您需要从文件中加载纹理,然后您可以在需要的地方使用这个纹理对象。最后,在渲染循环中,您需要将纹理设置为活动,并将它们绑定到渲染目标,并将它们传递给您的着色器。在某些情况下,您可能希望将它们设置为active &在render loop之前绑定它们,具体取决于要实现的shader-technique类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48574909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档