Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带有多个着色器程序的OpenGL多重纹理_C++_Opengl_Opengl Es_Glsl_Shader - Fatal编程技术网

C++ 带有多个着色器程序的OpenGL多重纹理

C++ 带有多个着色器程序的OpenGL多重纹理,c++,opengl,opengl-es,glsl,shader,C++,Opengl,Opengl Es,Glsl,Shader,我试图在OpenGL中制作一个场景,从太空模拟地球。我现在有两个球体,一个是地球,另一个稍大一点的是云层。地球和云球体对象有自己的着色器程序来保持简单。地球着色器程序采用4种纹理(白天、夜晚、specmap和normalmap),云着色器程序采用2种纹理(cloudmap和normalmap)。我有一个对象类,它有一个渲染函数,在该函数中我使用以下逻辑: //bind the current object's texture for (GLuint i = 0; i < texIDs.si

我试图在OpenGL中制作一个场景,从太空模拟地球。我现在有两个球体,一个是地球,另一个稍大一点的是云层。地球和云球体对象有自己的着色器程序来保持简单。地球着色器程序采用4种纹理(白天、夜晚、specmap和normalmap),云着色器程序采用2种纹理(cloudmap和normalmap)。我有一个对象类,它有一个渲染函数,在该函数中我使用以下逻辑:

//bind the current object's texture
for (GLuint i = 0; i < texIDs.size(); i++){
    glActiveTexture(GL_TEXTURE0 + i);
    if (cubemap)
        glBindTexture(GL_TEXTURE_CUBE_MAP, texIDs[i]);
    else
        glBindTexture(GL_TEXTURE_2D, texIDs[i]);
}
    if (samplers.size()){
    for (GLuint i = 0; i < samplers.size(); i++){
        glUniform1i(glGetUniformLocation(program, samplers[i]), i);
    }
}
//绑定当前对象的纹理
对于(GLuint i=0;i
它从第0个纹理单元开始,并将N个纹理绑定到从GL_TEXTURE0开始的N个纹理单元。然后在着色器程序中从0到N绑定采样器。采样器由我在加载纹理时提供:

void Object::loadTexture(const char* filename, const GLchar* sampler){
    int texID;
    texID = SOIL_load_OGL_texture(filename, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS);
    if(texID == 0){
        cerr << "SOIL error: " << SOIL_last_result();
    }
    cout << filename << " Tex ID: " << texID << endl;
    texIDs.push_back(texID);
    samplers.push_back(sampler);
    //glBindTexture(GL_TEXTURE_2D, texID);
}
void Object::loadTexture(常量字符*文件名,常量GLchar*采样器){
int-texID;
texID=土壤加载纹理(文件名、土壤加载自动、土壤创建新ID、土壤标志mipmap、土壤标志纹理重复);
如果(texID==0){

cerr据我所知,您将所有纹理绑定为单独的纹理单元

  • 这是错误的
  • 如果你有100个对象,每个都有4个纹理
  • 我强烈怀疑你是否有400个纹理单位可供你使用
  • 纹理ID(名称)不是纹理单位…
我像这样渲染空间体:

    • 我有特定任务的特定纹理单位

      // texture units:            
      // 0 - texture0 map 2D rgba (surface)
      // 1 - texture1 map 2D rgba (clouds blend)
      // 2 - normal map 2D xyz (normal/bump mapping)
      // 3 - specular map 2D i (reflection shininess)
      // 4 - light map 2D rgb rgb (night lights)
      // 5 - enviroment/skybox cube map 3D rgb
      
    • 请参见该链接中的着色器(它也是为太阳系可视化而编写的)

    • 在每次渲染单个实体之前,仅绑定该实体的纹理
    • (绑定着色器后)
    • 不要更改纹理单元的含义(如果您这样做,着色器如何知道哪个纹理是什么?)
    • 没有使用纹理
    • 它只是一个覆盖整个屏幕的透明四边形
  • [edit1]多文本的示例

    // init shader once per render all geometries
    GLint prog_id;      // shader program ID;
    GLint txrskybox;    // global skybox environment cube map
    GLint id;
    glUseProgram(prog_id);
    id=glGetUniformLocation(prog_id,"txr_texture0"); glUniform1i(id,0); //uniform sampler2D   txr_texture0;
    id=glGetUniformLocation(prog_id,"txr_texture1"); glUniform1i(id,1); //uniform sampler2D   txr_texture1;
    id=glGetUniformLocation(prog_id,"txr_normal");   glUniform1i(id,2); //uniform sampler2D   txr_normal;
    id=glGetUniformLocation(prog_id,"txr_specular"); glUniform1i(id,3); //uniform sampler2D   txr_specular;
    id=glGetUniformLocation(prog_id,"txr_light");    glUniform1i(id,4); //uniform sampler2D   txr_light;
    id=glGetUniformLocation(prog_id,"txr_skybox");   glUniform1i(id,5); //uniform samplerCube txr_skybox;
    
    // add here all uniforms you need ...
    glActiveTexture(GL_TEXTURE0+5); glEnable(GL_TEXTURE_CUBE_MAP); glBindTexture(GL_TEXTURE_CUBE_MAP,txrskybox);
    
    for (i=0;i<all_objects;i++)
        {
        // add here all uniforms you need ...
    
        // pass textures once per any object render
        // obj::(GLint) txr0,txr1,txrnor,txrspec,txrlight; // object local textures
        glActiveTexture(GL_TEXTURE0+0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,obj[i].txr0);
        glActiveTexture(GL_TEXTURE0+1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,obj[i].txr1);
        glActiveTexture(GL_TEXTURE0+2); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,obj[i].txrnor);
        glActiveTexture(GL_TEXTURE0+3); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,obj[i].txrspec);
        glActiveTexture(GL_TEXTURE0+4); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,obj[i].txrlight);
        // here render the geometry of obj[i]
        }
    
    // unbind textures and shaders
    glActiveTexture(GL_TEXTURE0+5); glBindTexture(GL_TEXTURE_CUBE_MAP,0); glDisable(GL_TEXTURE_CUBE_MAP);
    glActiveTexture(GL_TEXTURE0+4); glBindTexture(GL_TEXTURE_2D,0); glDisable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0+3); glBindTexture(GL_TEXTURE_2D,0); glDisable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0+2); glBindTexture(GL_TEXTURE_2D,0); glDisable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0+1); glBindTexture(GL_TEXTURE_2D,0); glDisable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE0+0); glBindTexture(GL_TEXTURE_2D,0); glDisable(GL_TEXTURE_2D); // unit0 at last so it stays active ...
    glUseProgram(0);
    
    //每次渲染所有几何体时初始化着色器一次
    闪烁程序id;//着色器程序id;
    闪烁txrskybox;//全局skybox环境立方体贴图
    闪烁id;
    glUseProgram(程序id);
    id=glGetUniformLocation(prog_id,“txr_texture0”);glUniform1i(id,0);//统一采样器2D txr_texture0;
    id=glGetUniformLocation(prog_id,“txr_texture1”);glUniform1i(id,1);//统一采样器2D txr_texture1;
    id=glGetUniformLocation(prog_id,“txr_normal”);glUniform1i(id,2);//统一采样器2D txr_normal;
    id=glGetUniformLocation(prog_id,“txr_镜面反射”);glUniform1i(id,3);//统一采样器2D txr_镜面反射;
    id=glGetUniformLocation(prog_id,“txr_light”);glUniform1i(id,4);//统一采样器2D txr_light;
    id=glGetUniformLocation(prog_id,“txr_skybox”);glUniform1i(id,5);//统一采样器立方体txr_skybox;
    //在这里添加您需要的所有制服。。。
    glActiveTexture(GL_纹理0+5);glEnable(GL_纹理_立方体_贴图);glBindTexture(GL_纹理_立方体_贴图,txrskybox);
    
    对于(i=0;你能演示如何使用GLASTeTeTeXION和GLBDIN纹理调用绑定纹理到C++的着色器吗?@ PSLAYR89+添加示例,我今天晚些时候再试试。结果我还在研究它,我在上面,我意识到了一些我不确定的东西。你读到纹理的顺序是什么?从file matter?据我所知,它不应该。只是想有人确认…@pslayer89它不重要唯一的区别是,如果你按顺序添加纹理,那么不同的顺序有时在OpenGL中意味着不同的
    TextureID
    ,但这与渲染本身无关,除非你不通过<代码>纹理ID
    但改为一些索引(但这毕竟是代码中的bug…)