상세 컨텐츠

본문 제목

OpenGL 스텐실 테스트, 그림판 지우기 Painter Eraser 구현 관련

프로그래밍 관련/3D,2D DRAW 관련

by AlrepondTech 2017. 7. 12. 23:34

본문

반응형

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

출처: http://wecansoar.tistory.com/103

 

 

Stencil Buffer 스텐실 버퍼

 

문을 페인트칠 하려고 할때 

문고리까지 도색하지 않기 위해 마스킹테이프 같은걸로 덧씌워놓는데

이 마스킹테이프 같은 용도로 사용하는게 Stencil Test (=Stencil Buffer)이다.

 

특정 부분을 제외한 채 Rendering 하는 예제

 

 

 

void RenderScene(void)

{

           GLdouble dRadius = 0.1; // 원의 반지름 값 설정

           GLdouble dAngle;

 

           // 화면을 파란색으로 채움 

           glClearColor(0.0f, 0.0f, 1.0f, 0.0f);

 

           // 스텐실 버퍼의 초기값 지정

           glClearStencil(0); 

           // 위에서 지정한 값으로 Stencil Buffer를 채움 (스텐실 버퍼를 0으로 채움)

           glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

           // 스텐실 테스트 기능 활성화 

           glEnable(GL_STENCIL_TEST);

 

/*   ---- 스텐실 테스트를 활성화 시킨 후부터는 Frame Buffer 에 쓰는 작업이 Stencil Buffer 에도 그대로 반영된다 ---- */

 

           // 스텐실 버퍼내의 값과 두번째 인자와 세번째 인자를 And 연산한 값을 비교값을 비교해 첫번째 인자인 조건에 맞춰 스텐실 테스트를 통과시킬지 지정  

           glStencilFunc(GL_NEVER, 0, 0); 

           /* GL_NEVER : 어떠한 Fragment(pixel)도 Test를 통과하지 못함. 두번째 세번째 매개변수 값이 뭐가 되던지 아무것도 그려지지 않게 됨  

               GL_ALWAYS : 모든 값 통과. 즉 두번째 세번째 매개변수와 상관없이 화면에 그리고자 하는 그림이 그대로 보임.

               GL_LESS

               GL_LEQUAL

               GL_EQUAL

               GL_NOTEQUAL : 스텐실 버퍼내의 값과 비교값이 같지 않을 경우 통과. 여기서는 (GL_NOTEQUAL, 0, 0) 도 같은 의미가 된다. 초기값으로 스텐실 버퍼를 모두 0으로 채웠기 때문에 0이 아닌 경우가 없어 모든 스텐실 테스팅이 실패하기 때문이다.

           */      

 

           // 스텐실 버퍼에 접근해 버퍼내의 값을 변경할 조건을 설정하는 부분

           glStencilOp(GL_INCR, GL_INCR, GL_INCR);    

           /* 첫번째 인자는 스텐실 테스트가 실패 => 스텐실 버퍼의 다음 동작 정의

               두번째 인자는 스텐실 테스트 성공, depth 테스트 실패 =>  스텐실 버퍼의 다음 동작 정의

               세번째 인자는 스텐실 테스트, depth 테스트 모두 성공 => 스텐실 버퍼의 다음 동작 정의  

              GL_KEEP : 스텐실 버퍼 내의 값을 그대로 유지

              GL_ZERO

              GL_REPLACE

              GL_INCR : 스텐실 버퍼에 있는 값을 하나 증가시킨다. 여기서는 GL_NEVER,0,0 으로 했기 때문에 모든 스텐실 테스트는 실패하므로 첫번째 인자인 GL_INCR이 동작하고, 화면에 보이지는 않지만 해당 위치의 버퍼 내용만 0에서 1로 바뀌게 된다. (종이에 구멍이 뚫린다는 개념??)

              GL_DECR

           */

 

           // 스텐실 패턴을 생성. 서로 지름이 다른 흰색 선 나선형 패턴을 그림 

           glColor3f(1.0f, 1.0f, 1.0f);

           glBegin(GL_LINE_STRIP);

           for(dAngle = 0; dAngle < 400.0; dAngle += 0.1)

           {

                     glVertex2d(dRadius * cos(dAngle), dRadius * sin(dAngle));

                     dRadius *= 1.002;

           }

           glEnd();

 

/*  ---- 여기까지... 나선원은 화면에 보이지는 않지만 나선원이 그려지는 부분에 있는 스텐실 버퍼의 값이 1로 변경되어 있음 ---- */

          

           // 스텐실 테스팅 방식이 변경됨. 스텐실 버퍼내에 1이 아닌 위치에 픽셀들만 Test 통과되게 설정 

           // 나선원을 그린 후에 나선원 부분의 스텐실 버퍼 값은 1로 변경됐는데 1과 같지 않은 것만 통과시키겠다는 뜻이므로 나선원 부분만 제외하고 그려질 것이다.

           // 만약 (GL_NOTEQUAL, 2, 1); 이렇게 하면 2 & 1 = 0 이므로 0이 아닌것만 통과시키겠다는 뜻이므로 나선원 부분만 그려지게 된다.

           glStencilFunc(GL_NOTEQUAL, 1, 1);

           // 나선원 그려진 부분의 스텐실 버퍼값이 1이고 나머지 부분은 0이기 때문에 나선원이 있는 부분은 실패. 나머지는 성공. 

           // 나선원이 있는 부분은 첫번째 인자 GL_KEEP 실행. 나머지 부분은 두번째 인자 GL_KEEP 실행.  

           glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

 

           // 빨간색 사각형 그림

           glColor3f(1.0f, 0.0f, 0.0f);

           glRectf(x, y, x + rsize, y - rsize);

 

 /*  ---- 여기까지... 나선원 부분만 제외하고 사각형이 그려짐 ------ */ 

           

           glSwapBuffers();

}

 

 



출처: http://202psj.tistory.com/1033 [알레폰드의 IT 이모저모]

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://blog.naver.com/kzh8055/140043022533

 

[OpenGL] Fragment TEST - 1.스텐실 테스트(Stencil TEST)

 

 

흠...

이번에 살펴볼 내용은 Stencil Buffer(혹은 Stencil Test)에 대해서다.

 

*정점 변환 하다 말고 왜 갑자기 Rendering PipeLine 의 막바지인 Fragment Test로

건너 띄게 된 이유는 따지지마라.

 

Direct Draw 때와 마찬가지로 순전히 본인 X리는데로 적는것 뿐이니.

 

 

 

Stencil TEST

 

우선 Stencil Test 가 뭔 짓거리를 하는 건지 책에서 읽었던 기억을 더듬어

아주 대략 설명해 보겄다.

 

문을 새로이 도색하고자 한다. 보통 페인트 칠에 앞서 문꼬리에 신문지와 같이  무언가를

덧 씌워놓는데 이것은 문꼬리까지 도색하지 않기 위해서일것이다.

Stencil Buffer 용도가 바로 이런것이다.

 

즉,문을 칠하는데 있어 자신이 칠하기 싶은 않은곳에 Mask를 씌어 그곳만은

페인트 칠의 영향을 받지 않게 하는것이다.

 

뭐 여기까지야 Stencil Buffer 를 거론 하는 대부분의 지문들에 나와있는 기본적인 내용들이고

이해도 그리 어렵지 않을것이다.

 

다만, 본인이 Stencil TEST를 이해 하는데 가장 어려웠던 부분인

 

'대체 언제 Stencil Buffer에 쓰는거여?'

 

즉,그리지 말아야 할 부분의 형태(MASK)를 만드는 부분에 대해선 관련 내용을 찾기 힘들었다.

 

하여간 지금 부터 Stencil Test 사용법과 예제를 통해 위에 대한 질문에 답해 보겄다.

 

 

1.Stencil Buffer 요청

 

처음으로 해야할일은 Stencil Buffer를 요청하는 일이다.

이 작업은 GLUT 를 사용해 OpenGL Programming을 할경우 아주 간단하게

Display Mode 초기화 함수 호출시 인자에 GLUT_STENCIL (상수)를 추가해 주면 된다.

 

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL )

 

2.Stencil Test 활성화

 

glutEnable(GL_STENCIL_TEST)

 

3. Stencil Test 설정

 

glStencilFunc(GLenum 함수,GLint 비교값, GLint Mask)

 

위 함수는 Stencil buffer내에 있는 내용과 비교값에 지정된 값을 어떠한 기준으로

비교할것인지 를 지정하는 용도로 사용된다.

 

함수, 즉 비교방법에 올 수있는 enum 값은

GL_NEVER,GL_ALWAYS,GL_LESS,GL_LEQUAL,GL_EQUAL,GL_NOTEQUAL

등이 있고 가령 GL_NEVER의 경우 아무것도 TEST 를 통과 하지 못하게 하고

GL_ALWAYS 는 모두 통과 GL_NOTEQUAL은 Stencil Buffer내의 값과 비교 값이 같지 않을

경우 통과 된다.

 

4. Stencil Pattern 생성

 

glStencilOp(GLenum 실패, GLenum z_실패, GLenum z_성공)

 

이 부분이 바로 Stencil Buffer에 접근해 Buffer내의 값을 변경할 조건을 설정하는것이다.

 

첫번째 인자는 Stencil Test가 실패 했을시 Stencil Buffer 어떻게 변경할것인가를 나타낸다.

 

여기엔 GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR 등이 올수 있다.

 

한가지 예를 들면 GL_KEEP 은 Stencil Buffer 내의 값을 그대로 유지한다.

 

두 번째 인자와 세 번째 인자는 Stencil Test가 성공했다는 전제 하에 Depth(Z) Test 의 성공

여부에 따라 적용될 Stencil Buffer내의 값 변경 방식을 나타낸다.

 

 

 

흠...이론은 이정도로 됐고 예제 하나를 훑어보며 Stencil Test 개념을 잡아보자.

 

*위의 내용과 지금부터 등장할 예제는 OpenGL SuperBible을 거의 그대로 옮긴것이다.

 

 

 

void RenderScence(void)

{

   GLdouble dRadius = 0.1;

   GLdouble dAngle;

    

   glClearColor(0.0f,0.0f,1.0f,0.0f);

   glClearStencil(0.0f);

   

  glEnable(GL_STENCIL_TEST);  

 

  glClear(GL_COLOR_BUFFER | GL_STENCIL_BUFFER_BIT);

 

  glStencilFunc(GL_NEVER,0x0,0x0);

  glStencilOp(GL_INCR , GL_INCR , GL_INCR);

 

   glColor3f(1.0f,1.0f,1.0f);

 

   glBegin(GL_LINE_STRIP);

      for( dAngle = 0 ; dAngle < 400 ; dAngle += 0.1)

      {

          glVertex2d( dRadius * cos(dAngle) , dRadius * sin( dAngle));

          dRadius *= 1.002;

      }

   glEnd();

 

   glStencilFunc(GL_NOTEQUAL , 0x1, 0x1 );

   glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);

 

   glColor3f(1.0f,0.0f,0.0f);

   glRectf(x,y, x + rsize, y - rsize);

 

   glSwapBuffer();

}

 

위 예제는 Stencil Test 를 이용해 특정 부분을 제외한 채 Rendering하는 예제다.

 

하여간 차근차근 살펴보자. 

 

glClearStencil(0.0f) 함수를 통해 Clear 할 Stencil Buffer의 초기값을 지정해주고 

glClear(GL_COLOR_BUFFER | GL_STENCIL_BUFFER_BIT) 함수를 호출함으로써 실제로

위에서 지정한 값으로 Stencil Buffer를 채운다.

 

그리고 나서 Stencil TEST를 활성화 시킨다. -> glEnable(GL_STENCIL_TEST)

 

다음은 Stencil Test 방법을 지정하는것인데

 

 

여기서 알아야 할 중요한 부분은

 

Stencil Test를 활성화 시킨 후 부터는 Frame Buffer 에 쓰는 작업이

Stencil Buffer에도 그대로 반영된다는 것이다.  

 

일단 그렇게 알고 계속 가보자.

 

glStencilFunc(GL_NEVER,0x0,0x0)

glStencilOp(GL_INCR , GL_INCR , GL_INCR);

 

glStencilFunc(...)함수는 Stencil Buffer 내의 값과 비교값(두번째 인자)를 비교해

조건(첫번째 인자)과 맞다면 Stencil Test를 통과하게끔 하기 위해 조건과 비교값을 지정한다.

그러나 조건 방식인 GL_NEVER 이므로 어떠한 Fragment(pixel)도 Test를 통과 하지 못한다.

그런데 아래 함수 glStencilOp의 첫번째 인자, 즉 Stencil Test를 통과하지 못했을때

Stencil Buffer에 적용되는 변경 방법은 GL_INCR, Buffer내의 해당 값을 증가 시키는 것이다. 

 

이게 뭔 말이냐면 일반적인 Rendering 즉 Frame Buffer에 뭔가를 그릴려 시도한다해도 

현 상태에서 무조건 Stencil TEST가 실패로 간주되므로 Frame Buffer에 아무 것도 그려지지

않고 그 Frame Buffer의 대응되는 동일 위치의 Stencil Buffer내의 값이 증감된다는 말이다.

 

glBegin(GL_LINE_STRIP) 과 glEnd() 사이의 Loop 는 서로 지름이 다른 동심원을 그린다.

이때 위의 조건에 의해 Frame Buffer에는 어떤 Pixel(Fragment)도 써지지 못하지만

Stencil Buffer에는 아마도 Frame Buffer에 쓰려던 형태(값은 다르다. 0x1 )가 그대로 써질 것이다.

 

바로 여기까지가 Stencil Pattern 즉, Mask를 만든것이다.

 

               <Frame Buffer>                                    <Stencil Buffer>

 

 

                           <A. glClear() 함수를 통해 초기화된 상태>

 

 

 

                                 <B. 동심원을 Rendering 한 후 >

 

 

 

                                  <C. 사각형을 Rendring 한  후 >

 

여기서 다시 Stencil TEST 방식이 변경됐는데 이번엔

참조 방식이 GL_NOTEQUAL 이고 비교 값이 0x1 이됐다.

풀어서 얘기하자면 Frame Buffer에 무언가를 그릴시에

Stencil Buffer내에 0x1이 아닌 위치에 Pixel들만 Test가 통과 되게 설정했다는것이다.

 

이런 상태에서   Rectf(...) 함수를 이용해 사각형을 그리면 Stencil Buffer에 그려진

동심원의 선 부분을 제외한 곳이 그려질것이다.

 

반대로 Stencil Buffer에 정의된 부분만 Frame Buffer에 그리고자 한다면

마지막 glStencilFunc(...)의 첫번째 인자를 GL_EQUAL 로 바꾸면 될것이다.

 

 

 

 

하여간 정리하자면

Stencil Buffer를 이용해 특정 부분만 Rendering 하고자 하는 방법은 다음과 같다.

 

1. Stencil TEST 를 활성화 시킨다.

 

2. 일단 모든 Stencil TEST 실패하게 한상태에서 Mask 형태 Rendering 한다.

->결국, 이것은 Frame Buffer가 아닌 Stencil Buffer에 그려진다.

 

3. Stencil Test Option을 변경한뒤 객체를 Rendering 한다.

 

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://202psj.tistory.com/1033

 

 

I'm working on a game for the iPhone that has a drawing/paint mechanic involved and I'm having problems trying to create a tool that would erase things already painted.

The main problem is that the background being painted on is not a solid color but a static image or animation. I've tried using different blending options and logical operations in drawing but nothing seemed to work. I'm new to OpenGL so I must be missing something.

Any tips?

EDIT: To give a little more information, I'm using textures for my brushes and using glVertexPointer() and glDrawArrays() to render them. For example:

glBindTexture(GL_TEXTURE_2D, circleBrush); glVertexPointer(3, GL_FLOAT, 0, verts); glTexCoordPointer(2, GL_FLOAT, 0, coords); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

EDIT 2: Unfortunately, stencil buffers are not available on the iPhone. : (

EDIT 3: Framebuffer objects are available on the iPhone and that is the road I took. I haven't fully implemented it yet, but so far it looks like it works the way I wanted it to. Thanks everyone!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Draw a full-screen textured quad over your scene. When the user draws a brush stroke, use glTexSubImage2D to update the your texture.

glReadPixels/glDrawPixels is slow.

Using FrameBufferObjects is even better, but I doubt this extention is available on the iPhone (then again, I don't know for sure, so maybe try it). FBO's allow you to draw directly into a texture as if it were another rendering context.

---------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

Stencil Buffer is the best way to approach this for sure...You'll save time, cpu, and potential problems..,They are available on Iphone, you just have to created an OpenGlES 2.0 surface (not gles 1.0 or 1.1).

        //Turn off writing to the Color Buffer and Depth Buffer         //We want to draw to the Stencil Buffer only         glColorMask(false, false, false, false);         glDepthMask(false);          //Enable the Stencil Buffer         glEnable(GL_STENCIL_TEST);          //Set 1 into the stencil buffer         glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);          //CALL YOUR DRAWING METHOD HERE           //Turn on Color Buffer and Depth Buffer         glColorMask(true, true, true, true);         glDepthMask(true);          //Only write to the Stencil Buffer where 1 is set         glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);         //Keep the content of the Stencil Buffer         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);          //CALL OUR DRAWING METHOD AGAIN

Lookup this example :http://www.opengl.org/resources/code/samples/glut_examples/examples/stenciltst.c

Here's the visual result :http://www.opengl.org/resources/code/samples/glut_examples/examples/stenciltst.jpg

I've implented the same kind of eraser tool with this, on both android and iPhone and it works like a charm !

Good luck !

Cheers !

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

You don't give much info, but I assume that your storing whatever they "paint" into a buffer and then drawing it on screen like this:

 glWindowPos2i(X, Y);  glDrawPixels(drawing->Width, drawing->Height, drawing->Format,                GL_UNSIGNED_BYTE, drawing->ImageData);

With drawing->ImageData being the buffer. What you could do is have a separate background buffer and draw it first. Then the erase tool will simply white-out the the drawing buffer(turning all the values, including alpha, all the way up).

For this solution to work you'd have to turn on blending and turn off depth testing.

 glEnable(GL_BLEND);  glDisable(GL_DEPTH_TEST);  glWindowPos2i(X, Y);  //background never changes  glDrawPixels(background->Width, background->Height, background->Format,                GL_UNSIGNED_BYTE, background->ImageData);  glWindowPos2i(X, Y);  glDrawPixels(drawing->Width, drawing->Height, drawing->Format,                GL_UNSIGNED_BYTE, drawing->ImageData);  glEnable(GL_DEPTH_TEST);  glDisable(GL_BLEND);

Is that what you're looking for?

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

You could use the stencil buffer for this operation. The stencil buffer is a special buffer which holds information for every pixel, similiar to the depth buffer. Unlike the depth buffer, you decide how the stencil buffer is altered while drawing and how it influences the decision to draw into the color buffer or not. To do so, you can set the specific states before any drawing operation. Here is what you do:

  • At the time the users erases, draw the "erased" region into the stencil buffer (using StencilOp, see below). You can use any GL drawing function for that.
  • In every rendering pass, first draw the background (if you want, you can use a negative stencil test here to only draw the "erased" part of the background - may increase performance).
  • Then, enable the stencil test for all other drawing operations. OpenGL will then only draw to the "non-erased" regions.

The function to set how the stencil buffer should influence drawing (or not): glStencilFunc()

The function to set how the stencil buffer itself is influenced by drawing: glStencilOp()

Further explanation, also with the arguments for these:http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node117.html

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

Using glBlendFunc(GL_ONE, GL_ZERO) mode can earse.



출처: http://202psj.tistory.com/1033 [알레폰드의 IT 이모저모]

 

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://blog.naver.com/PostView.nhn?blogId=gidools&logNo=20131734261

 

OpenGL stencil buffer

 

OpenGL+Dev.zip
다운로드

 

 

 

오랜만에 하나 올린다. 오늘은 OpenGL ES 버전이 아니라 OpenGL 에 대한 내용이다.

 

Stencil buffer - 첨 봤을 때는 어떻게 쓰는 것인지 전혀 감이 안 왔었는데 다시 보니까 이해가 된다인터넷에서 검색해 봐도 제대로 된 설명이 안 나와 있어서 초보의 마음으로 접근해 본다.

 

전체 예제 소스는 첨부 파일을 열어서 실행하면 된다.

 

핵심 내용에 대해서만 설명하겠다.

 

void RenderScene(void)

{

           GLdouble dRadius = 0.1; // Initial radius of spiral

           GLdouble dAngle;        // Looping variable

 

           // Clear blue window

           glClearColor(0.0f, 0.0f, 1.0f, 0.0f);

 

           // Use 0 for clear stencil, enable stencil test

           glClearStencil(0.0f);

           glEnable(GL_STENCIL_TEST);

 

           // Clear color and stencil buffer

           glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

 

           // All drawing commands fail the stencil test, and are not

           // drawn, but increment the value in the stencil buffer.

           glStencilFunc(GL_NEVER, 0x0, 0x0);

           glStencilOp(GL_INCR, GL_INCR, GL_INCR);

 

           // Spiral pattern will create stencil pattern

           // Draw the spiral pattern with white lines. We

           // make the lines  white to demonstrate that the

           // stencil function prevents them from being drawn

           glColor3f(1.0f, 1.0f, 1.0f);

           glBegin(GL_LINE_STRIP);

           for(dAngle = 0; dAngle < 400.0; dAngle += 0.1)

           {

                     glVertex2d(dRadius * cos(dAngle), dRadius * sin(dAngle));

                     dRadius *= 1.002;

           }

           glEnd();

 

           // Now, allow drawing, except where the stencil pattern is 0x1

           // and do not make any further changes to the stencil buffer

           glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);

           glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

 

           // Now draw red bouncing square

           // (x and y) are modified by a timer function

           glColor3f(1.0f, 0.0f, 0.0f);

           glRectf(x, y, x + rsize, y - rsize);

 

           // All done, do the buffer swap

           glutSwapBuffers();

}

 

아무것도 수정하지 않은 상태의 결과 화면은 아래 그림이다.




 

그럼이제부터 설명..

 

glClearStencil(0.0f);

스텐실 버퍼의 값을 모두 0으로 채운다는 뜻이다. glClearColor(0.0f, 0.0f, 1.0f) 함수를 호출한 다음  glClear(GL_COLOR_BUFFER_BIT) 함수를 실행하면 컬러 버퍼의 값이 모두 파란색 컬러 값으로 채워지듯이 마찬가지로 스텐실 버퍼를 0 으로 채운다는 개념으로 이해하면 된다책 본문의 소스는 0.0f 값을 줬는데 사실 glClearStencil() 함수의 매개변수는GLint 값으로 들어가야 한다타입 캐스팅 돼서 GLint 형으로 변경될 것이고 돌아가는데 문제는 없지만 바람직한 코드는 아니다따라서 glClearStencil(0) 과 같은 식으로 코드를 수정하는 것이 올바른 코드가 되겠다.

 

glEnable(GL_STENCIL_TEST);

스텐실 테스팅 기능을 사용할거라고 선언하는 부분이다이거 안 넣으면 나선원이던 붉은 사각형이던 모두 화면에 그냥 그려진다.

 

glStencilFunc(GL_NEVER, 0x0, 0x0);

이 함수의 첫번째 parameter 는 몇 가지가 있다. GL_ALWAYS, GL_LESS 등등이 있다그런데 여기서는 GL_NEVER 를 쓰고 있다스텐실 버퍼가 어떤 값이 들어가 있던지 무엇을 그리던지 아무것도 그려지지 않게 하겠다는 뜻이다그러므로 GL_NEVER 가 첫번째 값이면 두번째와 세번째 매개 변수가 의미가 없게 된다비슷한 의미로 GL_ALWAYS 로 설정되면 모든 값을 통과 시킨다는 뜻즉 화면에 그리고자 하는 그림이 그대로 보인다는 뜻이다.GL_ALWAYS 로 설정하고 테스트 해 보면 두번째 세번째 매개 변수의 값이 뭐가 되던지 아래 처럼 화면에 그려진다.

 

 

 

 

여기서는 glStencilFunc(GL_NOTEQUAL, 0x0, 0x0); 도 glStencilFunc(GL_NEVER, 0x0, 0x0); 와 같은 의미가 된다왜냐면 스텐실 버퍼의 값이 모두 0 으로 채워져 있기 때문에 0 이 아닌 경우가 없어 모든 스텐실 테스팅이 실패하기 때문이다.

 

glStencilOp(GL_INCR, GL_INCR, GL_INCR);

교재에도 나와 있듯이 첫번째 매개 변수는 스텐실 테스트가 실패했을 때 그 다음 동작을 두번째 매개 변수는 스텐실 테스트가 성공하고 depth 테스트가 실패했을 때 세번째는 스텐실 테스트와 깊이 테스트가 모두 성공했을 때 그 다음 동작을 정의하는 것이다첫번째 매개변수가 GL_INCR 로 돼 있으므로 스텐실 테스트가 실패했을 때 스텐실 버퍼에 있는 값을 하나 증가시킨다는 뜻이다바로 위 함수에서 glStencilFunc(GL_NVER, 0, 0) 으로 했기 때문에 화면에 어떤 그림을 그리던지 모든 스텐실 테스트가 실패한다화면에 아무것도 보이지 않게 된다스텐실 테스트가 성공해야 그 부분이 화면에 보이게 되는데 일단은 모든 테스트가 실패하도록 설정했기 때문에 화면에 아무것도 보이지 않는 것이고 그렇기 때문에 첫번째 옵션인 GL_INCR 이 동작하게 된다.그래서 결국 glClearStencil(0.0f)을 실행해서 0 으로 채워진 스텐실 버퍼의 내용이 1로 바뀌게 된다화면에 뭔가를 그리고자 했을 때 보이지는 않지만 해당 위치의 버퍼 내용만 1로 바뀌게 되는 것이다(종이에 구멍이 뚫린다는 개념으로 이해하면 된다). 버퍼의 나머지 부분은 그대로 0 으로 유지된다.

 

glBegin(GL_LINE_STRIP);

화면에 나선형의 그림을 그리는 부분이다스텐실 테스트 기능을 꺼 버린다면 - glEnable(GL_STENCIL_TEST) 함수를 실행하지 않는다면 – 서로 이어지는 나선형(?) 원들이 화면에 보일 것이다그런데 스텐실 테스트 기능이 ON 상태이고 glStencilFunc(GL_NEVER, 0x0, 0x0) 함수를 실행했기 때문에 화면에 아무것도 보이지 않는 상태인 것이다하지만 변화된 내용이 있는데 그것은 glStencilOp(GL_INCR, GL_INCR, GL_INCR) 를 실행하면서 나선원이 그려지는 부분에 있는 스텐실 버퍼의 값이 1 로 변경된다는 것이다. (일단 스텐실 버퍼의 위치와 화면 픽셀이 1:1 매핑이 된다고 생각하면 이해하기 편하다)

 

glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);

두번째 param 과 세번째 param  And 연산한 값이 스텐실 버퍼에 있는 값과 같지 않을 때 통과 시키겠다는 뜻나선원을 그린 후에 스텐실 버퍼는 그리고자 하는 위치에 있는 버퍼의 값이 1로 변경됐는데 이 함수를 실행하면 1과 같지 않은 것만 통과 시키겠다는 뜻이다즉 화면에 뭔가를 그린다면 나선원 부분만 제외하고 그려질 것이다만약 glStencilFunc(GL_NOTEQUAL, 0x2, 0x2); 이렇게 하면 어떻게 그려질까? 0x2 & 0x2 = 0x2 이고 스텐실 버퍼에 있는 값 중에서 0x2 가 아닌 것은 모두 통과 시키겠다는 뜻이므로 결국 화면에 뭘 그리면 그대로 모두 그려지게 된다그럼 glStencilFunc(GL_NOTEQUAL, 0x2, 0x1); 요렇게 하면? 0x2 & 0x1 = 0x0 이므로 0 이 아닌 것만 통과 시키게다는 뜻결국 나선원 부분만 그려지게 된다직접 실행해 보면 아래처럼 보인다.

 

 

 

glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

첫 번째 매개변수는 스텐실 테스팅이 실패했을 경우 다음 동작이라고 설명했다나선원이 그려진 부분의 스텐실 버퍼값이 1 이고 나머지 부분은 모두 0 이기 때문에 glStencilFunc(GL_NOTEQUAL, 0x1, 0x1); 함수를 실행하면 나선원이 있는 버퍼의 내용과 스텐실 테스트했을 때는 실패나머지 부분에서는 모두 성공이 나온다왜냐면 0x1 & 0x1 = 0x1 이 아닌 값은 모두 통과 시킨다고 했는데 나선원이 그려진 부분만 1 이기 때문이다그래서 0x1 인 버퍼와 테스트했을 때는 실패이므로 첫번째 매개변수인 GL_KEEP을 실행하고 0x0 인 스텐실 버퍼값과 테스트했을 때는 성공이므로 두번째 매개변수인 GL_KEEP 이 실행된다만약 두번째 매개변수를 GL_INCR로 하면 어떻게 될까나그러면 의 값이 들어가 있던 스텐실 버퍼의 내용이 모두1로 되므로 두번째 프레임 부터는 화면에 아무것도 그려지지 않을 것이다라고 예상할 수 있으나 사실은 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);함수 실행은 이 예제에서 의미가 없는 코드다왜냐면 glStencilFunc(GL_NOTEQUAL, 0x1, 0x1); 를 실행하면서 어떤 값들을 통과 시킬지 이미 결정이 나 있는 상태이기 때문에 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 를 실행한다고 해도 RenderScene() 함수가 다시 호출되면서 스텐실 버퍼의 값이 모두 0 으로 초기화 되기 때문이다.만약 첫번째 glStencilOp(GL_ INCR, GL

_

INCR, GL_ INCR); 함수를 실행할 때 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 와 같은 식으로 실행했다면 스텐실 버퍼의 내용이 변하는 게 없어서 결국 glStencilFunc(GL_NOTEQUAL, 0x1, 0x1); 실행하면서 화면에 그리고자 하는 내용이 모두 그려지게 된다.

 

glColor3f(1.0f, 0.0f, 0.0f);

glRectf(x, y, x + rsize, y - rsize);

스텐실 테스트와 관련된 함수들을 차례대로 실행하면서 나선원이 그려진 부분은 스텐실 테스팅이 실패하고 나머지 부분에서는 모두 성공할 것이라는 세팅이 돼 있기 때문에 붉은 사각형을 그리면 나선원 부분만 보이지 않고 나머지는 모두 그려진다.

 

부디 이해가 되셨기를..에고 힘들당..

 

 

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://hururuc.tistory.com/14

 

 

OpenGL은 Stencil buffer를 가지고 stencil 하는데 사용한다.
Stencil의 기본 기능은, 구멍뚫린 마스크(stencil)를 만들어서 구멍뚫린 부분의 각 pixel들을 비교해서 함수처리(같거나 다르거나 등등)를 해서 동작(색깔을 덧입히거나, 지우거나 등등)을 수행한다.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//3개의 buffer를 초기화 한다. 즉 색상버퍼, 깊이버퍼, 스텐실 버퍼를 초기화 한다.
glClearStencil(GLint s);
//stencil buffer 초기화시에 초기화 값으로 사용될 값을 지정한다.
glStencilFunc(GLenum 함수, GLint 참조, GLuint mask);

함수는 비교에 사용되는 기능들 중 하나를 지정하는데, GL_NEVER,GL_ALWAYS,GL_LESS,GL_EQUAL,GL_GEQUAL,GL_GREATER,GL_NOTEQUAL 이 있다. 참조는 비교시에 사용되는 참조 값이다. mask는 비교전에 AND 연산을 수행한다.

즉, (해당bits AND mask) 값이 (참조bits AND mask)와 비교해서 같은지,다른지 확인한다.

glStencilOp(GLenum 실패, GLenum z실패, GLenum z성공);

비교시 값이 거짓인경우, "실패"를 수행하고, 그리고 비교값이 참인경우에 깊이 test가 실패했을때 "z실패"를 수행하고, 깊이 test가 성공시에는 "z성공"을 수행한다.

즉,
1. 비교값이 거짓 : 실패 수행.
2. 비교값이 참:
2.1 깊이 test가 실패: z실패 수행.
2.2 깊이 test가 성공: z성공 수행.

수행되는 값은 GL_KEEP,GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR,GL_INVERT,GL_INCR_WRAP,GL_DECR_WRAP 등이 있다


[Sample code]
어떤 object를 화면의 특정 부분에서만 그리고 싶을 때 stencil buffer를 활용한 예.

void DrawScreen(void)
{

...

 glClear(GL_STENCIL_BUFFER_BIT);
 glStencilFunc(GL_NEVER, 0x0, 0x0);                   // 이후에 나오는 drawing 명령은 모두 stencil test를 pass하지 못하므로 실제로 그려지지 않는다. 
 glStencilOp(GL_INCR, GL_INCR, GL_INCR);         // test후 stencil buffer의 값을 증가시킨다.

 

 

 

 

=================================

=================================

=================================

 

 

 


 // draw screen boundary
 DrawScreenBoundary();

 

glStencilFunc(GL_EQUAL, 0x1, 0x1);                   // 0x1인 부분에 대해서만 드로잉을 허용한다.
 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// 아래 부분은 DrawScreenBoundary()에서 정해준 영역 안에만 렌더링 된다.

// ... Renderinig codes

 

glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);             // 0x1이 아닌 부분에 대해서 드로잉을 허용
// 아래 부분은 DrawScreenBoundary()에서 정해준 영역 밖에만 렌더링 된다.


return;
}



출처: http://hururuc.tistory.com/14 [Impossible is nothing]

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://diehard98.tistory.com/entry/Stencil-Buffer%EC%9D%98-%EC%82%AC%EC%9A%A9%EB%B2%95

 

 

현재 내가 수행중이 프로젝트는 절묘한 Stencil Buffer 사용을 요구한다.

Framebuffer Object의 Stencil buffer를 사용하려고 하다보니 생각지 못한 문제들에 막힌적이 있었다.

우선 Framebuffer Object 사용시 Stencil Buffer의 세부 규약에 대해서 몰라서 어떻게 세팅하는지 몰랐고

다른 한가지는 Nvidia 그래픽 카드에서는 Nvidia에서만 허용되는 특수한 타입이 있는데 그것을 반드시 써야만 Framebuffer Object의 Stencil Buffer를 아무 에러없이 쓸 수 있다는 점이었다.

이것은 다음에 자세히 알아보도록 하고 오늘은 Stencil Buffer를 어떻게 정하고 또 어떻게 사용하는지만 이야기 해보자.

우선 Stencil Buffer를 정의하는 것부터 시작한다. Stencil Buffer를 어디서 정의해야 하는가 하는 의문부터 해결하자. Stencil Buffer라 함은 사용자가 원하는 부분만 그려내고 싶을때 사용하는 기술이다.

자동차 게임을 예로 들어보면 Need for speed에서 자동차 내부에서 보는 시점이 있다. 그 때에는 차 앞쪽과 측면 유리를 통해서만 외부의 세상이 보여질 뿐이다. 바로 이럴때 Stencil Buffer를 사용한다. Full Screen으로 렌더링 할 필요가 없고 사용자가 원하는 부분만 보여주고 싶을때 이다.

그렇다면 당연히 외부의 세상을 그리기 전에 Stencil Buffer를 정의해야 한다. 외부의 모든 물체를 다 그려놓고 보이지 않는 부분을 삭제하는 것과 보여지지 않는 부분을 빼고 그리는 것 둘중에 어떤것이 더 나을까 라고 스스로에게 질문해보자.

그래서 물체를 그리기 전에 다음과 같은 명령들을 내려줘야 한다.

  glColorMask(0, 0, 0, 0); // 1
  glEnable(GL_STENCIL_TEST); // 2 
  glStencilFunc(GL_ALWAYS, 1, 1); // 3 
  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // 4
  glDisable(GL_DEPTH_TEST); // 5

  glColor3f(0.0f, 1.0f, 0.0f); // 6
  glPushMatrix(); // 7
  glTranslatef(VP_x, VP_y, -10.0f); // 8 
  glCallList(MakeMask); // 9
  glPopMatrix(); // 10
  glDisable(GL_STENCIL_TEST); // 11

1번은 Color Buffer(화면에 보여질 모습이 저장되는 버퍼)에 어떠한 색깔도 그리지 말라는 의미인데 이것을 하는 이유는 현재 우리는 Stencil Buffer에 그림을 그리고자 하는 것이지 Color Buffer에 그림을 그리고자 하는 것이 아니기 때문이다. Stencil Buffer에 그리고자 하는 그림이 화면에 그대로 보인다면 당연히 이상한 그림이 나올것이다.

2번과 5번 11번은 굳이 설명하지 않아도 알것이다. Stencil 기능을 켜고 끄며 혹은 Depth test를 끄는 기능들을 한다.

이제 3번과 4번이 중요한데 이거 상당히 복잡해서 나도 처음에 볼때는 많이 애먹었다. 3번 함수는 Stencil Buffer에 값을 쓸때 어떤 경우에 쓰고 또 어떤 값을 쓸것인가를 설정하는 함수다. 아시다시피 Stencil buffer는 단순히 생각해서 0과 1로 이루어진 bitplane이다. 즉 1이면 통과 0이면 통과 실패이다. 여기서 이해하고 넘어가야 할것은 stencil buffer를 정의할 때는 일일이 각각의 화소 위치에 대해서 1과 0을 세팅하는 것이 아니고 내가 원하는 위치에 물체를 그려 넣음으로써 그 부분은 1로 채워지게 만드는 것이다. 원래 Stencil Buffer는 모두 0으로 가득 차 있는데 내가 보여주고 싶은 부분에만 그림을 그려 넣으면 3번과 4번 함수에 의해서 그 부분의 Stencil buffer 값은 모두 1로 바뀌게 되는 것이다.

의미적으로만 설명을 했는데 3번과 4번 함수는 인터넷에서 man page를 찾아보면 금방 이해할 수 있을 것이다. 중요한 것은 이 단계에서는 Stencil buffer에 우리가 보여주고 싶은 부분만 그린다는 것이다.

6,7,8,9,10은 모두 물체를 그리는 명령이다. 다 설명하자면 너무 길고 어쨌든 줄여서 저 명령들은 내가 원하는 위치에 내가 원하는 물체를 그리는 것이다. 고로 그 위치의 Stencil Buffer 값은 모두 1로 변하게 된다. 자, 여기까지 하면 이제 비로서 Stencil Buffer를 사용할 수 있는 단계에 온것이다. 이제 고작 사용할 수 있는 단계에 온것이다. 그렇다면 어떻게 사용하느냐? 오히려 사용하는 것이 더 쉽다.

    glEnable(GL_STENCIL_TEST);
    glColorMask(1,1,1,1);
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 
    glPushMatrix();
    glCallList(MakeSpaceShip);
    glPopMatrix();
 
    glDisable(GL_STENCIL_TEST);

위의 일련의 명령이 사용하는 법이다. 우선 Stencil Test를 Enable한다음 glColorMask()함수를 이용해서 지금부터 그리는 물체를 color buffer에 넣으라는 명령을 내린다. 당연히 그래야 한다. 왜? 지금부터는 사용자에게 보여줄 화면을 그리는 것이기 때문이다. 그런다음 설정함수인 glStencilFunc와 glStencilOp가 나오는데 이것은 아까 본것과 조금 다를뿐 거의 같다. 함수에 대한 설명은 여기서 다 하기 힘드니 함수 설명을 찾아보고 읽으면 금방 이해가 갈것이다. 저 두함수가 하는 역활은 들어오는 각각의 화소에 대한 값을 stencil buffer의 해당 위치의 값과 비교해서 1이면 통과 0이면 통과 실패를 시키는 것이고 추가적으로 stencil buffer에 저장되어 있는 값은 변경하지 말라는 의미이다. 당연히 stencill buffer를 변경해서는 안된다.

그리고 그 다음 좌악 나오는 명령들은 이제 진짜 그림을 그리자는 명령들이다. 

쉽게 쉽게 그리고 간단하게만 썼는데 나중에 내가 참고하려고 할때 다시 보면 이해가 잘 될지 모르겠다.ㅋㅋ
팍팍 줄여서 단계별로 설명하자면,
1. 스텐실 버퍼에 내가 보여주고자 하는 부분만 그린다.
2. 실제로 물체를 그리고자 할때에는 스텐실 버퍼 설정함수를 조작하여 스텐실 버퍼가 1의 값을 가지는 곳만 그림이 그려지도록 한다.

아주 간단하게 써보았다. :)



출처: http://diehard98.tistory.com/entry/Stencil-Buffer의-사용법 [Unavailable]

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

출처: http://egloos.zum.com/keugbang/v/5858105

OpenGL Stencil 기능을 이용한 HUD 심볼 그리기

http://keugbang.egloos.com/5858105

HUD (Head Up Display)는 조종사 정면의 투명한 유리창에 유용한 정보를 투영하여 보여주는 장비.

 

조종사가 보게 될 외부 전경과 초점을 맞추기 위해 HUD에 시현되는 내용도 무한초점이 되도록 광학적으로 조정되어있다.
 
물론 실제가 아닌, PC에서 실행되는 Simulator는 초점을 고려할 필요는 없으나, 대신 HUD 심볼을 PC 모니터에 그릴 때 고려해야 할 것이 한가지 있는데, 일부 심볼들이 겹칠 때 그려지지 않는 부분 (Occlusion) 에 대한 처리가 그것이다.
 
가장 쉽게 눈에 띄는 것은 고도계와 속도계의 현재값이 들어 있는 박스에 대한 것인데, 아래 그림은 실제 HUD와 동일한 로직으로 그려진 것으로, 지평선라인이 속도계 박스와 겹친 부분은 그려지지 않은 것을 볼 수 있다.

 

아래 그림은 이런 처리 없이 그냥 그렸을 때 볼 수 있는 현상으로, 속도계 숫자 139와 지평선라인이 겹쳐서 읽기 곤란하다.

 

예전에 구현된 HUD 모의SW는 아래 그림과 같이 뒷 배경을 검은색으로 채워넣어 실제감이 떨어졌다.

 

이 HUD 모의SW는 예전 프로젝트에서는 문제없이 사용되었는데, 외부영상과 HUD 영상을 각각 별도 비디오로 생성하여 겹쳐서 투영했기 때문에 검은 부분은 투명하게 자동 처리가 되었었다.
 
그러나 동일한 SW를 외부영상SW와 합치고 나니 위와 같이 검은 바탕이 드러나게 된 것이다.
 
이를 해결할 수 있는 OpenGL 기능들을 검토해봤었는데, Stencil 방법을 이용하거나 비교적 최근에 추가된 (OpenGL 3.0 이후) Framebuffer Object를 사용하는 것이었는데, 이 중 Stencil 방법을 통해 구현할 수 있었다.
 
이 방법을 사용하는데 유용하게 참조한 내용은 다음 링크와 같다.  어렵지 않게 설명을 달았음에도 불구하고 이제까지 고려해보지 않던 낯선 내용이라 그런지 처음에 개념 파악이 좀 쉽지는 않았다.
위 링크 내용의 중간 쯤에 있는 코드 블록을 참조하여 아래와 같이 Stencil기능을 쓰는 주요 부분에 대한 코드를 구현하였다.
// hud.cpp
{
glEnable(GL_STENCIL_TEST);

// draw occlusion regions, such as airspeed box, to the stencil buffer
drawMode = Draw_Stencil;
glStencilFunc(GL_NEVER, 1, 0xFF); // only occlusion regions will be written
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0xFF); // write to stencil buffer
glColorMask(false, false, false, false);
glClear(GL_STENCIL_BUFFER_BIT);

// first pass to draw stencil
renderHudScreen();

// draw actual symbols
drawMode = Draw_Normal;
glStencilFunc(GL_EQUAL, 0, 0xFF); // pass symbols outside occlusion regions
// texts inside occlusion regions are written if 1
glStencilMask(0x00); // don't write to stencil buffer
glColorMask(true, true, true, true);

// last pass to render symbols
renderHudScreen();

glDisable(GL_STENCIL_TEST);
}
원래 HUD 심볼을 그리던 부분은 renderHudScreen() 이고, 한 프레임에 한번만 실행하면 되었으나, Stenciling을 위해서는 두 번 실행이 필요했고, 이에 따라 Stencil과 관련 없는 심볼들의 실행을 최소화 하기 위해 전역 변수 drawMode를 추가하였다.
 
이 변수는 다음과 같이 정의 되었다.
// hud.h
// Occulusion control
typedef enum HudDrawMode {
Draw_Stencil,
Draw_Normal,
TotalHudDrawMode
} HudDrawMode;

extern HudDrawMode drawMode;
첫번 Pass를 통해 Occlusion 영역을 Stencil Buffer에 기록하기 위한 세팅 부분을 보면, drawMode를 Draw_Stencil로 하여 renderHudScreen()의 심볼들 중 Stencil에 필요한 부분만 선택적으로 불리게 하였다.
 
그러나 나머지 심볼들을 모두 if-문 처리하기가 곤란했기 때문에 glStencilFunc의 디폴트 파라미터를 GL_NEVER로 하여 관련 없는 심볼들이 Stencil Buffer에 기록되는 것을 원천 차단했다.
 
renderHudSymbol() 함수에서 가려지는 영역 (Occlusion)을 그리는 부분은 다음과 같이 drawMode가 Draw_Stencil일 때 glStencilFunc를 GL_ALWAYS로 하여 Stencil Buffer에 기록 되도록 했다.  이 부분은 예전 코드에서 검은색으로 채워 넣던 부분이다.
// occlusion box
{
if (drawMode == Draw_Stencil)
{
glStencilFunc(GL_ALWAYS, 1, 0xFF); // was glColor4d(0,0,0,1)
drawOcclusionBox();
glStencilFunc(GL_NEVER, 1, 0xFF); // was glColor4d(0,1,0,1)
}
}
이어서 실제 HUD심볼을 그리는 두번째 pass에서는 drawMode를 Draw_Normal로 놓았고, 이를 이용하여 Occlusion 영역 위에 디스플레이할 숫자 값 등을 그리게 되었다.  이 부분은 다음과 같이 drawMode가 Draw_Normal일 때 glStencilFunc을 GL_ALWAYS로 하여 화면에 그려지도록 했다.
// numeric text box
{
if (drawMode == Draw_Normal)
{
glStencilFunc(GL_ALWAYS, 1, 0xFF);
drawNumericTextBox();
glStencilFunc(GL_EQUAL, 0, 0xFF);
}
}

Stenciling을 위해 HUD 심볼을 그리는 renderHudScreen()을 두 번 실행하는 것에 성능 저하를 우려하였으나, 예상외로 큰 차이가 없이 거의 완벽하게 원하는 효과를 이룰 수 있었다. 
 
아직 움직이는 심볼들 중 Occlusion이 필요한 것들 일부를 시험해보지 않았으나, 맨 위의 코드에 보인 바와 같이 첫번 Pass를 실행하기 전에 glClear(GL_STENCIL_BUFFER_BIT)을 실행하여 Stencil Buffer를 매번 새로 설정하기 때문에 아무 문제 없을 것으로 예상된다.
 
현재 진행되고 있는 프로젝트에서 HUD는 OpenSceneGraph (OSG) 기반 영상시스템 안에서 실행되므로 OSG 관련 몇가지 추가적인 세팅이 필요했다 (관련 포스팅).
 

 

=================================

=================================

=================================

 

 

 

반응형


관련글 더보기

댓글 영역