Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

998842 Posts in 39181 Topics- by 30593 Members - Latest Member: Ham

April 21, 2014, 06:40:22 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)capturing opengl textures
Pages: [1]
Print
Author Topic: capturing opengl textures  (Read 370 times)
nikki
Level 10
*****


View Profile Email
« on: March 26, 2013, 04:02:07 AM »

Hi !

in my 2d topdown game i've run into a bottleneck .
namely the drawing of large (100x100)+ tilebased terrain.
I've profiled the code and my tiledrawing routine takes 16% in the best case when the world is small <(64x64)tiles
but when the world is bigger it takes up to 46% of the total time.

I draw my tiles in immediate mode and most of the tiles have a colored rectangle behind them and a colored trasparent texture on top.

At first I tried using displaylists they give me only a small gain of 5-10% profit.
for the large worlds this is not enough.

Then I thought why not take screenshot/captures of the terrain ? with CopyTexImage2D

this works,and is workable too my largest worldsize 128x128 neatly fits into a power of two texture sized 1024x1024 since my tiles are 8x8 px.
But when I tried this I found out that I can only capture what is on the screen and in a power of two.

since my minimum/startup resolution is 1024x768 this means I can only capture 768 height and this goes down to 512px (power of two) so my maximum square I can capture  is only 512x512..

my question(s) is :

are there other ways of capturing what is outside of the screen ?
are there better ways of achieving this fix (I am openGL noob and I can only use OGL 1.4 plus perhabs some standard extensions)?
what would you do in my case ?






Logged
Christian Knudsen
Level 10
*****



View Profile WWW Email
« Reply #1 on: March 26, 2013, 04:31:00 AM »

Seems like what you need is FBOs. Instead of capturing the screen, draw to an FBO and draw that FBO to the screen.
Logged

Laserbrain Studios
Currently working on Hostile Takeover (TIGSource DevLog)
nospoon
Level 1
*


View Profile Email
« Reply #2 on: March 26, 2013, 04:33:47 AM »

You should use Vertex Buffer Objects.

Create a "chunk" from 16x16 tiles (or more), store them in one VBO, and it should be working really fast Smiley

You could probably store the whole world in one vbo if you are lazy, and it should be good enough (for a 100x100 world).
Logged
nikki
Level 10
*****


View Profile Email
« Reply #3 on: March 26, 2013, 04:40:00 AM »

I *think*  I am sure FBO's are not supported on my #@$%! laptop
atleast  
Code:
if (!GL.GetString(StringName.Extensions).Contains("EXT_framebuffer_object"))
that get's called.

I'll look intoa vbo now.

i also read something on the net about pbuffers .

would that maybe be usefull ?
I'll try both.

thanks already guys


edit: to be sure; that VBO approach is not to grab a screenshot right ? It's more like a general faster approach to this sort of thing ?

edit2: I can forget about pbuffers too
  
« Last Edit: March 26, 2013, 04:45:48 AM by nikki » Logged
nospoon
Level 1
*


View Profile Email
« Reply #4 on: March 26, 2013, 04:46:16 AM »

How did you use the displaylists ? they are similar to vbo.

You shouldn't draw each tile separately - you should create a big chunk of geometry, and then draw it at once.

So:
Code:
for(Tile t in all_tiles_in_the_screen){
t.draw();
}
Is bad.
Logged
nikki
Level 10
*****


View Profile Email
« Reply #5 on: March 26, 2013, 04:53:45 AM »

I've displaylists like this

Code:
 if (displayList == -1)
            {
                displayList = GL.GenLists(1);
                GL.NewList(displayList, ListMode.CompileAndExecute);

                GL.Begin(Quad)
                for (int x = 0; x < mapWidth; x++)
                {
                    for (int y = 0; y < mapHeight; y++)
                    {
                      // GL.Color4
                      // GL.TexCoord2(u1, v1);
                      // GL.Vertex2(x, y);
                      // x 4 corners
                    }
                }
                GL.End()

             }
   else
            {
                
                GL.CallList(displayList);
            }  


which would be sort of equal to your Bad! example.
or wouldn't it ?
I am only drawing one diplaylist in the end..

« Last Edit: March 26, 2013, 05:01:14 AM by nikki » Logged
Polly
Level 3
***


View Profile
« Reply #6 on: March 26, 2013, 05:00:39 AM »

That's the correct way of generating a display list for a 2D tile-map. Weird that the performance difference is so minimal.

Anyway, if your map is predominantly static, simply generate the texture(s) in software / on the CPU instead. Then using glTexSubImage2D you can always update tiles when they do change.
Logged
nikki
Level 10
*****


View Profile Email
« Reply #7 on: March 26, 2013, 05:06:47 AM »

what do you mean with :  simply generate the texture(s) in software / on the CPU instead.
? or well how would you do that ?

or would you use glTexSubImage2D  to grab 512x512 parts of a 1024x1024 image.
in 4 goes and moving the large one so it's always on screen ?
Logged
Polly
Level 3
***


View Profile
« Reply #8 on: March 26, 2013, 05:49:08 AM »

how would you do that ?

Let's say you've got the following 16x16 tilemap.



First load in the ( uncompressed ) tile-sheet into memory.



Each tile consists of 16x16 pixels, 4-bytes per pixel ( RGBA ), so 1 tile equals 1024 bytes.



Now, when you want to for example split the map into 8x8 chunks, you end up with 4 textures of 128x128. Each texture is ( 8x8x1024 ) 65536 bytes. In order to generate the texture data you iterate through the texture-array and calculate which pixel coordinate corresponds with the current iteration. From that pixel coordinate you can determine the tile-index, and from the tile-index ( + the pixel coordinate as offset ) the memory address of the pixel you need to copy.
Logged
nikki
Level 10
*****


View Profile Email
« Reply #9 on: March 26, 2013, 05:56:31 AM »

thanks for the wonderful tutorial !

so am I correct in thinking that you would color individual pixels in the new texture that way ?
by looking up the correct tile and the pixel at a certain location?
Logged
Polly
Level 3
***


View Profile
« Reply #10 on: March 26, 2013, 06:32:51 AM »

so am I correct in thinking that you would color individual pixels in the new texture that way ?
by looking up the correct tile and the pixel at a certain location?

Correct. Although you get better performance by copying 16-pixel lines ( width of a tile ) at a time instead of individual pixels .. but i didn't want to make it too difficult to understand Wink
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic