OpenGL - 快速精灵绘图 - 需要一些指导

Posted

技术标签:

【中文标题】OpenGL - 快速精灵绘图 - 需要一些指导【英文标题】:OpenGL - Fast Sprite Drawing - need some guidance 【发布时间】:2014-02-08 16:21:40 【问题描述】:

我的程序使用 OpenGL 创建并绘制了一个粒子系统。 我让它完全与 glBegin() 和 glEnd() 一起工作,但后来我注意到这已经过时了,根本不应该使用。于是我开始用 glDrawArrays(); 重写它

我的样子是这样的:

typedef QVector< Particle* > PARTICLES;
#define PARTICLE_SIZE 20.0f

void GLWidget::initializeGL()

    //>> TEST
    QGLFormat glFormat(QGL::SampleBuffers);
    glFormat.setSwapInterval(1); // vsync
    //>> /TEST
    QImage textureSnow = QGLWidget::convertToGLFormat( imgSnow );

    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    glGenTextures(3, m_texture);

    //Snow Particles
    glBindTexture(GL_TEXTURE_2D, m_texture[1]);
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
            textureSnow.width(), textureSnow.height(),
            0, GL_RGBA, GL_UNSIGNED_BYTE, textureSnow.bits());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glFinish();
    m_renderTimer->start(0);


void GLWidget::paintGL()

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glClear(GL_COLOR_BUFFER_BIT);
    glBindTexture(GL_TEXTURE_2D, m_texture[1]);
    glEnable(GL_TEXTURE_2D);

    glLoadIdentity();

    PARTICLES particles = m_particleSystem->getParticles();
    for(int i = 0; i < m_particleSystem->getParticleCount(); i++)
    
        // Get specific variables for the Particle
        float x = particles[i]->getX();
        float y = particles[i]->getY();
        float scale = particles[i]->getScale();
        float correctionValue = (PARTICLE_SIZE*scale/2);

        const float verts[] = 
            x -correctionValue, y -correctionValue,
            x +PARTICLE_SIZE -correctionValue, y -correctionValue,
            x +PARTICLE_SIZE -correctionValue, y + PARTICLE_SIZE -correctionValue,
            x -correctionValue, y +PARTICLE_SIZE -correctionValue
        ;

        // Since I don't use more than one sprite for this Particle at the moment
        const float texVerts[] = 
            0.0f, 0.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,
            0.0f, 1.0f
        ;

        glVertexPointer(2, GL_FLOAT, 0, verts);
        glTexCoordPointer(2, GL_FLOAT, 0, texVerts);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    

glBindTexture(GL_TEXTURE_2D, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

这样它就不会显示任何东西(黑屏)。 我一个人无法弄清楚我需要做什么。

我真正想知道的:

我错过了什么?或者换句话说: 如何使用 sprite 使用最新的 OpenGL 绘制大量始终在运动的粒子?

【问题讨论】:

您必须先将顶点数据提交给 GPU,然后才能通过顶点缓冲区对象或顶点数组对象进行渲染,然后使用着色器渲染顶点。 This tutorial does a good job of teaching modern opengl 我去看看这个教程,谢谢回复。 【参考方案1】:

您想使用哪个 OpenGL 版本?

OGL 2.0ES、2.1、3.0 及更高版本有细微差别,但您基本上需要一个着色器并减少数据的更改/上传,对于粒子系统,这些动态可以在着色器端处理,这样您就不会流失有不必要交通的公共汽车。

【讨论】:

我认为它会很好,如果它适用于 OGL 2.0 和其他东西:我几乎没有着色器经验。这是否意味着我应该以完全不同的方式(通过使用着色器)来处理粒子,或者这意味着什么? 对于 OGL 2.0,你不能改变着色器的位置,所以每个粒子都是一个独立的对象,有两种方法:动画精灵和修改顶点坐标;或它们的一些混合体。请注意,在某些平台(例如 windows)上,您需要显式创建 2.0 上下文,glew 可以让您的生活更轻松。

以上是关于OpenGL - 快速精灵绘图 - 需要一些指导的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 中的 2D 绘图:在原始尺寸下具有像素精度的线性过滤

与 QtOpenGl 之类的抽象相比,使用 OpenGl 的绘图要求应该有多低?

精灵绘图问题

使用 SDL 和 openGL 绘图原语不起作用

OpenGL VBO 绘图

OpenGL-ES 益智游戏 - 使绘图电池高效?