OpenGL多个纹理与多个着色程序
OpenGL multiple texture with multiple shader programs
我试图做一个场景在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);
}
}
从第0个纹理单元开始,将N个纹理绑定到从GL_TEXTURE0开始的N个纹理单元。然后在shader程序中绑定从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);
}
当我这样做时,第一个球体(地球)中的所有纹理都被成功加载,但在第二个球体中,我没有得到任何纹理,我只得到一个黑色球体。我的问题是,我应该如何管理多个纹理和采样器,如果我使用不同的着色器程序为每个对象?
从我看到你绑定所有纹理作为单独的纹理单元
- 错误
- 如果你有100个对象,每个对象有4个纹理…
- 我强烈怀疑你有400个纹理单位可供使用
- 纹理ID (name)不是纹理单元
我这样渲染空间体:
-
第一次渲染天体几何
-
我有特定的纹理单位为特定的任务
// 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
-
查看该链接中的着色器(它也是为太阳系可视化编写的)…
- 在每次渲染前只绑定单个主体的纹理
- (在你绑定着色器之后)
- 不改变纹理单位含义(如果你这样做,shader将如何知道哪个纹理是什么?)
-
-
第二个渲染通道添加了大气
- 没有使用纹理
- 它只是一个透明的四边形覆盖整个屏幕
-
这里有一些关于您的任务的见解
[edit1] multitextures的例子
// 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);
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- 模板元程序查找相似的连续类型名称
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 使用程序生成来创建磁盘,但纹理无法正常工作
- 3D 纹理大小会影响程序输出,而不会引发错误
- GPU驱动程序中的Vulkan纹理映射不准确
- opengl驱动程序在有限的VRAM中处理大型纹理阵列的效果如何
- 我是否应该确保在退出程序之前销毁 SDL 2.0 对象(渲染器、窗口、纹理等)
- SFML中的程序纹理
- OpenGL多个纹理与多个着色程序
- 为什么我的纹理渲染不正确在我的OpenGL应用程序
- 是否有可能在程序执行过程中通过函数加载精灵、纹理和音乐?