OpenGL L 系统渲染

发布于 2024-07-24 09:34:36 字数 3664 浏览 3 评论 0原文

我已经让基本的 L-System 正常工作,并决定尝试优化应用程序的渲染。 此前,我使用开关盒和绘图循环遍历 L 系统的整个字符串。 更好的是,我将向您展示我在做什么:

for(unsigned int stringLoop = 0; stringLoop < _buildString.length(); stringLoop++)
{
    
        switch(_buildString.at(stringLoop))
        {
        case'X':
            //Do Nothing
            //X is there just to facilitate the Curve of the plant
            break;
        case'F':

            _prevState = _currState;
            _currState.position += _currState.direction * stdBranchLength; 
            //Set the previous state to the current state
            _graphics.SetColour3f(0.0f, 1.0f, 0.0f);
            
            _graphics.Begin(OGLFlags::LINE_STRIP);
                _graphics.Vertex3f(_prevState.position.X(), _prevState.position.Y(), _prevState.position.Z());
                _graphics.Vertex3f(_currState.position.X(), _currState.position.Y(), _currState.position.Z());
            _graphics.End();

            break;
        case'[':
            _prevStack.push(_currState);
            break;
        case']':
            _prevState = _currState;
            _currState = _prevStack.top();
            _prevStack.pop();               
            break;
        case'-':
            
            _currState.direction = _currState.direction.RotatedAboutZ(-(ROTATION) * Math::DegreesToRadians);

            break;
        case'+':
            _currState.direction = _currState.direction.RotatedAboutZ(ROTATION * Math::DegreesToRadians);

            break;
        };

}

我删除了所有这些,因为我实际上是在每一帧解析树,我更改了这个循环,以便它将所有顶点保存在标准向量中。

    for(unsigned int stringLoop = 0; stringLoop < _buildString.length(); stringLoop++)
{
    
        switch(_buildString.at(stringLoop))
        {
        case'X':
            break;
        case'F':

            //_prevState = _currState;
            _currState.position += _currState.direction * stdBranchLength;
            _vertexVector.push_back(_currState.position);
        
            break;
        case'[':
            _prevStack.push(_currState);
            break;
        case']':
            _currState = _prevStack.top();
            _prevStack.pop();               
            break;
        case'-':            
            _currState.direction = _currState.direction.RotatedAboutZ(-(ROTATION) * Math::DegreesToRadians);
            break;
        case'+':
            _currState.direction = _currState.direction.RotatedAboutZ(ROTATION * Math::DegreesToRadians);
            break;
        };
}

现在我更改了渲染循环,因此我直接从向量数组中读取。

    DesignPatterns::Facades::OpenGLFacade _graphics = DesignPatterns::Facades::openGLFacade::Instance();

_graphics.Begin(OGLFlags::LINE_STRIP);
    for(unsigned int i = 0; i < _vertexVector.size(); i++)
    {
        _graphics.Vertex3f(_vertexVector.at(i).X(), _vertexVector.at(i).Y(), _vertexVector.at(i).Z());
    }
_graphics.End();

现在我的问题是,当我使用向量数组并使用 Line Stip 时,我会得到额外的伪影。

第一个图像是原始渲染,即未优化的渲染,然后第二个是运行速度更快的较新渲染,第三个是龙曲线的渲染,它不使用像前两个那样的推送和弹出(我很漂亮)确保推入和弹出是问题所在)。

我这里存储顶点的逻辑有问题吗,还是因为我使用的是线带? 我只想使用线条,但它根本不起作用,它最终看起来更像是线条点画。

也对这篇文章的长度感到抱歉。

替代文本 http://img197.imageshack.us/img197/8030/bettera.jpg< /a> 替代文本 http://img23.imageshack.us/img23/3924/buggyrender.jpg< /a> 替代文本 http://img8.imageshack.us/img8/627/dragoncurve.jpg< /a>

I have gotten my basic L-System working and I decided to try and optimize the rendering of the application. Previously I was looping through the whole string of the L-System with a switch case and drawing. Better yet I will show you what I was doing:

for(unsigned int stringLoop = 0; stringLoop < _buildString.length(); stringLoop++)
{
    
        switch(_buildString.at(stringLoop))
        {
        case'X':
            //Do Nothing
            //X is there just to facilitate the Curve of the plant
            break;
        case'F':

            _prevState = _currState;
            _currState.position += _currState.direction * stdBranchLength; 
            //Set the previous state to the current state
            _graphics.SetColour3f(0.0f, 1.0f, 0.0f);
            
            _graphics.Begin(OGLFlags::LINE_STRIP);
                _graphics.Vertex3f(_prevState.position.X(), _prevState.position.Y(), _prevState.position.Z());
                _graphics.Vertex3f(_currState.position.X(), _currState.position.Y(), _currState.position.Z());
            _graphics.End();

            break;
        case'[':
            _prevStack.push(_currState);
            break;
        case']':
            _prevState = _currState;
            _currState = _prevStack.top();
            _prevStack.pop();               
            break;
        case'-':
            
            _currState.direction = _currState.direction.RotatedAboutZ(-(ROTATION) * Math::DegreesToRadians);

            break;
        case'+':
            _currState.direction = _currState.direction.RotatedAboutZ(ROTATION * Math::DegreesToRadians);

            break;
        };

}

I removed all of this because I was literally resolving the tree every single frame, I changed this loop so that it would save all of the verticies in a std vector.

    for(unsigned int stringLoop = 0; stringLoop < _buildString.length(); stringLoop++)
{
    
        switch(_buildString.at(stringLoop))
        {
        case'X':
            break;
        case'F':

            //_prevState = _currState;
            _currState.position += _currState.direction * stdBranchLength;
            _vertexVector.push_back(_currState.position);
        
            break;
        case'[':
            _prevStack.push(_currState);
            break;
        case']':
            _currState = _prevStack.top();
            _prevStack.pop();               
            break;
        case'-':            
            _currState.direction = _currState.direction.RotatedAboutZ(-(ROTATION) * Math::DegreesToRadians);
            break;
        case'+':
            _currState.direction = _currState.direction.RotatedAboutZ(ROTATION * Math::DegreesToRadians);
            break;
        };
}

Now I changed my render loop so I just read straight from the vector array.

    DesignPatterns::Facades::OpenGLFacade _graphics = DesignPatterns::Facades::openGLFacade::Instance();

_graphics.Begin(OGLFlags::LINE_STRIP);
    for(unsigned int i = 0; i < _vertexVector.size(); i++)
    {
        _graphics.Vertex3f(_vertexVector.at(i).X(), _vertexVector.at(i).Y(), _vertexVector.at(i).Z());
    }
_graphics.End();

Now my problem is that when I am using a vector array and I use Line Stip, I get extra artifact.

The first image is the original render that is the unoptimized one, then the second is the newer render which runs faster, and the thirds is a render of a dragon curve which uses no push and pops like the first two are using (I am pretty sure the push and pop is where the problems are coming in).

Is the problem with my logic here of storing verticies, or is it because I am using a line strip? I would just use lines, but it doesn't really work at all, it ends up looking more of a line_stipple.

Also sorry about the length of this post.

alt text http://img197.imageshack.us/img197/8030/bettera.jpg
alt text http://img23.imageshack.us/img23/3924/buggyrender.jpg
alt text http://img8.imageshack.us/img8/627/dragoncurve.jpg

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

2024-07-31 09:34:36

您会得到这些额外的行,因为您使用的是 LINE_STRIP。

在“F”情况下,将线的两个端点推入向量中(就像您最初所做的那样)。

_vertexVector.push_back(_prevState.position);
_vertexVector.push_back(_currState.position);

当你绘制时,使用 LINE_LIST 代替。

You are getting those extra lines because you are using a LINE_STRIP.

In your 'F' case, push both end points of your line into the vector (like you were doing originally).

_vertexVector.push_back(_prevState.position);
_vertexVector.push_back(_currState.position);

And when you draw, use LINE_LIST instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文