Author Topic: Should texturing 160 OpenGL quads be SLOW?  (Read 4514 times)

0 Members and 1 Guest are viewing this topic.

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Should texturing 160 OpenGL quads be SLOW?
« on: September 19, 2007 »

Hi, I've been using the following routine to texture bullets for my game.

Code: [Select]
glLoadIdentity()
glTranslatef (x - radius, y - radius, 0)

glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, image)
glBegin(GL_QUADS)

glTexCoord2f 0.0, 0.0; glVertex2f 0.0, 0.0
glTexCoord2f 1.0, 0.0; glVertex2f radius * 2, 0.0
glTexCoord2f 1.0, 1.0; glVertex2f radius * 2, radius * 2
glTexCoord2f 0.0, 1.0; glVertex2f 0.0, radius * 2
  glEnd
glDisable(GL_TEXTURE_2D)
End Method

It appears to be SLOOOOOOOW. I'm sure I'm doing something wrong here. The bullets are all drawn once per cycle.
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #1 on: September 19, 2007 »
It shouldn't be slow, you should be able to draw thousands of quads per frame.  One thing you can do is remove the glEnable and glBindTexture out of the loop - all your textures are the same and texturing is always enabled.
Which graphics card do you have?

Jim
Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #2 on: September 19, 2007 »
Right now I'm playing with my lappy which has a ATI Radeon Express 1100. I know it is plenty powerfull enough to run a simple OpenGL program. Would it be best to post my entire code?
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #3 on: September 19, 2007 »
Well, that hardware should be able to do thousands of polys, so something's wrong.  Posting your code is a good idea, if you don't mind doing that :)

Jim
Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #4 on: September 20, 2007 »
Make sure your textures are power of 2
Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #5 on: September 20, 2007 »
Make sure your textures are power of 2

They are, 32x32.

Sorry to flood with blitzmax code. Yes, trying to utalize my own bullet hell demo.

I'm probably doing retarted things too in OpenGL I've been doing a bit of thumbing through my copy of the "Red Book". I should probably stop jumping around in it. :whack:

Code: [Select]

Strict

Global enemy_shots:TList= New TList ' list for our enemy shots
Global cell_groups:TList = New TList ' this is for the cell groups
Global player_shots:TList = New TList

' set some timer vars
Global base_time:Float = MilliSecs()
Global frames:Float = 0.0
Global second_time:Float = 0.0
Global FPS:Float = 0

Function reset_frames()
frames:+1.0
second_time = (MilliSecs() - base_time) / 1000.0


FPS = frames / second_time


End Function


 
' get the shot images

Global ship:player = New player
Type spline
 Field x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
 Method x_at_time#(t#)
  Return ((1-t)^2*x1)+(2*t*(1-t)*x2)+(t^2*x3)
 EndMethod
 Method y_at_time#(t#)
  Return ((1-t)^2*y1)+(2*t*(1-t)*y2)+(t^2*y3)
 EndMethod
 Method z_at_time#(t#)
  Return ((1-t)^2*z1)+(2*t*(1-t)*z2)+(t^2*z3)
 EndMethod
End Type
 
Type cell
 Field x:Float, y:Float, z:Float, direction:Float, num_sides:Float, hp:Float, my_timeline:burst_timeline
End Type  'resides in cell_group objects
 
Type cell_group
Field x:Float, y:Float, z:Float, my_cells:cell[], my_path:spline, direction:Float, speed:Float, path_position:Float
' adds a cell then records length and direction from the xy,
'turning the angle affects all cells

Method Update()
End Method

Method update_children()

End Method

Method move()
path_position:+speed 'move the position point along
x = my_path.x_at_time(path_position)
y = my_path.y_at_time(path_position)
z = my_path.z_at_time(path_position)
End Method

EndType ' holds and updates child cells

Type enemy_shot
Field x:Float, y:Float, direction:Float, speed:Float, radius:Float
Function Create(x:Float, y:Float, direction:Float, speed:Float, radius:Float)
Local temp:enemy_shot= New enemy_shot
temp.x=x
temp.y=y
temp.speed=speed
temp.direction = direction
temp.radius = radius
ListAddLast(enemy_shots,temp)
EndFunction
Method update()
outside_screen()
move()
draw()
End Method
Method move()
x:+Cos(direction)*speed
y:+Sin(direction)*speed
End Method
Method outside_screen()
If x<0
destroy()
End If
If y<0
destroy()
End If
If x > 640
destroy()
End If
If y>480
destroy()
End If
End Method
Method destroy()
ListRemove(enemy_shots,Self)
End Method
Method Draw()
 
glLoadIdentity()
glTranslatef (x - radius, y - radius, 0)

glBegin(GL_QUADS)
glTexCoord2f 0.0, 0.0
glVertex2f 0.0, 0.0
glTexCoord2f 1.0, 0.0
glVertex2f radius * 2, 0.0
glTexCoord2f 1.0, 1.0
glVertex2f radius * 2, radius * 2
glTexCoord2f 0.0, 1.0
glVertex2f 0.0, radius * 2
  glEnd

End Method
End Type ' basic bullet

Type shot_burst
Field x:Float, y:Float, fill_angle:Float, numshots:Float, direction:Float, step_delay:Int, shot_speed:Float, shot_radius = 16
Method Fire()
If fill_angle > 360
RuntimeError "Error angle > 360 degrees"
End If
Local start_angle:Float = direction - (fill_angle / 2.0)
Local sub_angle:Float = fill_angle / (numshots - 1)
If fill_angle = 360
sub_angle = 360 / numshots
start_angle = direction
End If
For Local i = 0 To numshots - 1
enemy_shot.Create(x, y, start_angle + (i * sub_angle) , shot_speed, shot_radius)
Next
End Method
End Type  ' resides witin a burst timeline  'describes a pattern

Type burst_timeline
Field num_bursts#=0,bursts:shot_burst[],event_time%,reset_time=0
Method add_burst(burst:shot_burst) ' add a burst and time from last shot to be executed
Local new_length%=bursts.length+1
bursts=bursts[..new_length]' holds bursts
bursts[new_length-1]=burst
num_bursts:+1
If burst.step_delay>reset_time ' if the new burst needs more time add to the reset time
reset_time=burst.step_delay
End If
End Method
Method update()

For Local i:shot_burst=EachIn(bursts)
If i.step_delay=event_time
i.fire()
EndIf
Next
event_time:+1
If event_time>reset_time
event_time=0
End If
End Method
End Type

Type player_shot
Field x:Float, y:Float, direction:Float, speed:Float

Function Create(x:Float, y:Float, direction:Float, speed:Float)
Local temp:player_shot = New player_shot
temp.x = x
temp.y = y
temp.direction = direction
temp.speed = speed
ListAddLast(player_shots, temp)
End Function
Method Update()
If x < 0
Destroy()
EndIf
If y < 0
Destroy()
EndIf
If x > 640
Destroy()
EndIf
If y > 480
Destroy()
EndIf
move()
Draw()
EndMethod
Method Draw()
DrawOval(x - 4, y - 4, 8, 8)
End Method
Method move()
x:+Cos(direction) * speed
y:+Sin(direction) * speed

End Method
Method Destroy()
ListRemove(player_shots, Self)
End Method

End Type

Type player_node
Field x:Float, y:Float, direction:String
EndType

Type player
Field x:Float = 320, y:Float = 420, lives:Int, shield_timer:Float, shot_timer:Float
Field chain:String 'keeps track of movements

Method Update()
shoot()
move()
chain_move()
Draw()
EndMethod
Method move()
x:+(KeyDown(KEY_RIGHT) - KeyDown(KEY_LEFT)) * 3
y:+(KeyDown(KEY_DOWN) - KeyDown(KEY_UP)) * 3
End Method
Method shoot()
If KeyDown(KEY_Z)
player_shot.Create(x, y, 270, 12)
End If
End Method
Method Draw()
DrawOval(x - 6, y - 6, 12, 12)
End Method
Method chain_move()
If KeyHit(KEY_LEFT)
chain:+"L"
End If
If KeyHit(KEY_RIGHT)
chain:+"R"
End If
If KeyHit(KEY_UP)
chain:+"U"
End If
If KeyHit(KEY_DOWN)
chain:+"D"
End If
chain = chain[chain.Length - 4..]

If chain = "UUUU"
For Local i = 0 To 5
player_shot.Create(x, y, 270, i + 1)

Next
End If
End Method
End Type
'test

Local p:burst_timeline = New burst_timeline ' here is a burst timelie-
' that might be stored in an enemy or boss type



' use a series of for loops to add burst patterns to our burst_timeline object




Global e:shot_burst = New shot_burst

e.step_delay = 0

e.x = 320
e.y = 240
e.direction = 0
e.shot_speed = 4
e.shot_radius = 8
e.numshots = 5
e.fill_angle = 360 ' 5 @ 180 degrees =225
p.add_burst(e)    ' 4 @ 180 degrees = 240





Function draw_ngon(numsides:Float, radius:Float)
Local angle:Float = 360 / numsides
glBegin(GL_TRIANGLE_FAN)
glColor3f(1, 1, 1)
glVertex3f(0, 0, 0)

For Local I:Float = 0 To numsides

glColor3f(0, .25, 1)
glVertex3f(Cos(i * angle) * radius, Sin(i * angle) * radius, 0)
Next
glEnd
End Function
GLGraphics 640, 480
glEnable (GL_BLEND)
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable GL_DEPTH_TEST
glEnable GL_ALPHA_TEST
glEnable(GL_ALPHA)
glAlphaFunc GL_GEQUAL, .5
glDepthMask(GL_TRUE)

 
Global shot_image:TImage = LoadAnimImage("image.png", 32, 32, 0, 1)
Global shot_pixmap:TPixmap[]= shot_image.pixmaps
Global image:Int = GLTexFromPixmap(shot_pixmap[0])






 
 


glMatrixMode(GL_PROJECTION) ;
glLoadIdentity();
glOrtho(0, 640, 480, 0, - 1000, 1000)
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;

While Not KeyDown(KEY_ESCAPE)
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT

glTranslatef 320.0, 240.0, 0

p.Update()
' udate bullets
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, image)
For Local e:enemy_shot = EachIn(enemy_shots)
e.Update()
Next
glDisable(GL_TEXTURE_2D)

e.direction = MilliSecs()
glColor3f(1, 1, 1) 
Flip
Wend

Challenge Trophies Won:

Offline nystep

  • ZX 81
  • *
  • Posts: 19
  • Karma: 4
    • View Profile
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #6 on: September 20, 2007 »
Hi,

Well, first of all, how much does the resolution affect your framerate? what framerate do you get in 640*480, 800*600, 1024*768... ? If the framerate varies a lot depending on resolution, it means you're fillrate-limited.
It can be the case with 160 quads if they cover all the screen for example.

In case you're fillrate limited, you should also check how the texture resolution affects performance, but it should be granted that your 32*32 textures fit in the GPU texturing-cache.

Then, there would be a test to do with the number of quads, to see if you're vertex-limited, which i beleive is not the case since you use only 160*4 vertices. And, on another side, you're using immediate mode (specifying each vertex with function calls on the CPU). In this mode, the hardware vertex-processor unit is most likelly crossing arms waiting for any data to come from the CPU. There is no real risk that you get vertex-processing power limited since the GPU requires that you send several thousands of triangles per CPU-call to be really busy.

The last solution, if your framerate does not depend on the resolution/number of vertex, is that your application is CPU-limited. The language you use may be too slow, or, you're making too many opengl calls for each primitive. Can you get extensions in blitzmax?
If you can, you should consider the way you're sending vertex data to the opengl. If the vertex are constant for each frame, you can store them in the video card memory and render them in a single opengl call, without a loop.
Elseway, if the vertex are moving, you're forced to update the contents of the video card's memory at every frame, so it sounds a bit useless. You can nonetheless use vertex arrays, since they're client side anyway.

To come to your code, first, i find it weird that you're using:
glLoadIdentity()
glTranslatef (x - radius, y - radius, 0)
to translate, since you can translate as well in the glVertex calls. You should prevent changing the modelview matrix inside a loop only for a few vertex... changing a matrix makes 16 floats to be transfered to the GPU, whereas your vertex are taking as well 16 floats.

As it has been said, you should enable texturing and bind your texture out of the loop too. Just keep the minimum OpenGL calls inside your loop, because those are quite CPU-expensive.

Well, hope i've been clear with those explanations and that they'll be useful. :)

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: Should texturing 160 OpenGL quads be SLOW?
« Reply #7 on: September 21, 2007 »
Thanks for all the tips.
It turned out that the mojor bottleneck came from compiling and running the code off a USB memory device. I didn't know that it would cause this kind of slow down.


Here is a "thank you" picture of a happy engine.
« Last Edit: September 21, 2007 by Pixel_Outlaw »
Challenge Trophies Won: