Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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
Opengl 每个对象的GLSL一致_Opengl_Glsl_Shader_Fragment Shader_Openscenegraph - Fatal编程技术网

Opengl 每个对象的GLSL一致

Opengl 每个对象的GLSL一致,opengl,glsl,shader,fragment-shader,openscenegraph,Opengl,Glsl,Shader,Fragment Shader,Openscenegraph,目前,我在GLSL着色器上处理制服时遇到问题。如果场景中只有一个对象,则制服的效果与我预期的一样。但是,对于多个对象,统一不是针对每个对象设置的,换句话说,最后一个统一用于表示所有场景对象 我如何处理这个问题?遵循我的C++代码: void addSimpleObject(osg::ref_ptr<osg::Group> root, osg::Vec3 position, float radius, float myUniform) { osg::ref_ptr<os

目前,我在GLSL着色器上处理制服时遇到问题。如果场景中只有一个对象,则制服的效果与我预期的一样。但是,对于多个对象,统一不是针对每个对象设置的,换句话说,最后一个统一用于表示所有场景对象

我如何处理这个问题?遵循我的C++代码:

void addSimpleObject(osg::ref_ptr<osg::Group> root, osg::Vec3 position, float radius, float myUniform) {

    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(position, radius)));
    root->addChild(geode);
    root->getChild(0)->asGeode()->addDrawable(geode->getDrawable(0));

    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
    stateset->addUniform(new osg::Uniform("myUniform", myUniform));
    root->setStateSet(stateset);
}


osg::ref_ptr<osg::Group> root = new osg::Group();
addSimpleObject(root, osg::Vec3(-3.0,  2.5, -10), 2, 0.5);
addSimpleObject(root, osg::Vec3( 3.0,  2.5, -10), 2, 1.5);
addSimpleObject(root, osg::Vec3( 0.0, -2.5, -10), 2, 1.0);
和片段着色器:

#version 130

in vec3 pos;
in vec3 normal;

uniform float myUniform;

void main() {
    vec3 normNormal;

    normNormal = normalize(normal);

    if (myUniform > 0)
        normNormal = min(normNormal * myUniform, 1.0);

    ...
}

制服绑定到着色器程序,而不是“对象”。 如果对所有对象使用相同的程序,则必须在绘制对象之前设置统一

您将
osg::StateSet
绑定到场景图的根节点。 如果每个可绘制图形的统一变量值发生变化,则必须添加 一个独立的
osg::StateSet
到每个
osg::Drawable
节点

调整您的方法
addSimpleObject
如下:

void addSimpleObject(osg::ref_ptr<osg::Group> root, osg::Vec3 position, float radius, float myUniform) {

    // create the drawable 
    osg::ref_ptr<osg::Drawable> drawable = new osg::ShapeDrawable(new osg::Sphere(position, radius))

    // crate the stateset and add the uniform
    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
    stateset->addUniform(new osg::Uniform("myUniform", myUniform));

    // add the stateset tor the drawable
    drawable->setStateSet(stateset);

    if (root->getNumChildren() == 0) {
        osg::ref_ptr<osg::Geode> geode = new osg::Geode();
        root->addChild(geode);
    }
    root->getChild(0)->asGeode()->addDrawable(drawable);
} 
void addSimpleObject(osg::ref_ptr根、osg::Vec3位置、浮点半径、浮点myUniform){
//创建可绘制的
osg::ref_ptr drawable=新osg::ShapeDrawable(新osg::球体(位置、半径))
//将状态集装箱并添加制服
osg::refptr stateset=新osg::stateset();
stateset->addUniform(新osg::Uniform(“myUniform”,myUniform));
//将状态集添加到可绘制的
可绘制->设置状态集(状态集);
if(root->getNumChildren()==0){
osg::ref_ptr geode=新osg::geode();
root->addChild(geode);
}
root->getChild(0)->asGeode()->addDrawable(drawable);
} 

制服绑定到着色器程序,而不是“对象”。如果对所有对象使用相同的程序,yoa必须在绘制对象之前设置统一。您好@rabbi76,谢谢您的回答。你能给我举个例子吗?我如何修改我的程序来解决你的建议?嗨@rabbi76,我测试了你的解决方案,它成功了!谢谢!
void addSimpleObject(osg::ref_ptr<osg::Group> root, osg::Vec3 position, float radius, float myUniform) {

    // create the drawable 
    osg::ref_ptr<osg::Drawable> drawable = new osg::ShapeDrawable(new osg::Sphere(position, radius))

    // crate the stateset and add the uniform
    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
    stateset->addUniform(new osg::Uniform("myUniform", myUniform));

    // add the stateset tor the drawable
    drawable->setStateSet(stateset);

    if (root->getNumChildren() == 0) {
        osg::ref_ptr<osg::Geode> geode = new osg::Geode();
        root->addChild(geode);
    }
    root->getChild(0)->asGeode()->addDrawable(drawable);
}