Advertisement

Lesson 26 don't work

Started by November 09, 2005 09:58 AM
4 comments, last by eSCHEn 19 years ago
I tried to use code in lesson 26 with the stencil function that might prevent object from drawing outside some region, but this don't works.. just like i have no stencil function at all. here is code (i just removed lights)

 Protected Overrides Sub InitGLContext()
   GL.glShadeModel(Convert.ToUInt32(GLFlags.GL_SMOOTH))              '// Enable Smooth Shading
   GL.glClearColor(0.0F, 0.0F, 0.0F, 0.5F)    '// Black Background
   GL.glClearDepth(1.0F)                     '// Depth Buffer Setup
   GL.glClearStencil(0)
   GL.glEnable(Convert.ToUInt32(GLFlags.GL_DEPTH_TEST))        '// Enables Depth Testing
   GL.glDepthFunc(Convert.ToUInt32(GLFlags.GL_LEQUAL))        '// The Type Of Depth Testing To Do
   GL.glHint(Convert.ToUInt32(GLFlags.GL_PERSPECTIVE_CORRECTION_HINT), Convert.ToUInt32(GLFlags.GL_NICEST))  '// Really Nice Perspective Calculations
   GL.glHint(Convert.ToUInt32(GLFlags.GL_POINT_SMOOTH_HINT), Convert.ToUInt32(GLFlags.GL_NICEST))   '// Really Nice Perspective Calculations

   GL.glEnable(Convert.ToUInt32(GLFlags.GL_TEXTURE_2D))

   Dim Image As Bitmap = New Bitmap("..\water.bmp")
   Image.RotateFlip(RotateFlipType.RotateNoneFlipY)

   Dim bitmapdata As System.Drawing.Imaging.BitmapData
   Dim rect As Rectangle = New Rectangle(0, 0, Image.Width, Image.Height)

   bitmapdata = Image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, Drawing.Imaging.PixelFormat.Format24bppRgb)

   GL.glGenTextures(1, texture)
   GL.glBindTexture(Convert.ToUInt32(GLFlags.GL_TEXTURE_2D), texture(0))
   GL.glTexImage2D(Convert.ToUInt32(GLFlags.GL_TEXTURE_2D), 0, Convert.ToInt32(GLFlags.GL_RGB8), _
                   Image.Width, Image.Height, 0, Convert.ToUInt32(GLFlags.GL_BGR), _
                   Convert.ToUInt32(GLFlags.GL_UNSIGNED_BYTE), bitmapdata.Scan0)
   GL.glTexParameteri(Convert.ToUInt32(GLFlags.GL_TEXTURE_2D), Convert.ToUInt32(GLFlags.GL_TEXTURE_MIN_FILTER), Convert.ToUInt32(9729))   '// Linear Filtering
   GL.glTexParameteri(Convert.ToUInt32(GLFlags.GL_TEXTURE_2D), Convert.ToUInt32(GLFlags.GL_TEXTURE_MAG_FILTER), Convert.ToUInt32(9729))     '// Linear Filtering
 
   Image.UnlockBits(bitmapdata)
   Image.Dispose()

   GL.glTexGeni(Convert.ToUInt32(GLFlags.GL_S), Convert.ToUInt32(GLFlags.GL_TEXTURE_GEN_MODE), GLFlags.GL_SPHERE_MAP)
   GL.glTexGeni(Convert.ToUInt32(GLFlags.GL_T), Convert.ToUInt32(GLFlags.GL_TEXTURE_GEN_MODE), GLFlags.GL_SPHERE_MAP)
  
End Sub

Public Overrides Sub glDraw()
   Dim high As Integer = 1
  
   GL.glClear(Convert.ToUInt32(GLFlags.GL_COLOR_BUFFER_BIT Or GLFlags.GL_DEPTH_BUFFER_BIT Or GLFlags.GL_STENCIL_BUFFER_BIT))  '// Clear Screen and Depth Buffer
   Dim clipp() As Double = {0, -1, 0, 0}

   GL.glMatrixMode(Convert.ToUInt32(GLFlags.GL_MODELVIEW))
   GL.glLoadIdentity()           '// reset the current modelview matrix
   GL.glTranslatef(0.0F, -1.0F, -8.0F)      '// move 5 Units into the screen

   GL.glColorMask(0, 0, 0, 0)
   GL.glEnable(Convert.ToUInt32(GLFlags.GL_STENCIL_TEST))
   GL.glDisable(Convert.ToUInt32(GLFlags.GL_DEPTH_TEST))
   GL.glStencilFunc(Convert.ToUInt32(GLFlags.GL_ALWAYS), 1, Convert.ToUInt32(1))
   GL.glStencilOp(Convert.ToUInt32(GLFlags.GL_KEEP), Convert.ToUInt32(GLFlags.GL_KEEP), Convert.ToUInt32(GLFlags.GL_REPLACE))
   
   GL.glBegin(Convert.ToUInt32(GLFlags.GL_QUADS))
   GL.glNormal3f(0, 1, 0)
   GL.glVertex3f(-3, -0, -3)
   GL.glVertex3f(3, -0, -3)
   GL.glVertex3f(3, -0, 3)
   GL.glVertex3f(-3, -0, 3)
   GL.glEnd()

   GL.glEnable(Convert.ToUInt32(GLFlags.GL_DEPTH_TEST))
   GL.glColorMask(1, 1, 1, 1)
   GL.glStencilFunc(Convert.ToUInt32(GLFlags.GL_EQUAL), 1, Convert.ToUInt32(1))
   GL.glStencilOp(Convert.ToUInt32(GLFlags.GL_KEEP), Convert.ToUInt32(GLFlags.GL_KEEP), Convert.ToUInt32(GLFlags.GL_KEEP))
   
   GL.glClipPlane(Convert.ToUInt32(GLFlags.GL_CLIP_PLANE0), clipp)
   GL.glEnable(Convert.ToUInt32(GLFlags.GL_CLIP_PLANE0))
   GL.glPushMatrix()
   GL.glScaled(1, -1, 1)
 
   GL.glTranslatef(0, high, 0)
   GL.glRotatef(xrot, 1.0F, 0.0F, 0.0F) '// rotate on the X-axis
   GL.glRotatef(yrot, 0.0F, 1.0F, 0.0F) '// rotate on the Y-axis
   GL.glRotatef(zrot, 0.0F, 0.0F, 1.0F) '// rotate on the Z-axis
   GL.glColor4f(1, 1, 1, 1)
   GL.glBindTexture(Convert.ToUInt32(GLFlags.GL_TEXTURE_2D), texture(0))
   GL.glBegin(Convert.ToUInt32(GLFlags.GL_QUADS))
   '// Front Face
   GL.glNormal3f(0, 0, 0.5)
   GL.glTexCoord2f(1.0F, 1.0F) '// top right of texture
   GL.glVertex3f(1.0F, 1.0F, 1.0F) '// top right of quad
   GL.glTexCoord2f(0.0F, 1.0F)  '// top left of texture
   GL.glVertex3f(-1.0F, 1.0F, 1.0F) '// top left of quad
   GL.glTexCoord2f(0.0F, 0.0F)  '// bottom left of texture
   GL.glVertex3f(-1.0F, -1.0F, 1.0F) '// bottom left of quad
   GL.glTexCoord2f(1.0F, 0.0F) '// bottom right of texture
   GL.glVertex3f(1.0F, -1.0F, 1.0F) '// bottom right of quad

   '// Back Face
   GL.glNormal3f(0, 0, -0.5)
   GL.glTexCoord2f(1.0F, 1.0F)  '// top right of texture
   GL.glVertex3f(-1.0F, 1.0F, -1.0F) '// top right of quad
   GL.glTexCoord2f(0.0F, 1.0F)  '// top left of texture
   GL.glVertex3f(1.0F, 1.0F, -1.0F) '// top left of quad
   GL.glTexCoord2f(0.0F, 0.0F)  '// bottom left of texture
   GL.glVertex3f(1.0F, -1.0F, -1.0F) '// bottom left of quad
   GL.glTexCoord2f(1.0F, 0.0F)  '// bottom right of texture
   GL.glVertex3f(-1.0F, -1.0F, -1.0F) '// bottom right of quad

   '// Top Face
   GL.glNormal3f(0, 0.5, 0)
   GL.glTexCoord2f(1.0F, 1.0F)  '// top right of texture
   GL.glVertex3f(1.0F, 1.0F, -1.0F) '// top right of quad
   GL.glTexCoord2f(0.0F, 1.0F)  '// top left of texture
   GL.glVertex3f(-1.0F, 1.0F, -1.0F) '// top left of quad
   GL.glTexCoord2f(0.0F, 0.0F)  '// bottom left of texture
   GL.glVertex3f(-1.0F, 1.0F, 1.0F) '// bottom left of quad
   GL.glTexCoord2f(1.0F, 0.0F)  '// bottom right of texture
   GL.glVertex3f(1.0F, 1.0F, 1.0F) '// bottom right of quad

   '// Bottom Face
   GL.glNormal3f(0, -0.5, 0)
   GL.glTexCoord2f(1.0F, 1.0F)  '// top right of texture
   GL.glVertex3f(1.0F, -1.0F, 1.0F) '// top right of quad
   GL.glTexCoord2f(0.0F, 1.0F)  '// top left of texture
   GL.glVertex3f(-1.0F, -1.0F, 1.0F) '// top left of quad
   GL.glTexCoord2f(0.0F, 0.0F)  '// bottom left of texture
   GL.glVertex3f(-1.0F, -1.0F, -1.0F) '// bottom left of quad
   GL.glTexCoord2f(1.0F, 0.0F)  '// bottom right of texture
   GL.glVertex3f(1.0F, -1.0F, -1.0F) '// bottom right of quad

   '// Right Face
   GL.glNormal3f(0.5, 0, 0)
   GL.glTexCoord2f(1.0F, 1.0F)  '// top right of texture
   GL.glVertex3f(1.0F, 1.0F, -1.0F) '// top right of quad
   GL.glTexCoord2f(0.0F, 1.0F)  '// top left of texture
   GL.glVertex3f(1.0F, 1.0F, 1.0F) '// top left of quad
   GL.glTexCoord2f(0.0F, 0.0F)  '// bottom left of texture
   GL.glVertex3f(1.0F, -1.0F, 1.0F) '// bottom left of quad
   GL.glTexCoord2f(1.0F, 0.0F)  '// bottom right of texture
   GL.glVertex3f(1.0F, -1.0F, -1.0F) '// bottom right of quad

   '// Left Face
   GL.glNormal3f(-0.5, 0, 0)
   GL.glTexCoord2f(1.0F, 1.0F)  '// top right of texture
   GL.glVertex3f(-1.0F, 1.0F, 1.0F) '// top right of quad
   GL.glTexCoord2f(0.0F, 1.0F)  '// top left of texture
   GL.glVertex3f(-1.0F, 1.0F, -1.0F) '// top left of quad
   GL.glTexCoord2f(0.0F, 0.0F)  '// bottom left of texture
   GL.glVertex3f(-1.0F, -1.0F, -1.0F) '// bottom left of quad
   GL.glTexCoord2f(1.0F, 0.0F)  '// bottom right of texture
   GL.glVertex3f(-1.0F, -1.0F, 1.0F) '// bottom right of quad
   GL.glEnd()
   GL.glTranslatef(0, -high, 0)

   GL.glPopMatrix()
   GL.glDisable(Convert.ToUInt32(GLFlags.GL_CLIP_PLANE0))
   GL.glDisable(Convert.ToUInt32(GLFlags.GL_STENCIL_TEST))

   GL.glEnable(Convert.ToUInt32(GLFlags.GL_BLEND))
   GL.glBlendFunc(Convert.ToUInt32(GLFlags.GL_SRC_ALPHA), Convert.ToUInt32(GLFlags.GL_ONE_MINUS_SRC_ALPHA))
   GL.glColor4f(1, 1, 1, 0.8)

   GL.glBegin(Convert.ToUInt32(GLFlags.GL_QUADS))
   GL.glNormal3f(0, 1, 0)
   GL.glVertex3f(-3, -0, -3)
   GL.glVertex3f(3, -0, -3)
   GL.glVertex3f(3, -0, 3)
   GL.glVertex3f(-3, -0, 3)
   GL.glEnd()

   GL.glDisable(Convert.ToUInt32(GLFlags.GL_BLEND))

   xrot += 0.3F     '// X-axis rotation
   yrot += 0.2F     '// Y-axis rotation
   zrot += 0.4F   '// Z-axis rotation
   
End Sub

I'm not using glu predefined objects, just drawing a standart cube for a lesson 6, and also i removed a part where i draw original cube, just left the mirror-image drawing part.. I have no idea how to post screenshot here but what i got is the blue-looking floor and cube beneath it. It's clipped right, but the bottom part of it, that is out of floor range is still showed, and as i understand using stencil function i draw cube only inside floor-area. When i try to remove "disable gl_depth_test" before i draw a invisible floor to mark out a stencil area i got another strange result - top part of cube that might be seen inside of floor removed, and the out-of-floor part is noy removed(inverse result of what i want). The second i guess maybe something wrong and replaced GL_EQUAL in my second stencil function to opposite GL_NOT_EUQAL and nothing changed at all, like this function don't works at all.... [Edited by - Centurion on November 11, 2005 6:20:35 PM]
Yup, I had the same problem when I didn't read the tutorial properly & tried to use it in my own program. Have you set the PIXELFORMATDESCRIPTOR in your window setup code to use stencil buffers?

static	PIXELFORMATDESCRIPTOR pfd=					// pfd Tells Windows How We Want Things To Be	{		sizeof(PIXELFORMATDESCRIPTOR),					// Size Of This Pixel Format Descriptor		1,								// Version Number		PFD_DRAW_TO_WINDOW |						// Format Must Support Window		PFD_SUPPORT_OPENGL |						// Format Must Support OpenGL		PFD_DOUBLEBUFFER,						// Must Support Double Buffering		PFD_TYPE_RGBA,							// Request An RGBA Format		bits,								// Select Our Color Depth		0, 0, 0, 0, 0, 0,						// Color Bits Ignored		0,								// No Alpha Buffer		0,								// Shift Bit Ignored		0,								// No Accumulation Buffer		0, 0, 0, 0,							// Accumulation Bits Ignored		16,								// 16Bit Z-Buffer (Depth Buffer)		1,								// Use Stencil Buffer ( * Important * )		0,								// No Auxiliary Buffer		PFD_MAIN_PLANE,							// Main Drawing Layer		0,								// Reserved		0, 0, 0								// Layer Masks Ignored};


Also for future reference when posting code, use the source tags
"I must not fear. Fear is the mindkiller. Fear is the little death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past me I will turn to see fear's path. Where the fear has gone there will be nothing. Only I will remain." ~Frank Herbert, DuneMy slice of the web
Advertisement
Quote: Original post by DrewGreen

16, // 16Bit Z-Buffer (Depth Buffer)
1, // Use Stencil Buffer ( * Important * )


just an addition to this
try 24 and 8 for better z space resolution and more stencil layers(you will need it for tut 27, or at least if you start fiddeling around with it).
So problem is in some flag enabling use of stencil buffer at initialization. BUT. I'm using CsGL library so i have a problem adding this flag here.

protected virtual OpenGLContext CreateContext(){ ControlGLContext c = new ControlGLContext(this); c.Create(new DisplayType(0,0), null); return c;}

That's the initialization code in that library i can change (and i need to i think). This one uses DisplayType to make a new OpenGlContext. But when i making my own gl context i can use only this flags -

DOUBLEBUFFER = 0x0001DRAW_TO_BITMAP = 0x0008 DRAW_TO_WINDOW = 0x0004STEREO = 0x0002SUPPORT_GDI = 0x0010


And there is no option to enable of disable stencil buffer so i think i need to add some flag here because using this standart flags the biggest value i can make is 0x1F, but when i'm retreving standartly created PixelFormat (it's the DisplayType called in CsGL, not PIXELFORMATDESCRITOR) i got value of 0x225, so there is other flags and one of them must enable using stencil buffer. I tried to change the code to add stencil buffer bits (there was zero stencil bits in standartly created control) but that don't helps, i got that bits, but stencil buffer still not works...


I don't know why this happens this way, but i got it working !!! Here is how i done that:

Firstly i added stencil buffer bits 8 and create context function
Protected Overrides Function CreateContext() As OpenGLContext Dim c As ControlGLContext = New ControlGLContext(Me) Dim disp As New DisplayType(0, 0, 8, 0) c.Create(disp, Nothing) Return cEnd Function


After i tried that nothing changed so i feel like stencil wasn't enabled, but it's got enabled. Secondly i started to "play" with parameters for glStencilFunc and finnaly i got that working. In tutorial is said to use it that way
glStencilFunc(GL_ALWAYS, 1, 1)glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE)' drawing floorglStencilFunc(GL_EQUAL, 1, 1)glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP)' drawing mirrored image

but as i said that doesn't worked so here is how it worked for me

glStencilFunc(GL_ALWAYS, 0, 1)glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE)' drawing floorglStencilFunc(GL_EQUAL, 0, 1)glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP)' drawing mirrored image

I have no idea what that second and third parameter exactly means but now it's worked !!!
This is from the OpenGL reference:
glStencilFuncThe glStencilFunc function sets the function and reference value for stencil testing.void glStencilFunc(GLenum func, GLint ref, GLuint mask);ParametersfuncSpecifies the test function. Eight tokens are valid: GL_NEVER, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL, GL_EQUAL, GL_NOTEQUAL, and GL_ALWAYS. refSpecifies the reference value for the stencil test. ref is clamped to the range [0,2^n - 1], where n is the number of bitplanes in the stencil buffer. maskSpecifies a mask that is ANDed with both the reference value and the stored stencil value when the test is done.RemarksStenciling, like z-buffering, enables and disables drawing on a per-pixel basis. You draw into the stencil planes using GL drawing primitives, then render geometry and images, using the stencil planes to mask out portions of the screen. Stenciling is typically used in multipass rendering algorithms to achieve special effects, such as decals, outlining, and constructive solid geometry rendering.The stencil test conditionally eliminates a pixel based on the outcome of a comparison between the reference value and the value in the stencil buffer. The test is enabled by glEnable and glDisable with argument GL_STENCIL. Actions taken based on the outcome of the stencil test are specified with glStencilOp.The func parameter is a symbolic constant that determines the stencil comparison function. It accepts one of eight values, shown below. ref is an integer reference value that is used in the stencil comparison. It is clamped to the range [0,2^n - 1], where n is the number of bitplanes in the stencil buffer. mask is bitwise ANDed with both the reference value and the stored stencil value, with the ANDed values participating in the comparison.If stencil represents the value stored in the corresponding stencil buffer location, the following list shows the effect of each comparison function that can be specified by func. Only if the comparison succeeds is the pixel passed through to the next stage in the rasterization process (see glStencilOp). All tests treat stencil values as unsigned integers in the range [0,2^n - 1], where n is the number of bitplanes in the stencil buffer.Here are the values accepted by func:GL_NEVERAlways fails. GL_LESSPasses if ( ref & mask) < ( stencil & mask).  GL_LEQUALPasses if ( ref & mask) £ ( stencil & mask). GL_GREATERPasses if ( ref & mask) > ( stencil & mask). GL_GEQUALPasses if ( ref & mask) ³ ( stencil & mask). GL_EQUALPasses if ( ref & mask) = ( stencil & mask). GL_NOTEQUALPasses if ( ref & mask) ¹  ( stencil & mask). GL_ALWAYSAlways passes.Initially, the stencil test is disabled. If there is no stencil buffer, no stencil modification can occur and it is as if the stencil test always passes.The following functions retrieve information related to the glStencilFunc function:glGet with argument GL_STENCIL_FUNCglGet with argument GL_STENCIL_VALUE_MASKglGet with argument GL_STENCIL_REFglGet with argument GL_STENCIL_BITSglIsEnabled with argument GL_STENCIL_TESTErrorsGL_INVALID_ENUM is generated if func is not one of the eight accepted values.GL_INVALID_OPERATION is generated if glStencilFunc is called between a call to glBegin and the corresponding call to glEnd.See AlsoglAlphaFunc, glBlendFunc, glDepthFunc, glEnable, glIsEnabled, glLogicOp, glStencilOp 


Have a look at this thread, there are links to the Red and Blue books which will guide you well.

Hope that's useful. :)
--
Cheers,
Darren Clark

This topic is closed to new replies.

Advertisement