Graphics3D and GLGraphics
BlitzMax Forums/MiniB3D Module/Graphics3D and GLGraphics
| ||
Hi all, I may be wrong about this one... I guess I'm seeking confirmation from the experts. I've been revisiting my Shadow Mapping thing for the game, which, as it so turns out, has a few major flaws. To get some pointers in the right direction, I stumbled upon this thing from a while ago: BM OpenGL Programming: shadow mapping The code in that posts essentially works, on today's machines even nicely with a 512 shadow map (increase texsize to 512). You can do the minor adjustments required or you leave it, either way the mapping is pretty damn near perfect. I have been trying to sort of port this to MiniB3D - but I have come to a disconcerting revelation. It's not working for me so far, only parts of the shadow mapping is working. If you take the code above and just compile, it'll run pretty smoothly. However, when you replace GLGraphics 1024,768,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER with Import "minib3d.bmx" Graphics3D 1024,768,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER (if you use MiniB3D that way, otherwise import the module) and then run it, it'll be black. BUT! Press "n" on your keyboard to see the shadow map, you will notice that suddenly it runs horribly slow. So my guess is that it has to do with MiniB3D converting things into a 2D display of sorts (I have not checked the code in that detail), or maybe it has to do with VSync. Either way I'm pretty concerned about this, any insights into this are highly appreciated. If MiniB3D has always been this slow I will have no choice as to probably write my own 3D framework. Please advise. Thanks, Marcus Last edited 2012 |
| ||
Minib3d uses the glmax2ddriver, not glgraphics driver. Cheers Charlie |
| ||
Also, if you want to use raw gl stuff with minib3d your code has to go between renderworld and beginmax2d (if you're using max2d). Don't know if that's exactly what you're doing though. Cheers Charlie |
| ||
Hi Charlie, thanks for that pointer. I have changed the MiniB3D driver line to use the GLGraphicsDriver - not much seems to have changed. I am making progress though. |
| ||
Here's a somewhat working modification of the code from the other post, using MiniB3D. Things like TMesh don't yet work as I have to figure out a way to do this. I need to mention that in this implementation, the ground plane is not rendered - it was only a single face. However when a "closed" plane is used, it renders correctly. (???) Ah yes, also, the cylinder's "cap" is missing =/ 'shadowMap mark2 Import "minib3d.bmx" 'GLGraphics 1024,768,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER Graphics3D 1024,768,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER Global LIGHT_POS:Float[] = [ -60.0, 25.0, 0.0, 1.0 ] Global CAMERA_POS:Float[] = [0.0, 100.0, 150.0, 1.0 ] Global WHITE:Float[] =[ 1.0, 1.0, 1.0, 1.0] Global BLACK:Float[] =[ 0.0, 0.0, 0.0, 0.0] Global GREY:Float[] =[ 0.3, 0.3, 0.3, 0.3 ] Global DARK_GREY:Float[] = [0.1, 0.1, 0.1, 0.1] Global m_shadowMap:Int Global m_bounce:Float = 0.0 Global showShadowMap:Int = False Global noShadows:Int = False Global ambientShadowAvailable:Int = False Global m_windowHeight = 768 Global m_windowWidth = 1024 Global sPlane:Float[] = [1.0, 0.0, 0.0, 0.0] Global tPlane:Float[] = [0.0, 1.0, 0.0, 0.0] Global rPlane:Float[] = [0.0, 0.0, 1.0, 0.0] Global qPlane:Float[] = [0.0, 0.0, 0.0, 1.0] Global m_quadric:Byte Ptr m_quadric = gluNewQuadric() gluQuadricNormals(m_quadric, GLU_SMOOTH) Global modelview:Float[16], projection:Float[16] Global texsize:Int = 512 ' I added this Global cam:TCamera = CreateCamera() PositionEntity cam , 0.0 , 100.0 , 150.0 RotateEntity cam, 20, 0, 0 'Global light:TLight = CreateLight(2) 'PositionEntity light , 0 , 500 , 0 'LightRange light, 600 ' This does not show yet Global plane:TMesh = CreateCube() ScaleEntity plane , 50 , 0.01 , 50 PointEntity cam, plane '**************************************************** init() 'main loop While Not AppTerminate() And Not KeyDown(KEY_ESCAPE) update(1) RenderWorld() render() Flip If KeyHit(Key_N) showshadowmap = True If KeyHit(KEY_m) showshadowmap = False If KeyHit(KEY_O) noshadows = True If KeyHit(KEY_P) noshadows = False Wend End '***************************************************** Function Init() glewinit() glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glGenTextures(1, Varptr m_shadowMap) glBindTexture(GL_TEXTURE_2D, m_shadowMap) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) 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_DEPTH_TEXTURE_MODE, GL_INTENSITY) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE) glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR) glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR) glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR) glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR) glEnable(GL_LIGHT0) glEnable(GL_COLOR_MATERIAL) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR) glPolygonOffset(4.0, 0.0) End Function '**************************************************************** Function SetupProjection(width:Int, height:Int) glViewport( 0, 0, width, height ) ' // set up a perspective projection glMatrixMode( GL_PROJECTION ) glLoadIdentity() gluPerspective( 45.0, Float(width)/Float(height), 1.0, 1000.0 ) End Function '***************************************************************** Function Update( dt:Float ) m_bounce :+ 10 * dt End Function '***************************************************************** Function Render() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) GenerateShadowMap() '// Track camera angle glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45.0, 1.0, 1.0, 1000.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(CAMERA_POS[0], CAMERA_POS[1], CAMERA_POS[2],0.0, 0.0, 0.0, 0.0, 1.0, 0.0) glViewport(0, 0, 1024,768) '// Track light position glLightfv(GL_LIGHT0, GL_POSITION, LIGHT_POS) '// Clear the window with current clearing color glClear(GL_DEPTH_BUFFER_BIT) If showShadowMap = True Then ' // Display shadow map For educational purposes glMatrixMode(GL_PROJECTION) glLoadIdentity() glMatrixMode(GL_MODELVIEW) glLoadIdentity() glMatrixMode(GL_TEXTURE) glPushMatrix() glLoadIdentity() glEnable(GL_TEXTURE_2D) glDisable(GL_LIGHTING) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) '// Show the shadowMap at its actual size relative To window glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0) glVertex2f(-1.0, -1.0) glTexCoord2f(1.0, 0.0) glVertex2f((Float(texsize)/Float(1024))*2.0-1.0,-1.0) glTexCoord2f(1.0, 1.0) glVertex2f((Float(texsize)/Float(1024))*2.0-1.0,Float(texsize)/Float(768)*2.0-1.0) glTexCoord2f(0.0, 1.0) glVertex2f(-1.0,Float(texsize)/Float(768)*2.0-1.0) glEnd() glDisable(GL_TEXTURE_2D) glEnable(GL_LIGHTING) glPopMatrix() glMatrixMode(GL_PROJECTION) gluPerspective(45.0, 1.0, 1.0, 1000.0) glMatrixMode(GL_MODELVIEW) Else If noShadows = True ' // Set up some simple lighting glLightfv(GL_LIGHT0, GL_AMBIENT, GREY) glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE) '// Draw objects in the scene RenderObjects(False) Else If ambientShadowAvailable = False Then '// Because there is no support For an "ambient" '// shadow compare fail value, we'll have to '// draw an ambient pass first... glLightfv(GL_LIGHT0, GL_AMBIENT, GREY) glLightfv(GL_LIGHT0, GL_DIFFUSE, DARK_GREY) '// Draw objects in the scene RenderObjects(False) '// Enable alpha test so that shadowed fragments are discarded glAlphaFunc(GL_GREATER, 0.9) glEnable(GL_ALPHA_TEST) EndIf glLightfv(GL_LIGHT0, GL_AMBIENT, grey) glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE) '// Set up shadow comparison glEnable(GL_TEXTURE_2D) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE) '// Set up the eye plane For projecting the shadow map on the scene glEnable(GL_TEXTURE_GEN_S) glEnable(GL_TEXTURE_GEN_T) glEnable(GL_TEXTURE_GEN_R) glEnable(GL_TEXTURE_GEN_Q) glTexGenfv(GL_S, GL_EYE_PLANE, sPlane) glTexGenfv(GL_T, GL_EYE_PLANE, tPlane) glTexGenfv(GL_R, GL_EYE_PLANE, rPlane) glTexGenfv(GL_Q, GL_EYE_PLANE, qPlane) '// Draw objects in the scene RenderObjects(False) glDisable(GL_ALPHA_TEST) glDisable(GL_TEXTURE_2D) glDisable(GL_TEXTURE_GEN_S) glDisable(GL_TEXTURE_GEN_T) glDisable(GL_TEXTURE_GEN_R) glDisable(GL_TEXTURE_GEN_Q) EndIf End Function '******************************************************************** Function RenderObjects(isShadowPass:Int) glPushMatrix() glColor3f(0.2, 0.9, 0.3) glTranslatef(0.0, 5 + 5 * Sin(m_bounce), 0.0) glRotatef(-90.0, 1.0, 0.0, 0.0) gluCylinder(m_quadric, 10, 0, 20, 20, 20) glPopMatrix() glPushMatrix() glColor3f(0.75, 0.2, 0.1) glTranslatef(15.0, 5.0, 12 * Cos(m_bounce/3.0)) glusphere(M_quadric,5,20,20) glPopMatrix() glPushMatrix() glColor3f(0.5, 0.1, 0.9) glTranslatef(28.0, 6.0, -24.0) glRotatef(30.0, 0.0, 1.0, 0.0) glucylinder(m_quadric,6, 6, 20, 20, 20) glPopMatrix() glDisable(GL_LIGHTING) glPushMatrix() glColor3f(1,1,1) glTranslatef(light_pos[0],light_pos[1],light_pos[2]) glusphere(m_quadric,1,20,20) glPopMatrix() glEnable(GL_LIGHTING) glPushMatrix() glColor3f(.75,.75,.95) For Local i = -50 To 50 Step 20 For Local j = -50 To 50 Step 20 glBegin(GL_QUADS) glNormal3f(0 , 1 , 0) glVertex3f( 50.0, 1.0,-50.0)' // Top Right Of The Quad (Top) glVertex3f(-50.0, 1.0,-50.0)' // Top Left Of The Quad (Top) glVertex3f(-50.0, 1.0, 50.0)' // Bottom Left Of The Quad (Top) glVertex3f( 50.0, 1.0, 50.0)' // Bottom Right Of The Quad (Top) glVertex3f( 50.0,-1.0, 50.0)' // Top Right Of The Quad (Bottom) glVertex3f(-50.0,-1.0, 50.0)' // Top Left Of The Quad (Bottom) glVertex3f(-50.0,-1.0,-50.0)' // Bottom Left Of The Quad (Bottom) glVertex3f( 50.0,-1.0,-50.0)' // Bottom Right Of The Quad (Bottom) glVertex3f( 50.0, 1.0, 50.0)' // Top Right Of The Quad (Front) glVertex3f(-50.0, 1.0, 50.0)' // Top Left Of The Quad (Front) glVertex3f(-50.0,-1.0, 50.0)' // Bottom Left Of The Quad (Front) glVertex3f( 50.0,-1.0, 50.0)' // Bottom Right Of The Quad (Front) glVertex3f( 50.0,-1.0,-50.0)' // Top Right Of The Quad (Back) glVertex3f(-50.0,-1.0,-50.0)' // Top Left Of The Quad (Back) glVertex3f(-50.0, 1.0,-50.0)' // Bottom Left Of The Quad (Back) glVertex3f( 50.0, 1.0,-50.0)' // Bottom Right Of The Quad (Back) glVertex3f(-50.0, 1.0, 50.0)' // Top Right Of The Quad (Left) glVertex3f(-50.0, 1.0,-50.0)' // Top Left Of The Quad (Left) glVertex3f(-50.0,-1.0,-50.0)' // Bottom Left Of The Quad (Left) glVertex3f(-50.0,-1.0, 50.0)' // Bottom Right Of The Quad (Left) glVertex3f( 50.0, 1.0,-50.0)' // Top Right Of The Quad (Right) glVertex3f( 50.0, 1.0, 50.0)' // Top Left Of The Quad (Right) glVertex3f( 50.0,-1.0, 50.0)' // Bottom Left Of The Quad (Right) glVertex3f( 50.0,-1.0,-50.0)' // Bottom Right Of The Quad (Right) 'glVertex3f(i + 10 , 0 , j + 10) 'glVertex3f(i + 10 , 1 , j + 10) 'glVertex3f(i - 10 , 0 , j + 10) 'glVertex3f(i - 10 , 1 , j + 10) 'glVertex3f(i - 10 , 0 , j - 10) 'glVertex3f(i - 10 , 1 , j - 10) 'glVertex3f(i + 10 , 0 , j - 10) 'glVertex3f(i + 10 , 1 , j - 10) glEnd() Next Next glPopMatrix() End Function '************************************************************* Function GenerateShadowMap() Local lightToSceneDistance:Float, nearPlane:Float, fieldOfView:Float Local lightModelview:Float[16], lightProjection:Float [16] '// Save the depth precision For where it's useful lightToSceneDistance = Sqr(LIGHT_POS[0]*LIGHT_POS[0]+LIGHT_POS[1]*LIGHT_POS[1]+LIGHT_POS[2]*LIGHT_POS[2]) nearPlane = lightToSceneDistance - 150.0 If nearPlane < 50.0 nearPlane = 50.0 '// Keep the scene filling the depth texture fieldOfView = 17000.0 / lightToSceneDistance glViewport(0, 0, texsize, texsize) glMatrixMode(GL_PROJECTION) glLoadIdentity() 'glFrustum(-12.0, 12.0, -20.0, 5.0, 13.0, 150.0) gluPerspective( 60,1, 13, 1000 ) glGetFloatv(GL_PROJECTION_MATRIX, lightProjection) '// Switch To light's point of view glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(LIGHT_POS[0], LIGHT_POS[1], LIGHT_POS[2],0.0, 0.0, 0.0, 0.0, 1.0, 0.0) glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview) '// Clear the window with current clearing color glClear(GL_DEPTH_BUFFER_BIT) '// All we care about here is resulting depth values glShadeModel(GL_FLAT) glDisable(GL_LIGHTING) glDisable(GL_COLOR_MATERIAL) glDisable(GL_NORMALIZE) glColorMask(0, 0, 0, 0) '// Overcome imprecision glEnable(GL_POLYGON_OFFSET_FILL) '// Draw objects in the scene RenderObjects(True) '// Copy depth values into depth texture glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,0, 0, texsize, texsize, 0) '// Restore normal drawing state glShadeModel(GL_SMOOTH) glEnable(GL_LIGHTING) glEnable(GL_COLOR_MATERIAL) glEnable(GL_NORMALIZE) glColorMask(1, 1, 1, 1) glDisable(GL_POLYGON_OFFSET_FILL) '// Set up texture matrix For shadow map projection glMatrixMode(GL_TEXTURE) glLoadIdentity() glTranslatef(0.5, 0.5, 0.5) glScalef(0.5, 0.5, 0.5) glMultMatrixf(lightProjection) glMultMatrixf(lightModelview) End Function '******************************************************** Last edited 2012 |
| ||
I believe the issue is caused by how you invoke Graphics3D.Function Graphics3D(width:Int,height:Int,depth:Int=0,mode:Int=0,rate:Int=60,flags:Int=-1) 'SMALLFIXES added flags TGlobal.Graphics3D(width,height,depth,mode,rate,flags) End Function It is compatible with Blitz3D, not the new BlitzMax graphics system. Currently, you are setting the hertz value to, I believe, three. It should be, 'GLGraphics 1024,768,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER Graphics3D 1024,768,0,0,60,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER |
| ||
I'll be damned :D haha - how could I have missed that |
| ||
I've looked at getting shadow mapping into minib3d before but didn't get very far. I can say that I don't think you'll be able to do it "externally" you'll have to integrate it properly into the minib3d render process. Looking at klepto's minib3dextnew mod to see how he fit his stencil shadow system into the minib3d framework might be instructive (but please don't use stencil shadows). It might give a few clues as to where the intercept points should be. ps I find just using "Graphics3D 1024,768" is pretty fast for some reason |
| ||
I was looking at implementing those stencil shadows... but it came at a prize. While the shadows do work, it messes up the rest. So that's not an option. I really want the code from that post I found. Seems I have two options - either try to implement it somehow, or adapt my engine around the code with the shadows. I don't want to do the latter... but maybe I don't have a choice. I want my game to be really nice-looking |
| ||
this is where minib3d needs an update, to handle shader and fbo tricks and to isolate rendering of specific objects tied to specific cameras. i have my own in progress, but monkey+minib3d has priority for now. |
| ||
I'm looking at different approaches for Shadow Mapping at this point. I'll let you know if I have anything worth showing. |