OpenGL trying to Draw Multiple 2d Textures, only 1st one appears

橙三吉。 提交于 2020-01-11 09:55:40

问题


I've got a problem in that I'm trying to draw a solar system using textures (one texture for each planet) and as I draw my textures, only the 1st one appears. None of the rest do.

My init function iterates through my files, saves the textures into an object, and then iterates through the objects. As it's iterating, it generates the textures and binds them to a name using the OpenGL calls.

        SharpGL.OpenGL gl = args.OpenGL;
        gl.Enable(SharpGL.OpenGL.GL_BLEND);
        gl.Enable(SharpGL.OpenGL.GL_TEXTURE_2D);
        gl.BlendFunc(SharpGL.Enumerations.BlendingSourceFactor.SourceAlpha, SharpGL.Enumerations.BlendingDestinationFactor.OneMinusSourceAlpha);                        
        gl.ClearColor(0, 0, 0, 1);

        foreach (ImageWrapper iw in m_images)
        {                            
            uint[] texNames = new uint[1];

            gl.GenTextures(1, texNames);
            gl.BindTexture(SharpGL.OpenGL.GL_TEXTURE_2D, texNames[0]);

            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_WRAP_S, SharpGL.OpenGL.GL_REPEAT);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_WRAP_T, SharpGL.OpenGL.GL_REPEAT);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_MAG_FILTER, SharpGL.OpenGL.GL_LINEAR);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_MIN_FILTER, SharpGL.OpenGL.GL_LINEAR);

            gl.TexImage2D(SharpGL.OpenGL.GL_TEXTURE_2D,
                          0,
                          3,
                          iw.BitmapSource.PixelWidth,
                          iw.BitmapSource.PixelHeight,
                          0,
                          SharpGL.OpenGL.GL_BGRA,
                          SharpGL.OpenGL.GL_UNSIGNED_BYTE,
                          iw.Pixels);

            iw.TextureHandle = texNames;

        }

Here is my function that draws everything. I iterate through all my objects that have the texture data and try to draw them one at a time. I also want to execute some rotations and transformations to get my solar system to spin. That part works fine for the texture that appears.

        SharpGL.OpenGL gl = args.OpenGL;
        gl.Clear(SharpGL.OpenGL.GL_COLOR_BUFFER_BIT | SharpGL.OpenGL.GL_DEPTH_BUFFER_BIT );
        gl.LoadIdentity();

        float[] data = new float[4];
        foreach (ImageWrapper iw in m_images)
        {
            //gl.MatrixMode(SharpGL.Enumerations.MatrixMode.Modelview);                

            gl.Ortho2D(0, this.Width, 0, this.Height);                
            gl.Enable(OpenGL.GL_TEXTURE_2D);                
            gl.BindTexture(OpenGL.GL_TEXTURE_2D, iw.TextureHandle[0]);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_WRAP_S, SharpGL.OpenGL.GL_REPEAT);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_WRAP_T, SharpGL.OpenGL.GL_REPEAT);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_MAG_FILTER, SharpGL.OpenGL.GL_LINEAR);
            gl.TexParameter(SharpGL.OpenGL.GL_TEXTURE_2D, SharpGL.OpenGL.GL_TEXTURE_MIN_FILTER, SharpGL.OpenGL.GL_LINEAR);


            gl.PushMatrix();
            //gl.Translate(this.Width / 2, this.Height / 2, 0);               

            //gl.Rotate(iw.RotationAboutSun, 0, 0, 1);
            //gl.Translate(iw.X + 1 * this.Width / 2, iw.Y + 1 * this.Height / 2, 0);
            gl.Translate(32,32, 0);
            //gl.Rotate(iw.RotationAboutAxis, 0, 0, 1);  
            //

            gl.Begin(SharpGL.Enumerations.BeginMode.Quads);
            gl.Color(new float[] { 1f,1f,1f});                                          
            gl.TexCoord(0,0);
            gl.Vertex(new double[] { 0 - iw.PixelWidth / 2, 0 - iw.PixelHeight / 2});                
            gl.TexCoord(0,1);
            gl.Vertex(new double[] { 32 - iw.PixelWidth / 2, 0 - iw.PixelHeight / 2 });               
            gl.TexCoord(1,1);
            gl.Vertex(new double[] { 32 - iw.PixelWidth / 2, 32 - iw.PixelHeight / 2 });
            gl.TexCoord(1,0);
            gl.Vertex(new double[] { 0 - iw.PixelWidth / 2, 32 - iw.PixelHeight / 2 });                            
            gl.End();

            gl.PopMatrix();

            gl.Disable(OpenGL.GL_TEXTURE_2D);                

        }

I'm using the SharpGL library in C# to do this.


回答1:


gluOrtho2D() doesn't issue a glLoadIdentity() like you seem to expect.

Generally you only set your projection matrix once per frame.

Try something like this:

void DrawFrame()
{
    ...

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluOrtho2D(0, this.Width, 0, this.Height);

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    // "camera" transform(s)

    foreach object
    {
        glPushMatrix();
        // per-object matrix transform(s)

        // draw object

        glPopMatrix();
    }
}



回答2:


Just had to deal with this problem so I thought I'd chip in as well.
I saw the accepted answer and in my case, I did reset everything correctly in the pipeline. In my pipeline, I need to render both 3D and 2D objects. For 3D objects I would switch to 3D projection/model view and for 2D objects would switch to orthographic projection.

However, when I wanted to render a couple of text blocks (using quads and textures), only the first texture was rendered. Depth testing was the root of my problem. So I've modified the code above to work for my situation.

void DrawFrame()
{
    foreach object
    {
        drawObject();   // Is an abstract method
    }
}


void _3DObject::drawObject() {
    switchTo3D();

    // Camera transform

    glPushMatrix();
    .
    . // Draw
    .
    .glPopMatrix();
}

void _2DObject::drawObject() {
    switchTo2D();

    // Having depth testing enabled was causing
    // problems when rendering textured quads.
    glDisable(GL_DEPTH_TEST);

    // Camera transform

    glPushMatrix();
    .
    . // Draw
    .
    .glPopMatrix();

    glEnable(GL_DEPTH_TEST);
}

PS: "Just" refers to exactly 1 month ago! Don't know why I forgot to post this answer sooner :(



来源:https://stackoverflow.com/questions/15386821/opengl-trying-to-draw-multiple-2d-textures-only-1st-one-appears

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!