【问题标题】:SDL2 and OpenGL stencil buffer don't workSDL2 和 OpenGL 模板缓冲区不起作用
【发布时间】:2015-09-27 16:57:24
【问题描述】:

我正在用 c++ 和 sdl、opengl 编写游戏,但模板缓冲区似乎没有运行。我已经使用这个参数启用了模板位:

SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);

代码如下:

glColorMask(0,0,0,0);

_stencil.EnableStencil();
_stencil.StencilFunc(GL_ALWAYS,2,1);
_stencil.StencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);

glBegin(GL_QUADS);
    glColor3f(0,0,0);
    glVertex2f(_size.x,_size.y);
    glVertex2f(_size.x,_size.y + _size.h);
    glVertex2f(_size.x + _size.w,_size.y + _size.h);
    glVertex2f(_size.x + _size.w,_size.y);
    glColor3f(1,1,1);
glEnd();

glColorMask(1,1,1,1);

_stencil.StencilFunc(GL_EQUAL,2,1);
_stencil.StencilOp(GL_KEEP,GL_KEEP,GL_KEEP);

for(int i = 0; i < _list.size(); i++)
    {

        _name.SetFontData(_fdata);
        _name.SetLabelText(_list[i].name);
        _name.SetLabelColor(255,255,255,255);

        _icon.BindTexture( _list[i].data.ID, _list[i].data.width , _list[i].data.height );

        /*if( _offsety + (_listGui.GetTextureInfo().height*i) + (_spacing_y*i) >= _size.y && _offsety + ((_listGui.GetTextureInfo().height*i)+_listGui.GetTextureInfo().height) + (_spacing_y*i) <= (_size.y + _size.h) )
        {*/
            if(i == 0)
            {
                _listGui.Render( _size.x + _spacing_x, _offsety );
                _name.RenderText(_size.x + _spacing_x + _label.x,_offsety + _label.y );
                _icon.Render( _size.x + (_iconPos.y + _spacing_x) , _offsety + _iconPos.y );
            }
            else
            {
                _listGui.Render( _size.x + _spacing_x, ( _offsety + ((_listGui.GetTextureInfo().height*i) + (_spacing_y*i) ) ) );

                _name.RenderText(
                        _size.x + ( _label.x + _spacing_x), 
                        _offsety + ( (_listGui.GetTextureInfo().height*i) + (_spacing_y*i) ) + _label.y 
                    );

                _icon.Render( 
                    _size.x + (_iconPos.x + _spacing_x),
                    _offsety + _iconPos.y + (_listGui.GetTextureInfo().height*i) + (_spacing_y*i) 
                    );

            }
        /*}*/
    }_stencil.DisableStencil();

_stencil.EnableStencil() 等于 glEnable(GL_STENCIL_TEST); _stencil.DisableStecil() 也一样;

【问题讨论】:

  • SDL_GL_STENCIL_SIZE 以位为单位获取模板缓冲区的大小(典型值为 8,默认为 0)。

标签: c++ opengl sdl sdl-2


【解决方案1】:

您在模板状态中使用的掩码值有问题:

_stencil.StencilFunc(GL_ALWAYS,2,1);

glStencilFunc() 的第三个参数给出的掩码值在应用任何模板逻辑之前与参考值和模板缓冲区中的值进行“与”运算。在规范的语言中:

mask 的 s 最低有效位与引用和存储的模板值进行按位与运算,得到的屏蔽值是那些参与由 func 控制的比较的值。

使用您使用的值,掩码值 1 将与参考值 2 进行“与”运算,从而产生有效的参考值 0。二进制:

2     = 00000010
1     = 00000001
2 & 1 = 00000000

这意味着在第一遍中,您渲染的所有内容的模板值都设置为 0,这是您已经清除它们的值。在第二遍中,将值与 0 进行比较,所有像素都将通过模板测试。

要使其正常工作,您需要更改参考值或掩码,以便参考值不会被屏蔽。参考值为 2 时,掩码可能是 2 或 3 之类的值。但如果您只想使用一位模板,最简单的方法是使用 1 作为参考值。

这意味着您将第一次传递的设置更改为:

_stencil.EnableStencil();
_stencil.StencilFunc(GL_ALWAYS, 1, 1);
_stencil.StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

第二次传递到:

_stencil.StencilFunc(GL_EQUAL, 1, 1);
_stencil.StencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

【讨论】:

  • 感谢您的回答,我非常有用!但问题仍然存在,我似乎必须重写这段代码以获得干净的副本。
猜你喜欢
  • 2012-01-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多