C++ OpenGL-快速绘制精灵-需要一些指导

C++ OpenGL-快速绘制精灵-需要一些指导,c++,qt,opengl,sprite,C++,Qt,Opengl,Sprite,我的程序使用OpenGL创建并绘制粒子系统。 我完全可以使用glBegin()和glEnd(),但后来我注意到这已经过时,根本不应该使用。所以我开始用glDrawArrays()重写它 我所拥有的是这样的: typedef QVector< Particle* > PARTICLES; #define PARTICLE_SIZE 20.0f void GLWidget::initializeGL() { //>> TEST QGLFormat glFor

我的程序使用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);
typedef QVector粒子;
#定义粒度为20.0f
void GLWidget::initializeGL()
{
//>>试验
QGLFormat glFormat(QGL::SampleBuffers);
glFormat.setSwapInterval(1);//vsync
//>>/测试
QImage textureSnow=QGLWidget::convertToGLFormat(imgSnow);
glEnable(GL_混合物);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去GL_SRC_ALPHA);
glClearColor(0.0f、0.0f、0.0f、0.0f);
glGenTextures(3,m_纹理);
//雪粒
glBindTexture(GL_纹理_2D,m_纹理[1]);
glTexImage2D(GL_纹理_2D,0,GL_RGBA,
textureSnow.width(),textureSnow.height(),
0,GL_RGBA,GL_无符号字节,textureSnow.bits();
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
glFinish();
m_渲染器->开始(0);
}
void GLWidget::paintGL()
{
glEnableClientState(GL_顶点_数组);
glEnableClientState(GL_纹理_坐标_阵列);
glClear(GLU颜色缓冲位);
glBindTexture(GL_纹理_2D,m_纹理[1]);
glEnable(GL_纹理_2D);
glLoadIdentity();
粒子粒子=m_particleSystem->getParticles();
对于(int i=0;igetParticleCount();i++)
{
//获取粒子的特定变量
float x=粒子[i]->getX();
float y=粒子[i]->getY();
浮动比例=粒子[i]->getScale();
浮动校正值=(粒度*比例/2);
常量浮点顶点[]={
x-校正值,y-校正值,
x+粒度-校正值,y-校正值,
x+粒度-校正值,y+粒度-校正值,
x-校正值,y+粒子大小-校正值
};
//因为我现在没有为这个粒子使用多个精灵
常量浮点texVerts[]={
0.0f,0.0f,
1.0f,0.0f,
1.0f,1.0f,
0.0f,1.0f
};
glVertexPointer(2,GLU浮点,0,顶点);
glTexCoordPointer(2,GL_浮点,0,texVerts);
gldrawArray(GL_三角带,0,4);
}
}
glBindTexture(GL_TEXTURE_2D,0);
glDisableClientState(GL_顶点_数组);
glDisableClientState(GL_纹理_坐标_数组);
glDisable(GL_纹理_2D);

这样它就不会显示任何内容(黑屏)。 我一个人想不出我需要做什么

我真正想知道的是:

我错过了什么?换句话说:
如何使用最新的OpenGl,使用精灵绘制大量始终处于运动状态的粒子

您希望使用哪个OpenGL版本


OGL 2.0ES、2.1、3.0和更高版本有一些细微的区别,但基本上你需要一个着色器并减少数据的更改/上传,对于粒子系统来说,这些动态可以在着色器端处理,这样你就不会因为不必要的流量而耗尽总线。

你必须在渲染之前将顶点数据提交给GPU,通过顶点缓冲区对象或顶点数组对象,然后使用着色器渲染顶点。我将看一看这个教程,谢谢你的回复。我认为如果它能在OGL2.0上运行的话会很好。另外,我几乎没有着色器方面的经验。这是否意味着我应该以完全不同的方式(通过使用着色器)处理粒子,或者这意味着什么?对于OGL2.0,您不能改变着色器上的位置,因此每个粒子都是独立的对象,有两种方式:设置动画的精灵和修改顶点坐标;或者是它们的混合体。请注意,在某些平台(如windows)上,您需要显式创建2.0上下文,glew可以使您的生活更加轻松。