草庐IT

c++ - OpenGL 加载将最后加载的纹理绑定(bind)到所有 textureID

coder 2024-02-20 原文

所以我的问题是我尝试在启动时加载多个纹理,然后存储所有 ID,以便我可以绑定(bind)它们以使用它们。现在我知道 ID 已正确存储,因为我可以调试它并在分配和使用中看到 ID 是相同的。对于每个绑定(bind),它都使用我加载的最后一个纹理。这是我的代码:

GLuint TextureLoader::LoadTexture (const char* fileName,Material& material,int width,int height) {
    GLuint textureImage;

    FILE* textureFile;
    textureFile = fopen(fileName, "rb");
    unsigned char* imageData;

    if (textureFile == NULL) {
        return 0;
    }
    imageData = (unsigned char*)malloc(width * height * 3);
    char header[54];
    fread(header,1,54,textureFile);
    fread(imageData, width * height * 3, 1, textureFile);

    fclose(textureFile);

    for (int i = 0; i < width * height; ++i) {
        int nextIndex = i * 3;
        unsigned char a = imageData[nextIndex];
        unsigned char b = imageData[nextIndex+2];

        imageData[nextIndex] = b;
        imageData[nextIndex+2] = a;
    }

    glEnable(GL_TEXTURE_2D);
    glGenTextures( 1, &textureImage );
    glBindTexture( GL_TEXTURE_2D, textureImage );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
    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);


    /*glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );


    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, imageData );*/
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, imageData);
    glGenerateMipmap(GL_TEXTURE_2D);
    free(imageData);

    return textureImage;
}

这是我对这段代码的用法:

if (showTexture) {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, material.texture);
}

这是我的加载调用:

green1.texture = TextureLoader::LoadTexture("/Users/hewitt/Desktop/OpenGLImages/face6.bmp",green1, 256, 256);

然后我就用:

glTexCoord2f(1.0f,0.0f);

根据它变化的角来绘制。这正确地绘制了一个纹理,它只是重复纹理,即使我 glBind 一个不同的数字也是如此。

非常感谢任何帮助。

编辑------------

glBegin(mode);
            Spatial::Vector3 normal = Mesh::calculateNormal (pointGroup);
            glNormal3f(normal.x, normal.y, normal.z);

            Material material = mesh.getMaterial();

            if (showTexture) {
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, material.texture);
            }

            int counter = 0;
            for (Spatial::Vector3 point : pointGroup) {
                if (showTexture == false) {
                    Material::Colour colour = material.getColour();
                    glColor3f(colour.red, colour.green, colour.blue);
                } else {

                    if (counter == 0) {
                        glTexCoord2f(1.0f,0.0f);
                    } else if (counter == 1) {
                        glTexCoord2f(1.0f,1.0f);
                    } else if (counter == 2) {
                        glTexCoord2f(0.0f,1.0f);
                    } else if (counter == 3) {
                        glTexCoord2f(0.0f,0.0f);
                    }
                }

                glVertex3f(point.x,point.y,point.z);
                counter ++;
            }


            glEnd();

最佳答案

您不能在 glBeginglEnd 之间调用 glEnableglBindTexture。您必须在 glBegin 之前绑定(bind)您的纹理。事实上,您可以在 glBeginglEnd 之间调用的 OpenGL 函数集仅限于那些传输顶点属性(glVertexglColorglTexCoord 等...)。

请注意,立即模式 API(即 glBegin/glEnd 和 friend )是遗留的,已弃用 10 多年。我建议您切换到现代 OpenGL 管道,它会为您解决很多问题。

关于c++ - OpenGL 加载将最后加载的纹理绑定(bind)到所有 textureID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41117070/

有关c++ - OpenGL 加载将最后加载的纹理绑定(bind)到所有 textureID的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  5. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  6. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  7. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  8. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  9. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  10. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

随机推荐