OpenGL problem, totally confused

BlitzMax Forums/OpenGL Module/OpenGL problem, totally confused

ImaginaryHuman(Posted 2005) [#1]
I have a custom OpenGL program which basically uploads a texture and draws a 2D quad with the texture mappene onto it.

It works as expected on my iBook.

On the iMac, it does not work. Instead of showing the texture, it shows just a white square.

Why?


Tom(Posted 2005) [#2]
My crystal ball is at the cleaners, any chance of seeing the code? :)


ImaginaryHuman(Posted 2005) [#3]
OK.. ..here is the code. This works at it currently should on the ibook (G3, ATI Rage Mobility L gfx card). On the iMac, it also works fine except that the texture does not show. Instead, it draws white rectangles. I have no idea why or what I need to enable/disable/define to make it work. The iMac is a G4 1GHz with an Nvidia GeForce4 MX gfx card.

Any help or suggestions would be greatly appreciated. Hopefully it's not a blitamax bug or some kind of driver problem. You'd think it would work the same on two macs!

You'll need a 256x256 image, the one I load is RGB not RGBA.

Strict

Const ballsize:Int=256 'based on 256x256 image
Local ballsizehalf:Int=ballsize Shr 1

AutoMidHandle True
Local px1:TPixmap=LoadPixmap("Ball09.png") '4 to 9  RGB no alpha
px1=ConvertPixmap(px1,PF_RGBA8888)

bglCreateContext(640,480,32,0,BGL_BACKBUFFER|BGL_ALPHABUFFER)'|BGL_STENCILBUFFER)
glMatrixMode (GL_PROJECTION)
glOrtho(0,640,480,0,-1,1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity
glClear(GL_COLOR_BUFFER_BIT)
bglSwapBuffers
glClear(GL_COLOR_BUFFER_BIT)
bglSwapBuffers
glDisable(GL_DEPTH_TEST)
glDisable(GL_STENCIL_TEST)
glDisable(GL_ALPHA_TEST)
glDisable(GL_SCISSOR_TEST)
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE)
bglSetSwapInterval(0) 'no vbl sync
GLDisable(GL_DITHER)

glClearColor(0,0,0,0)
glColor4b($FF,$FF,$FF,$FF)
SeedRnd(MilliSecs())

'Create bank space to store a downloaded image
Local bnk:TBank=CreateBank(ballsize*ballsize) 'to store screen image
Local where:Byte Ptr=BankBuf(bnk)

'Give our image an alpha buffer
Local pxp:Byte Ptr=PixmapPixelPtr(px1,0,0)
Local pitch:Int=PixmapPitch(px1)
For Local yy:Int=0 To ballsize-1
	Local yloc:Int=yy*pitch
	For Local xx:Int=0 To ballsize-1
		pxp[yloc+(xx Shl 2)+3]=pxp[yloc+(xx Shl 2)] 'copy the red component into the image's alpha buffer
	Next
Next
'Pixmap now has equivalent data in alpha buffer

'Upload our pixmap as a texture
glDrawBuffer(GL_BACK)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST)
glPixelStorei(GL_UNPACK_ALIGNMENT,4)
glPixelStorei(GL_UNPACK_ROW_LENGTH,PixmapPitch(px1)/4) '4 bytes per pixel RGB format
Local name:Int
glGenTextures(1,VarPtr(name))
glBindTexture(GL_TEXTURE_2D,name)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ballsize,ballsize,0,GL_RGBA,GL_UNSIGNED_BYTE,PixmapPixelPtr(px1,0,0)) 'RGB=no alpha in pixmap!

Local objx:Int=Rand(0,619-ballsize)+10
Local objy:Int=Rand(0,459-ballsize)+10
Local objx2:Int=Rand(0,619-ballsize)+10
Local objy2:Int=Rand(0,459-ballsize)+10
Local xadd:Int=Rand(1,5)
Local yadd:Int=Rand(1,5)
Local xadd2:Int=Rand(1,5)
Local yadd2:Int=Rand(1,5)
Local spin:Int=0
Local spin2:Int=0
Repeat
	'Move objects
	If ballsize<620
		objx:+xadd; objx2:+xadd2
		If objx>630-ballsize Or objx<10
			xadd=-xadd
			objx:+xadd
		EndIf
		If objx2>630-ballsize Or objx2<10
			xadd2=-xadd2
			objx2:+xadd2
		EndIf
	EndIf
	If ballsize<460
		objy:+yadd; objy2:+yadd2
		If objy>470-ballsize Or objy<10
			yadd=-yadd
			objy:+yadd
		EndIf
		If objy2>470-ballsize Or objy2<10
			yadd2=-yadd2
			objy2:+yadd2
		EndIf
	EndIf

	glClear(GL_COLOR_BUFFER_BIT) 'cls
	'SetBlend LIGHTBLEND
	glEnable(GL_BLEND)
	'glBlendFunc GL_SRC_ALPHA,GL_ONE 'lightblend
	glBlendFunc GL_SRC_COLOR,GL_ONE_MINUS_SRC_COLOR
	glShadeModel(GL_FLAT)'SMOOTH)
	glPolygonMode(GL_FRONT,GL_FILL) 'face
	'spin=(spin+3) Mod 360
	'SetRotation spin
	'Draw texture
	glColor4b($FF,$FF,$FF,$FF)
	glEnable(GL_TEXTURE_2D)
	glBegin GL_QUADS
		glTexCoord2f(0,0); glVertex2i(objx,objy)
		glTexCoord2f(0,1); glVertex2i(objx,objy+ballsize)
		glTexCoord2f(1,1); glVertex2i(objx+ballsize,objy+ballsize)
		glTexCoord2f(1,0); glVertex2i(objx+ballsize,objy)
	glEnd
	'SetRotation -spin
	glBegin GL_QUADS
		glTexCoord2f(0,0); glVertex2i(objx2,objy2)
		glTexCoord2f(0,1); glVertex2i(objx2,objy2+ballsize)
		glTexCoord2f(1,1); glVertex2i(objx2+ballsize,objy2+ballsize)
		glTexCoord2f(1,0); glVertex2i(objx2+ballsize,objy2)
	glEnd
	Local mx:Int=Int(MouseX())-ballsizehalf
	Local my:Int=Int(MouseY())-ballsizehalf
	glBegin GL_QUADS
		glTexCoord2f(0,0); glVertex2i(mx,my)
		glTexCoord2f(0,1); glVertex2i(mx,my+ballsize)
		glTexCoord2f(1,1); glVertex2i(mx+ballsize,my+ballsize)
		glTexCoord2f(1,0); glVertex2i(mx+ballsize,my)
	glEnd
	glDisable(GL_TEXTURE_2D)
	glDisable(GL_BLEND)
	'SetRotation 0
	
	glPixelZoom(1.0,1.0) 'no zooming
	glPixelStorei(GL_PACK_ROW_LENGTH,ballsize) 'row length
	glPixelStorei(GL_PACK_ALIGNMENT,4) 'byte alignment
	glReadPixels(mx,my,ballsize,ballsize,GL_ALPHA,GL_UNSIGNED_BYTE,where) 'grab alpha into buffer
	glRasterPos2i 0,256'mx,my 'Set the position top-left to draw this object at
	glPixelStorei(GL_UNPACK_ROW_LENGTH,ballsize)
	glPixelStorei(GL_UNPACK_ALIGNMENT,4)
	glDrawPixels(ballsize,ballsize,GL_RED,GL_UNSIGNED_BYTE,where) 'Render alpha buffer into the stencil buffer
'	'GL_INDEX_SHIFT
'	'GL_INDEX_OFFSET
	
'	glEnable(GL_STENCIL_TEST) 'Test the stencil
'	glStencilFunc(GL_GEQUAL,140,$FF) 'Allow any pixels where the alpha is >=140
'	glEnable(GL_BLEND) 'Do blending
'	glBlendFunc(GL_SRC_ALPHA,GL_ZERO) 'Multiply source color by the alpha value, ignore dest
'	'glEnable(GL_ALPHA_TEST)
'	'glAlphaFunc(GL_GREATER,0.5)
'	'glEnable(GL_ALPHA_TEST)
'	'glAlphaFunc(GL_GREATER,0.5)

'	glColor3b($44,$FF,$88) 'What color to render
'	glColorMask True,True,True,False 'Draw in color components only, keep alpha for future operations
'	glRasterPos2i 0,my+ballsize 'Set the position top-left to draw this object at
'	glBegin GL_QUADS
'		glVertex2i(mx,my)
'		glVertex2i(mx,my+ballsize)
'		glVertex2i(mx+ballsize,my+ballsize)
'		glVertex2i(mx+ballsize,my)
'	glEnd
'	glDisable(GL_STENCIL_TEST)
'	glDisable(GL_BLEND)
'	glFlush()

	bglSwapBuffers
'	Repeat;Until KeyHit(KEY_SPACE)
Until KeyHit(KEY_ESCAPE)
End



ImaginaryHuman(Posted 2005) [#4]
The bizarre thing is that using DrawImage works fine, ie the BlitzMax command. ... it draws textured images on both macs. So there's maybe something I'm not doing, or in the right order, something odd.

This program works fine ...

Graphics 640,480,0
Local img:TImage=LoadImage("Ball09.png")
DrawImage img,0,0
Flip
WaitKey



ImaginaryHuman(Posted 2005) [#5]
I also found that this following code (uses glCopyPixels with a Map to remap the colors) does not work on the imac, but it works on the ibook. This is not the full program, just the parts that define the color map arrays and the actual routine to do the remapping. With MAP_COLOR set to GL_TRUE, there is nothing rendered to the display. With MAP_COLOR set to GL_FALSE, the copypixels is performed but obviously without any remapping.

How come?

'Define remapping for use with glCopyPixels
Local redmap:Short[256]
Local greenmap:Short[256]
Local bluemap:Short[256]
For Local index:Int=0 To 255
	redmap[index]=Short(Rand(0,255) Shl 8)
	greenmap[index]=Short(Rand(0,255) Shl 8)
	bluemap[index]=Short(Rand(0,255) Shl 8)
Next

...some other code is in here

		glPixelMapusv(GL_PIXEL_MAP_R_TO_R,256,redmap)
		glPixelMapusv(GL_PIXEL_MAP_G_TO_G,256,greenmap)
		glPixelMapusv(GL_PIXEL_MAP_B_TO_B,256,bluemap)
		glPixelZoom(1.0,1.0)
		glPixelTransferi(GL_MAP_COLOR,GL_TRUE)
		glPixelTransferf(GL_RED_SCALE,1.0)
		glPixelTransferf(GL_RED_BIAS,0.0)
		glPixelTransferf(GL_GREEN_SCALE,1.0)
		glPixelTransferf(GL_GREEN_BIAS,0.0)
		glPixelTransferf(GL_BLUE_SCALE,1.0)
		glPixelTransferf(GL_BLUE_BIAS,0.0)
		glRasterPos2i(0,480)
		glDisable(GL_TEXTURE_2D)
		glCopyPixels(0,0,640,480,GL_COLOR)
		glEnable(GL_TEXTURE_2D)
		glPixelTransferi(GL_MAP_COLOR,GL_FALSE)



ImaginaryHuman(Posted 2005) [#6]
Anyone? Help help *jumps up and down*


ImaginaryHuman(Posted 2005) [#7]
Could it be that I'm defining the quads with the vertexes in the wrong order? Is there a particular sequence they're supposed to go in, certain corners that have to come first? Like bottom left, top left, top right, bottom right or something?


ImaginaryHuman(Posted 2005) [#8]
I'm wondering if this might explain it:

http://www.idevgames.com/forum/showthread.php?t=8215

I can't try anything till I get home from work *agh*


ImaginaryHuman(Posted 2005) [#9]
I guess I'm having a conversation with myself here, lol

I was given the idea that:

"glTexParameter only affects the currently-bound texture. You're calling it before you've bound your texture."

So I will try that this evening and see if it is the reason, it does make sense.


N(Posted 2005) [#10]
Yes you are. If I'd had any idea I would've responded already.


marksibly(Posted 2005) [#11]

"glTexParameter only affects the currently-bound texture. You're calling it before you've bound your texture."



Looking at it now, that would be my guess.

Mipmapping filtering is 'on' by default in GL (I think), and unloaded mipmaps typically (always?) come out white. Your TexParameter call is doing the right thing to turn off mipmapping but it's not doing it to the bound texture.

You've got a lot of code there, and much of it is redundant as OpenGL starts up in a known default state - you might wanna try stripping stuff out to make it easier to spot such problems.


Clyde(Posted 2005) [#12]
What is the default state then?


Shambler(Posted 2005) [#13]
An excellent OpenGL resource is here,
http://www.opengl.org/

And specifically number 5 on this page addresses the mipmapping issue,
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/index.html


ImaginaryHuman(Posted 2005) [#14]
Thanks. This did resolve the problem - just placing the filtering setup after the binding of the texture.

I don't know if I can trust that there is a default state accross all machine and all platforms. Otherwise, why did I have this problem only on my imac? In the software renderer on my ibook the texture showed up fine without the filtering being defined after the texture binding. So apparently it defaulted to something different than it does on the imac.

And yea, there's a lot of extra probably redundant code in there that I added just to try to get this thing working, it could be much simpler (I wanted to make sure I was covering all the bases and making sure everything was defined right).

I haven't figured out, though, why the GL_COLOR remapping does not work (in that second program) when it works fine on the ibook again. It doesn't upload any textures it just does a glCopyPixels. It copies pixels with the remapping off but not when it's on.