Author Topic: OpenGL texturing  (Read 8382 times)

0 Members and 1 Guest are viewing this topic.

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
OpenGL texturing
« on: September 03, 2007 »
Hey all DBF members!

I know there has to be some OpenGL users out there, Rbraz at least! I haven't visited you for a long time, which is a shame. Especially because of the atmosphere of this community, which is awesome :cheers:

Anyways, onto the question. I have drawn a nice little image in paint to illustrate the problem.



I have a quad, and also a texture. I can easily draw a texture onto the quad, making it cover the whole rectangle, but I want to draw multiple instances of my texture onto the quad, as seen at the rightmost part of the image. Can't really figure out how to do it though :-\ At the moment, I have one quad for each texture I want to draw, but that's not really performance efficient when having 500 textures on screen. (500*4=2000 vertices. If I had one rectangle it would be 1*4=4, quite a difference!)

Any help is greatly appreciated!
Martin

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: OpenGL texturing
« Reply #1 on: September 03, 2007 »
No doubt that the Opengl experts here will tell you a better solution than this, but it sounds to me like you need two textures, one to have the image you want to copy and one target texture.

you could try using glCopyTexImage2D to draw multiple instances of the source texture to the target texture?
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: OpenGL texturing
« Reply #2 on: September 03, 2007 »
Yep, that's pretty much it except you can only draw to the framebuffer so you:

set the viewport to match the size of your target texture
draw your texture to it
copy from the framebuffer with glcopyteximage2d to your target texture
reset viewport to original size.

I think that's how it's done anyway.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: OpenGL texturing
« Reply #3 on: September 04, 2007 »
Hi Phoenix, you can't get the image on the right with a single quad and just that texturemap.  Either you need to use more quads, one for each squished circle, or you need to use a texture with that image on it.  Don't worry too much about having lots of geometry, that can be fixed up later if it's too slow.

Jim
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: OpenGL texturing
« Reply #4 on: September 04, 2007 »
Phoenix,

Jims right, dont worry about speed yet. 2000 texture mapped quads is nothing. In fact, depending on cards, you may find its faster than making a new texture and drawing one quad. Even worse, if you make one new texture that is not square (the obvious thing to do from your diagram) and you are not very careful with opengl state, your program will drop to 1-2 frames a second.

Personally until I know its too slow, I'd simply draw all the quads.

Chris
Challenge Trophies Won:

Offline ferris

  • Pentium
  • *****
  • Posts: 841
  • Karma: 84
    • View Profile
    • Youth Uprising Home
Re: OpenGL texturing
« Reply #5 on: September 04, 2007 »
I think this would be a good test - try it both ways and compare framerates. It would probably only be about your card's performance but now I'm curious as to which is actually faster.

But I'd take the easy way out and make lots of quads if you really want my opinion.
http://iamferris.com/
http://youth-uprising.com/

Where the fun's at.
Challenge Trophies Won:

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
Re: OpenGL texturing
« Reply #6 on: September 04, 2007 »
I had a test program with 50 spinning balls, 50 quads. It ran at ~100 fps on my computer. But at my big computer, it ran at 1000 fps. So performance shouldn't be much of a problem if you have a decent computer. My laptop isn't decent, and it had 100 fps.

But let's say we have a 800x600 screen, filled with tiles. The tiles are 32x32, making the screen 25x19 tiles. 25*19=475 quads, which is way too slow on my laptop (~7 fps). Jim, you say that speed can be fixed, could you explain how? If there is no way to optimize it, is there another method that can handle many images on screen at the same time? Blitz could handle lots of images on screen at the same time, and it's generally considered to be slow, so surely there must be an effective approach.

Offline stormbringer

  • Time moves by fast, no second chance
  • Amiga 1200
  • ****
  • Posts: 453
  • Karma: 73
    • View Profile
    • www.retro-remakes.net
Re: OpenGL texturing
« Reply #7 on: September 04, 2007 »
drawing tons of quads should not be a problem.... geometry in OpenGL is very very fast (and even if explicit calls show some slowdown, there are then other ways to optimize)..

one thing to avoid, especially in this case (as far as I understood) is that if you use the same texture, then avoid making calls to glBindTexture() before drawing each quad. Or if you can have a loop that looks like this:

glBindTexture()
glBegin(GL_QUADS)

for (c=0; c < NUM_QUADS; c++)
{
    glTexCoordXXX()
    glVertexXXX()
}
glEnd()

it should be pretty fast...

You cannot have a quad filled in with several textures (unless you use multi-texture extensions, which are not great at all and if this is the case, the you should switch to shaders)
We once had a passion
It all seemed so right
So young and so eager
No end in sight
But now we are prisoners
In our own hearts
Nothing seems real
It's all torn apart

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
Re: OpenGL texturing
« Reply #8 on: September 04, 2007 »
After stripping the code down a lot, there aren't many lines left. This is called 500 times:
Code: [Select]
Gl.glBegin( Gl.GL_QUADS );
Gl.glVertex3f( X, Y, 0.0f );
Gl.glVertex3f( (Width + X), Y, 0.0f );
Gl.glVertex3f( (Width + X), (Height + Y), 0.0f );
Gl.glVertex3f( X, (Height + Y), 0.0f );
Gl.glEnd();
Without any textures, colors or anything, and I get 15-20 fps. Is that normal? Should I stop using glBegin/glEnd?

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: OpenGL texturing
« Reply #9 on: September 04, 2007 »
Tell us processor and graphics card, but I'd say thats definitely not normal. 500 quads at less than 20fps? I'd call that a WTF the mid 90s called and asked for their performance back?

It almost sounds like you are dropping back to software. That might be happening if you are asking for a pixel format that is unsupported. What pixel format are you using?

Thats only a wild guess but really this is very unusual.


Chris
« Last Edit: September 04, 2007 by chris »
Challenge Trophies Won:

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
Re: OpenGL texturing
« Reply #10 on: September 04, 2007 »
1.5 GHz Intel processor, 64mb graphics card. Runs at more than 1000 fps with 2.54 GHz Intel/256mb video memory.

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: OpenGL texturing
« Reply #11 on: September 04, 2007 »
No way its that slow so either the pixel format is screwed or somehow its finding a SW implementation fo OGL not hardware. Please post your windowing code...
Challenge Trophies Won:

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
Re: OpenGL texturing
« Reply #12 on: September 04, 2007 »
I'm using a SimpleOpenGLControl (found in the Tao framework), with C#, and it's attached to  a Windows Form. Pixel format seems to be normal:
Code: [Select]
Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();// The pixel format descriptor
            pfd.nSize = (short) Marshal.SizeOf(pfd);                        // Size of the pixel format descriptor
            pfd.nVersion = 1;                                               // Version number (always 1)
            pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW |                          // Format must support windowed mode
                        Gdi.PFD_SUPPORT_OPENGL |                            // Format must support OpenGL
                        Gdi.PFD_DOUBLEBUFFER;                               // Must support double buffering
            pfd.iPixelType = (byte) Gdi.PFD_TYPE_RGBA;                      // Request an RGBA format
            pfd.cColorBits = (byte) colorBits;                              // Select our color depth
            pfd.cRedBits = 0;                                               // Individual color bits ignored
            pfd.cRedShift = 0;
            pfd.cGreenBits = 0;
            pfd.cGreenShift = 0;
            pfd.cBlueBits = 0;
            pfd.cBlueShift = 0;
            pfd.cAlphaBits = 0;                                             // No alpha buffer
            pfd.cAlphaShift = 0;                                            // Alpha shift bit ignored
            pfd.cAccumBits = accumBits;                                     // Accumulation buffer
            pfd.cAccumRedBits = 0;                                          // Individual accumulation bits ignored
            pfd.cAccumGreenBits = 0;
            pfd.cAccumBlueBits = 0;
            pfd.cAccumAlphaBits = 0;
            pfd.cDepthBits = depthBits;                                     // Z-buffer (depth buffer)
            pfd.cStencilBits = stencilBits;                                 // No stencil buffer
            pfd.cAuxBuffers = 0;                                            // No auxiliary buffer
            pfd.iLayerType = (byte) Gdi.PFD_MAIN_PLANE;                     // Main drawing layer
            pfd.bReserved = 0;                                              // Reserved
            pfd.dwLayerMask = 0;                                            // Layer masks ignored
            pfd.dwVisibleMask = 0;
            pfd.dwDamageMask = 0;

Complete window code, if needed.
Code: [Select]
windowForm = new Form();
windowForm.ClientSize = new Size( ScreenWidth, ScreenHeight );
windowWidth = windowForm.Width;
windowHeight = windowForm.Height;
windowForm.Icon = null;
windowForm.Text = windowTitle;
windowForm.FormClosing += new FormClosingEventHandler( windowForm_FormClosing );
windowForm.Resize += new EventHandler( windowForm_Resize );

// Window mode specific settings
// Changes borders/control boxes/etc
switch( mode )
{
case WindowMode.Windowed:
windowForm.FormBorderStyle = FormBorderStyle.FixedSingle;
windowForm.MaximizeBox = false;
windowForm.MinimizeBox = false;
break;
case WindowMode.Fullscreen:
Resolution.CResolution changeRes = new Resolution.CResolution( screenWidth, screenHeight );
windowForm.FormBorderStyle = FormBorderStyle.None;
windowForm.WindowState = FormWindowState.Maximized;
windowForm.TopMost = true;
break;
case WindowMode.WindowScalable:
windowForm.FormBorderStyle = FormBorderStyle.Sizable;
break;
case WindowMode.BorderlessWindow:
windowForm.FormBorderStyle = FormBorderStyle.None;
break;
}

// Initialize the OpenGL graphics device
glDevice = new SimpleOpenGlControl();
glDevice.Location = new Point( 0, 0 );
glDevice.Size = new Size( screenWidth, screenHeight );
glDevice.InitializeContexts();

windowForm.Controls.Add( glDevice );

// Set up OpenGL
Gl.glMatrixMode( Gl.GL_PROJECTION );
Gl.glOrtho( 0, screenWidth, screenHeight, 0, -1, 1 );
Gl.glMatrixMode( Gl.GL_MODELVIEW );
Gl.glClearColor( 1, 1, 1, 1 );

// Enable transparency
Gl.glBlendFunc( Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA );
Gl.glEnable( Gl.GL_BLEND );

// We're done setting up, so the program is running
running = true;

// Show the created window
windowForm.Show();

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: OpenGL texturing
« Reply #13 on: September 04, 2007 »
OK so check that accumBits is 0, depth bits is 32, colorBits is 32 and stencilBits is 0. I dont know what SimpleOpenGlControl() is ...
« Last Edit: September 04, 2007 by chris »
Challenge Trophies Won:

Offline Phoenix

  • C= 64
  • **
  • Posts: 99
  • Karma: 4
    • View Profile
Re: OpenGL texturing
« Reply #14 on: September 04, 2007 »
No luck, I changed them but the FPS still sits at 15-20.

Offline stormbringer

  • Time moves by fast, no second chance
  • Amiga 1200
  • ****
  • Posts: 453
  • Karma: 73
    • View Profile
    • www.retro-remakes.net
Re: OpenGL texturing
« Reply #15 on: September 04, 2007 »
do not remove glBegin()/glEnd() calls. They control the geometry definition => removing them will ruin the GL geometry pipeline
We once had a passion
It all seemed so right
So young and so eager
No end in sight
But now we are prisoners
In our own hearts
Nothing seems real
It's all torn apart

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: OpenGL texturing
« Reply #16 on: September 04, 2007 »
1.5 GHz Intel processor, 64mb graphics card. Runs at more than 1000 fps with 2.54 GHz Intel/256mb video memory.
Seems to me that you have a problem with your gfx driver, have you tried to update it ?
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: OpenGL texturing
« Reply #17 on: September 04, 2007 »
Perhaps it's PB itself that's slowing it down?
I was going to suggest using glDrawBuffers and friends, but only if your poly count was in the order of 10,000 or so.  500 is nothing.

Jim
Challenge Trophies Won: