Author Topic: Masking an Opengl texture  (Read 6196 times)

0 Members and 1 Guest are viewing this topic.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Masking an Opengl texture
« on: April 27, 2008 »
Any way to mask certain colours in an opengl texture map?

For example, how can I stop it drawing the pure white texels in this program; ?

I've been right through the red book and I cant seem to find what I need..

Code: [Select]
option explicit
option static

'-------------------------------------
' Includes
'-------------------------------------
#include "GL/gl.bi"
#include "GL/glu.bi"
#include "windows.bi"


dim shared pfd as PIXELFORMATDESCRIPTOR
dim shared hdc as hDC
declare sub InitOGL()
DECLARE SUB LOGO_TEXTURE()


InitOGL()

'===============================================================================
' LOGO XOR TEXTURE GENERATION;
'===============================================================================
    DIM SHARED AS UINTEGER LOGOBUFFER ( 256 * 256 )
    DIM SHARED tex1 AS GLUINT
DIM AS UINTEGER X,Y,PIXEL


for y = 0 TO 255

for x = 0 TO 255

PIXEL = X XOR Y
            pixel=int(rnd(1)*2)
            if pixel=1 then
                PIXEL=255
                   else
                PIXEL=100
            end if
LOGOBUFFER((y * 256)+X) = RGBA(PIXEL,PIXEL,PIXEL,255)

        NEXT
    NEXT

glGenTextures 1, @tex1
glBindTexture(GL_TEXTURE_2D, tex1)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR)
gluBuild2DMipmaps (GL_TEXTURE_2D, 3, 256, 256,GL_RGBA, GL_UNSIGNED_BYTE, @LOGOBUFFER(0)) 

'===============================================================================
' MAIN LOOP
'===============================================================================
while(GetAsyncKeyState(VK_ESCAPE)<>-32767)
    glClear(GL_DEPTH_BUFFER_BIT + GL_COLOR_BUFFER_BIT )
 
    LOGO_TEXTURE()

    SwapBuffers(hDC)
wend

'===============================================================================
' Initialise OpenGL
'===============================================================================
sub InitOGL()
pfd.cColorBits = 32
    pfd.cDepthBits = 32
pfd.dwFlags    = PFD_SUPPORT_OPENGL + PFD_DOUBLEBUFFER
    hDC = GetDC(CreateWindow("edit", 0,WS_POPUP+WS_VISIBLE+WS_MAXIMIZE,0, 0, 0 , 0, 0, 0, 0, 0))
SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, @pfd) , @pfd )
wglMakeCurrent ( hDC, wglCreateContext(hDC) )
    ShowCursor(FALSE)
   
glMatrixMode(GL_PROJECTION)
gluPerspective(45.0f,1024/768,0.1f,100.0f)
glMatrixMode(GL_MODELVIEW)
   
end sub

'===============================================================================
'                              DRAW THE "LOGO"
'===============================================================================
SUB LOGO_TEXTURE()
 
    glLoadIdentity()
 
    glTranslatef(0, 0, -6)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, tex1)
glenable gl_blend
    GLBEGIN GL_QUADS
   
      glNormal3f  0.0f, 0.0f, 1.0f
      glTexCoord2f 0.0, 0.0
      glVertex3f -1.0f, -1.0f,  1.0f
      glTexCoord2f 1.0, 0.0
      glVertex3f  1.0f, -1.0f,  1.0f
      glTexCoord2f 1.0, 1.0
      glVertex3f  1.0f,  1.0f,  1.0f
      glTexCoord2f 0.0, 1.0
      glVertex3f -1.0f,  1.0f,  1.0f
     
    GLEND
gldisable gl_blend
END SUB
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Masking an Opengl texture
« Reply #1 on: April 27, 2008 »
Unfortunately glColorMask only deals with the whole colour component and isn't much use, If you have regions of a texture that you want to be able to hide or show you could maybe set the alpha values in the texture and use glAlphaFunc and glEnable(GL_ALPHA_TEST)

It's just a thought and I've never tried it so I don't know if it'll work or not.


Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Masking an Opengl texture
« Reply #2 on: April 27, 2008 »
Just tried it and it looks like you could come up with some interesting effects with it.

Code: [Select]
option explicit
option static

'-------------------------------------
' Includes
'-------------------------------------
#include "GL/gl.bi"
#include "GL/glu.bi"
#include "windows.bi"


dim shared pfd as PIXELFORMATDESCRIPTOR
dim shared hdc as hDC
declare sub InitOGL()
DECLARE SUB LOGO_TEXTURE(byval a as single)


InitOGL()

'===============================================================================
' LOGO XOR TEXTURE GENERATION;
'===============================================================================
    DIM SHARED AS UINTEGER LOGOBUFFER ( 256 * 256 )
    DIM SHARED tex1 AS GLUINT
DIM AS UINTEGER X,Y,PIXEL


for y = 0 TO 255

for x = 0 TO 255

PIXEL = X XOR Y
            pixel=int(rnd(1)*2)
            if pixel=1 then
                PIXEL=255
                   else
                PIXEL=100
            end if
LOGOBUFFER((y * 256)+X) = RGBA(PIXEL,PIXEL,PIXEL,(PIXEL+y)shr 1)

        NEXT
    NEXT

glGenTextures 1, @tex1
glBindTexture(GL_TEXTURE_2D, tex1)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR)
gluBuild2DMipmaps (GL_TEXTURE_2D, 4, 256, 256,GL_RGBA, GL_UNSIGNED_BYTE, @LOGOBUFFER(0)) 

'===============================================================================
' MAIN LOOP
'===============================================================================
dim as single af
while(GetAsyncKeyState(VK_ESCAPE)<>-32767)
    glClear(GL_DEPTH_BUFFER_BIT + GL_COLOR_BUFFER_BIT )
 
    LOGO_TEXTURE(.5+.5*sin(af))
    af+=.01
    sleep 10
    SwapBuffers(hDC)
wend

'===============================================================================
' Initialise OpenGL
'===============================================================================
sub InitOGL()
pfd.cColorBits = 32
    pfd.cDepthBits = 32
pfd.dwFlags    = PFD_SUPPORT_OPENGL + PFD_DOUBLEBUFFER
    hDC = GetDC(CreateWindow("edit", 0,WS_POPUP+WS_VISIBLE+WS_MAXIMIZE,0, 0, 0 , 0, 0, 0, 0, 0))
SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, @pfd) , @pfd )
wglMakeCurrent ( hDC, wglCreateContext(hDC) )
    ShowCursor(FALSE)
   
glMatrixMode(GL_PROJECTION)
gluPerspective(45.0f,1024/768,0.1f,100.0f)
glMatrixMode(GL_MODELVIEW)
   
end sub

'===============================================================================
'                              DRAW THE "LOGO"
'===============================================================================
SUB LOGO_TEXTURE(byval a as single)
 
  glenable(gl_alpha_test)
  glalphafunc(gl_less,a)
    glLoadIdentity()
 
    glTranslatef(0, 0, -6)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, tex1)
glenable gl_blend
    GLBEGIN GL_QUADS
      glNormal3f  0.0f, 0.0f, 1.0f
      glTexCoord2f 0.0, 0.0
      glVertex3f -1.0f, -1.0f,  1.0f
      glTexCoord2f 1.0, 0.0
      glVertex3f  1.0f, -1.0f,  1.0f
      glTexCoord2f 1.0, 1.0
      glVertex3f  1.0f,  1.0f,  1.0f
      glTexCoord2f 0.0, 1.0
      glVertex3f -1.0f,  1.0f,  1.0f
     
    GLEND
gldisable gl_blend
gldisable(gl_alpha_test)
END SUB

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Masking an Opengl texture
« Reply #3 on: April 27, 2008 »
How cool is that!

Thanks mate!  :clap:

Just found gl_stencil_func too..  I am having a look at it.

Shockwave ^ Codigos
Challenge Trophies Won:

Offline Dr_D

  • Atari ST
  • ***
  • Posts: 151
  • Karma: 29
    • View Profile
Re: Masking an Opengl texture
« Reply #4 on: April 27, 2008 »
Well, you could use a shader to do this, but then your program would only run on cards that can handle shader model 2.0. The good news is that GLSL is very similar to C/C++, so the learning curve is moderate for people with any experience in C or C++. I would have modified you code to show you, but I'm not sure how to go about getting at the function pointers for OpenGL extensions without a library like GLEW, GLFW or FBGFX.  I'm sure there is a way to do it with the windows api, but I don't now how.
The Dr. is INsane!!!

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Masking an Opengl texture
« Reply #5 on: April 27, 2008 »
Cheers Dr. D This needs to have maximum compatibility though so I need to stay away from shaders.

Stonemonkey's solution is working here I am wondering how fast it is though.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Masking an Opengl texture
« Reply #6 on: April 27, 2008 »
That's definitely the way to do it - set the alpha to 0 where you want it transparent and use glAlphaFunc(GL_NOTEQUAL,0) to cut off those values.  This is very fast.

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Masking an Opengl texture
« Reply #7 on: April 27, 2008 »
TBH, no idea about the speed of it but I'd imagine there'd not be much difference using the alpha test or not. It will have to do the texture fetch before doing the test so might be very slightly slower for a large number of fragments that pass the z test.

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Masking an Opengl texture
« Reply #8 on: April 28, 2008 »
What I am going to use it for is scrollers :) I'll post what I make.
Cheers!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Masking an Opengl texture
« Reply #9 on: April 28, 2008 »
Something I've just thought of with using the alpha test, you don't get any filtering between pixels that are on and pixels that are off so if you're using it for a scroller your text'll have jagged edges. If you're not wanting that then you might just have to go with blending instead.
« Last Edit: April 28, 2008 by Stonemonkey »

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Masking an Opengl texture
« Reply #10 on: April 28, 2008 »
Now I've just noticed something quite strange but I can't grab a screenshot to show. Using the alpha test to mask out half of the image with a diagonal line between opposite corners and zooming in much closer so that only a couple of texels are visible on the screen the external corners of the texels are slightly curved.

Ah, just tried a couple of things and it looks like while the alpha value is filtered and the result affects the alpha test the alpha test result is still just either pass or fail.

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Masking an Opengl texture
« Reply #11 on: April 28, 2008 »
So if you do your masking with values 0 and 255 in the alpha component of your texture and use glAlphaFunc(GL_GREATER,0.5) that might smooth it out a bit.


EDIT:
or GL_LESS depending on which value (0 or 255) you're using to mask
« Last Edit: April 28, 2008 by Stonemonkey »

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Masking an Opengl texture
« Reply #12 on: May 12, 2008 »
I was so stuck here.

I tried to use gl alpha test to draw a logo with transparrent bits.. Looking at this topic I got really confused when I wanted to do it.

Then I realised that the material of the quad I was drawing on had it's alpha set to 0.0 so I set up a new material for the quad with the logo and it's now drawn correctly..

I am only posting this in case anyone else gets stuck in the same way as me.
Shockwave ^ Codigos
Challenge Trophies Won: