Użyj GL_STENCIL_TEST do renderowania wklęsłych wielokątów
Pracuję nad niestandardową biblioteką geometrii dostosowaną do Quartz Composer i próbując narysować wklęsłe wielokąty w wtyczce.
Zaimplementowałem bibliotekę poly2tri, więc użytkownik może wybrać triangulację lub nie, ale nie nadaje się do renderowania wielokątów na klatkę.
Jestem noobem w OpenGL i dużo czytałem i testowałem, o buforze szablonów i operacjach nieparzystych / parzystych, ale nawet kod, który wydaje się działać dla innych ludzi, nie działa dla mnie.
Kontekst renderowania to CGLContextObj i pracuję nad wyświetlaczem MacBook Pro Retina z NVidia GEForce GT650. Czytałem, że wszystkie konfiguracje nie mają buforów szablonów, ale wyglądają, jakby działały czasami, choć nie tak, jak bym chciał.
Zastanawiałem się, czy ktoś z taką samą konfiguracją używał kodu, który działa i mógłby przyjrzeć się mojemu kodowi. Szczególnie interesuje mnie też liczba wymaganych zgłoszeń, w zależności od liczby wierzchołków lub „wad wypukłości”, jak sądzę ...
Otrzymałem informacje od:
http://fly.cc.fer.hr/~unreal/theredbook/chapter13.htmlhttp://commaexcess.com/articles/7/concave-polygon-triangulation-shortcuthttp://graphicsbb.itgo.com/solutions/extrude.htmlhttp://analysesmusings.wordpress.com/2012/07/13/drawing-filled-concave-polygons-using-the-stencil-buffer/... ale nadal nie jest jasne ...
Oto mój kod (w rzeczywistości jeden z nich, ponieważ testowałem tak wiele konfiguracji) i obraz wyniku. Właściwie używam do umieszczenia rzeczywistego renderowania w metodzie zwanej dla każdego wielokąta, ale przepisałem go, aby było jasne:
EDYTOWAĆ
W rzeczywistości zrozumiałem, że muszę narysować każdy trójkąt, aby odwrócić wartość bitu w buforze szablonu. Przepisałem więc mój kod:
CGLContextObj cgl_ctx = [context CGLContextObj];
CGLLockContext(cgl_ctx);
GLenum error;
if(cgl_ctx == NULL)
return NO;
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glClear(GL_STENCIL_BUFFER_BIT);
glClearStencil(0);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
glStencilFunc(GL_ALWAYS, 1, 1);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// glColor4d(1., 1., 1., 1.); ----> does it make sense ?
glBegin(GL_TRIANGLE_FAN); {
for (int i = 1; i < [vertices count] - 1; i++) {
// Allways drawing the first vertex
glVertex2d([[[vertices objectAtIndex:0] objectAtIndex:0] doubleValue], [[[vertices objectAtIndex:0] objectAtIndex:1] doubleValue]);
// Then two others to make a triangle
glVertex2d([[[vertices objectAtIndex:i] objectAtIndex:0] doubleValue], [[[vertices objectAtIndex:i] objectAtIndex:1] doubleValue]);
glVertex2d([[[vertices objectAtIndex:i+1] objectAtIndex:0] doubleValue], [[[vertices objectAtIndex:i+1] objectAtIndex:1] doubleValue]);
}
}
glEnd();
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
glStencilFunc(GL_EQUAL, 1, 1);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glColor4d(1., 0., 0., 0.5);
glBegin(GL_TRIANGLE_FAN); {
for (id vertex in vertices) {
glVertex2d([[vertex objectAtIndex:0] doubleValue], [[vertex objectAtIndex:1] doubleValue]);
}
glVertex2d([[[vertices objectAtIndex:0] objectAtIndex:0] doubleValue], [[[vertices objectAtIndex:0] objectAtIndex:1] doubleValue]);
}
glEnd();
glDisable (GL_STENCIL_TEST);
glDisable(GL_BLEND);
glPopClientAttrib();
glPopAttrib();
if((error = glGetError()))
NSLog(@"OpenGL error %04X", error);
CGLUnlockContext(cgl_ctx);
return (error ? NO : YES);
Ale to nadal nie działa. Oto mój wynik i link do oryginalnego obrazu i wyjaśnienia.
EDYCJA 2:
W rzeczywistości kontekst włączony przez Quartz Composernie implementuje bufora wzornika. Wydaje się niemożliwe renderowanie bezpośrednio w OpenGL za pomocą bufora wzornika.