c++ - 渲染 openGL 纹理 : Class function causes rendering to fail

标签 c++ class opengl rendering sdl

我正在开发一个菜单系统,它允许我将“父级”应用于对象。我有一个呈现字体的 CLabel 类。我有一个 CEditBox 类,它有一个指向基 CControl 类的指针,它们都是其中的一部分。然后,我声明一个指向 CControl 对象的指针,并将其指向 CEditBox 构造函数中的 CLabel

据我所知,这一切都设置正确。我为什么这么说?这个函数:

void CControl::RenderChildren() {
    for( int i = 0; i < Children.size(); i++ ) {


        //Children[i]->X(Children[i]->X()+_X); //offset child _X with parent's _X
        //Children[i]->Y(Children[i]->Y()+_Y); //offset child _Y with parent's _Y

        Children[i]->OnRender();
    }
}

将呈现编辑框,它将呈现带有标签偏移量的标签(_X,_Y 它们是 CControl 的成员)。由于它们位于 0,0,因此它在左上角呈现文本。

现在,如果我取消对这两行的注释并使用以下函数,则文本不会呈现。

void CControl::RenderChildren() {
    for( int i = 0; i < Children.size(); i++ ) {


        Children[i]->X(Children[i]->X()+_X); //offset child _X with parent's _X
        Children[i]->Y(Children[i]->Y()+_Y); //offset child _Y with parent's _Y

        Children[i]->OnRender();
    }
}

我已经使用 exit(variable) 调用来专门测试这些值,并且可以告诉您几件事。 _X 和 _Y 是为 child 设置的。 Parent 在所需位置呈现,因此它不会影响父级的 _X,_Y 值。

接下来,让我们看看我调用的函数:

void CControl::X(int x) {                                           
    //      Set Component's X coordinate
    _X = x;
    //if(Pappy != NULL) { 
    //  _X = _X + Pappy->X(); 
    //}
}

void CControl::Y(int y) {                                           
    //      Set Component's Y coordinate
    _Y = y;
    //if(Pappy != NULL) {
    //  _Y = _Y + Pappy->Y();
    //}
}

不要介意注释掉的行,那些是因为我要检查它是否是某个东西的子项并修改 _X 和 _Y 函数中的偏移量,但意识到不担心可能更有效关于它并且只在渲染子项时应用偏移量(因此我上面的原始功能)。简单地说,这些函数只是将传递的整数设置为当前偏移量。

然后是函数的读取版本:

int CControl::X() {                                             
    //      Get Component's X coordinate
    //if(Pappy != NULL) return _X - Pappy->X();
    return _X;
}

int CControl::Y() {                                             
    //      Get Component's Y coordinate
    //if(Pappy != NULL) return _Y - Pappy->Y();
    return _Y;
}

也只是返回值,我无法弄清楚这两行

    Children[i]->X(Children[i]->X()+_X); //offset child _X with parent's _X
    Children[i]->Y(Children[i]->Y()+_Y); //offset child _Y with parent's _Y

导致渲染失败。

查看我的 CLabel::OnRender() 函数,我也无法检测到问题。

void CLabel::OnRender() {

    if(Visible) {
        SDL_Surface* Surf_Text; 
        Surf_Text = Font.BlendedUTF8Surface();
        Text_Font.OnLoad(Surf_Text);
        Text_Font.RenderQuad(_X,_Y);
        SDL_FreeSurface(Surf_Text);
    }
}

我知道密码在这里输入。我在 if 语句中使用了 exit(variable)。我已经测试了 Surf_Text->wSurf_Text->h 并且知道文本正在渲染,因为有或没有偏移线的 SDL_Surface 值没有区别并且它渲染在一个场合而不是另一个。此外,我在此函数中测试了 _X 和 _Y,只是为了验证它们确实在正确的位置呈现。他们是。

这意味着渲染顺序可能有问题,但在这个函数中,如果我将 Text_Font.RenderQuad(_X,_Y); 替换为 Text_Font.RenderQuad(_X+dX) ,_Y+dY); 其中 dX 和 dY 只是在应用父偏移量后应该是的整数值,文本呈现得很好。所以我能想到的一切,我都测试过了。我不明白为什么这两条偏移线会破坏渲染。

    Children[i]->X(Children[i]->X()+_X); //offset child _X with parent's _X
    Children[i]->Y(Children[i]->Y()+_Y); //offset child _Y with parent's _Y

[已解决]

是的。去想了一会儿。

第 1 帧

Children[i]->X(Children[i]->X()+_X) // will be 100 and exit correctly.

框架 2)

Children[i]->X(Children[i]->X()+_X) // will be 200 if I don't add the exit

等...

实现了我的功能:

void CControl::RenderChildren() {
    for( int i = 0; i < Children.size(); i++ ) {


        Children[i]->X(Children[i]->X()+_X); //offset child _X with parent's _X
        Children[i]->Y(Children[i]->Y()+_Y); //offset child _Y with parent's _Y

        Children[i]->OnRender();

        Children[i]->X(Children[i]->X()-_X);
        Children[i]->Y(Children[i]->Y()-_Y);
    }
}

完美呈现。希望我没有浪费任何人的时间。

[解决方案 2]

阅读所选答案后,我选择重写函数以在渲染期间应用偏移。我只是在渲染 child 之前计算偏移量,如下所示:

void CControl::RenderChildren() {
    for( int i = 0; i < Children.size(); i++ ) {

        int xOff, yOff;
        xOff = yOff = 0;                                //Initialize offsets

        CControl * Kin = this;                          //Pointer to current parent
        while( Kin != NULL ) {                          //Until there is no more parent container repeat
            xOff = Kin->X() + xOff;                     //Add X of Parent to the current X offset total.
            yOff = Kin->Y() + yOff;                     //Add Y of Parent to the current Y offset total.
            Kin = Kin->GetParent();                     //Get next parent.  
        }

        Children[i]->OnRender(xOff,yOff);               //Render based on parental induced offset location

    }
}

最佳答案

我确实在一秒钟内看到了你的错误。所以你没有浪费任何人的时间(除了你自己的 ;))。无论如何这样做:

void CControl::RenderChildren() {
    for( int i = 0; i < Children.size(); i++ ) {


        Children[i]->X(Children[i]->X()+_X); //offset child _X with parent's _X
        Children[i]->Y(Children[i]->Y()+_Y); //offset child _Y with parent's _Y

        Children[i]->OnRender();

        Children[i]->X(Children[i]->X()-_X);
        Children[i]->Y(Children[i]->Y()-_Y);
    }
}

不是最优的。在您的情况下,您在遇到任何问题时使用整数。 但是假设你有一次决定使用 float :

问题是,对 float 进行的每个操作都会产生舍入误差。迭代地进行(就像你的情况一样)可能会在一个稳定点收敛数字,或者它可能会稍微发散。作为一般规则,您应该尽量减少单个 float “流动”的操作。从数学上讲,您的序言和序言可能看起来像是彼此的倒数。实际上,在精度有限的计算机上,它们不是。

长话短说:

您应该稍微更改 CControl::OnRender 以将偏移作为参数,以便在渲染时就地应用偏移添加。不要介意额外的工作。如果这确实是一个问题,请使用分析器来确定真正的瓶颈。不要在设计界面时考虑到某些关于性能的“想法”。过早的优化是不好的。


顺便说一句:在 StackOverflow 上,标记自行解决问题的规范方法是将您自己的解决方案写入您自己问题的答案中,然后将其标记为已接受。

关于c++ - 渲染 openGL 纹理 : Class function causes rendering to fail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17256301/

相关文章:

c - glDisplayFunc(RenderScene) 回调是否会在以下代码中导致竞争条件?

c++ - 如何从调试控制台中删除额外的详细信息?

c++ - g++ ld 共享库错误代码:: block

c++ - 在类中构建结构

swift - 访问子类时不能在类型错误的实例上使用静态成员

c++ - glMatrixMode(GL_PROJECTION) 和 glMatrixMode(GL_MODELVIEW) 的区别

c++ - 如何禁用然后启用 MessageBox 中的重试按钮?

c++ - 涵盖boost::trim并接受std::vector <std::string>的函数

php - 未找到“Michelf\Markdown”类

opengl - OpenGL中glTexSubImage和glTexImage函数的区别