Skip to content

Instantly share code, notes, and snippets.

@vumbumy
Created February 3, 2017 09:34
Show Gist options
  • Select an option

  • Save vumbumy/8f21427402f1cf9021552be4507e42e3 to your computer and use it in GitHub Desktop.

Select an option

Save vumbumy/8f21427402f1cf9021552be4507e42e3 to your computer and use it in GitHub Desktop.
#include "main.h"
// Initial square position and size
GLfloat x = 0.0f;
GLfloat y = 0.0f;
GLfloat rsize = 25;
// Step size in x and y directions
// (number of pixels to move each time)
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;
// Keep track of windows changing width and height
GLfloat windowWidth;
GLfloat windowHeight;
/*
오브젝트(?)는 순서대로 위에 쌓인다.
*/
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);
glEnable(GL_STENCIL_TEST);
// 스텐실 버퍼를 사용하겠음.
glClearStencil(0);
/*
glClearStencil specifies the index used by glClear to clear the stencil buffer.
화면에 한 픽셀마다 가지고 있는 스텐실 버퍼를 모두 0으로 초기화 하겠음.
*/
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
/*
화면에 한 픽셀마다 가지고 있는 색상, 스텐실 버퍼를 모두 지우겠음.
*/
glStencilFunc(GL_NEVER, 0x0, 0x0);
/*
어떤 경우에도 이 아래의 오브젝트를 화면으로 통과시키지 않겠음.
*/
glStencilOp(GL_INCR, GL_KEEP, GL_KEEP);
/*
스텐실 테스트를 통과하지 못한경우 아래의 오브젝트와 관련된
픽셀의 스텐실 버퍼를 1 증가시키겠음.
깊이 테스트를 통과하지 못한 경우 또는, 스텐실 테스트와 깊이 테스트를 모두 통과한 경우엔
관련 픽셀의 스텐실 버퍼를 변경시키지 않겠음.
*/
// Draw Spiral Pattern
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();
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
/*
이 아래의 오브젝트는 무조건 화면에 통과시키고,
어떤 값도 변화시키지 마!
*/
glColor3f(0.0f, 1.0f, 0.0f);
glRectf(50, 10, 100, 60);
glStencilFunc(GL_EQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
/*
현재 Spiral Pattern 픽셀에 스텐실 버퍼가 1로 되어 있어.
근데 Ref = 1, Mask = 1 이기 때문에 (Ref & Mask)와 (Stencil & Mask)를 비교 했을때
Spiral 픽셀의 스텐실 버퍼를 만나는 부분에서 화면 통과가 가능해!
*/
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(x, y, x + rsize, y - rsize);
glutSwapBuffers();
}
///////////////////////////////////////////////////////////
// Called by GLUT library when idle (window not being
// resized or moved)
void TimerFunction(int value)
{
// Reverse direction when you reach left or right edge
if(x > windowWidth-rsize || x < -windowWidth)
xstep = -xstep;
// Reverse direction when you reach top or bottom edge
if(y > windowHeight || y < -windowHeight + rsize)
ystep = -ystep;
// Check bounds. This is in case the window is made
// smaller while the rectangle is bouncing and the
// rectangle suddenly finds itself outside the new
// clipping volume
if(x > windowWidth-rsize)
x = windowWidth-rsize-1;
if(y > windowHeight)
y = windowHeight-1;
// Actually move the square
x += xstep;
y += ystep;
// Redraw the scene with new coordinates
glutPostRedisplay();
glutTimerFunc(33,TimerFunction, 1);
}
///////////////////////////////////////////////////////////
// Called by GLUT library when the window has chanaged size
void ChangeSize(int w, int h)
{
GLfloat aspectRatio;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
{
windowWidth = 100;
windowHeight = 100 / aspectRatio;
glOrtho (-100.0, 100.0, -windowHeight, windowHeight, 1.0, -1.0);
}
else
{
windowWidth = 100 * aspectRatio;
windowHeight = 100;
glOrtho (-windowWidth, windowWidth, -100.0, 100.0, 1.0, -1.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
///////////////////////////////////////////////////////////
// Program entry point
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL);
//glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInitWindowSize(800,600);
glutCreateWindow("OpenGL Stencil Test");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutTimerFunc(33, TimerFunction, 1);
glutMainLoop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment