다음 코드는 glkit으로 색상 피킹을위한 완벽한 템플릿이 될 수 있습니다. 나는 왜 오프 스크린 버퍼에있는 모든 픽셀들이 nslog에 아래에 인쇄 된 것처럼 색깔 (0, 0, 0)인지 이해해야한다. 참고 : 정점 배열은 헤더 파일에서 const 배열로 정의됩니다. 이는 프로젝트의 다른 섹션에서 화면에 잘 표시됩니다 (문제는 오프 스크린과 관련됨).opengl glkit 색상 피킹 glreadpixels은 항상 0 색의 픽셀을 반환합니다. (0,0,0)
헤더 파일 다음의 ViewController 코드에서
typedef struct {
float Position[3];
float Color[4];
float TexCoord[2];
float Normal[3];
} Vertex;
//Vertices array format: {{vertex.x, vertex.y, vertex.z}, {color.R, color.G, color.B, color.alpha}, {texture.U, texture.V}, {normal.x, normal.y, normal.z}},
const Vertex parparit51OBJVertices[] = {
{{0.057, -0.088, -0.155},{1,1,1,1},{0.848, 0.810}, {0.329, -0.157, -0.931}},
{{0.056, -0.035, -0.165},{1,1,1,1},{0.848, 0.811}, {0.338, -0.139, -0.931}}, ......
:
GLuint _pickFBO = 0;
int32_t glVertexAttributeBufferID = 0;
- (IBAction) tapGesture:(id)sender
{
if ([(UITapGestureRecognizer *)sender state] == UIGestureRecognizerStateEnded) {
NSLog(@"In tap ended");
CGPoint tapLocation = [(UITapGestureRecognizer *)sender locationInView:self.view];
int tt = [self findMeshByPoint:tapLocation];
}
}
- (NSUInteger)findMeshByPoint:(CGPoint)point
{
//In openGL the y axis starts from the bottom of the screen
point.y = self.view.bounds.size.height - point.y;
GLKView *glView = (GLKView *)self.view;
NSAssert([glView isKindOfClass:[GLKView class]],
@"View controller's view is not a GLKView");
// Make the view's context current
[EAGLContext setCurrentContext:glView.context];
_height = ((GLKView *)self.view).drawableHeight;
_width = ((GLKView *)self.view).drawableWidth;
self.effect.useConstantColor = GL_TRUE;
self.effect.colorMaterialEnabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(1.0f,1.0f,1.0f,1.0f);
glBindVertexArrayOES(0);
glDisable(GL_DITHER);
glEnable(GL_DEPTH_TEST);
glLineWidth(2.0F);
// Important to turn light off !!!
self.effect.light0.enabled = GL_TRUE;
glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
//this crashes the code
//glEnableVertexAttribArray(GLKVertexAttribColor);
self.effect.constantColor = GLKVector4Make(0.0f, //This should be meshId/255.0f
0.8f, 0.8f, 1.0f);
if(0 == _glVertexAttributeBufferID)
{
GLuint glName;
glGenBuffers(1, // STEP 1
&glName);
glBindBuffer(GL_ARRAY_BUFFER, // STEP 2
glName);
glBufferData( // STEP 3
GL_ARRAY_BUFFER, // Initialize buffer contents
sizeof(parparit51OBJVertices), parparit51OBJVertices,
GL_STATIC_DRAW); // Hint: cache in GPU memory
_glVertexAttributeBufferID = glName;
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
NSLog(@"Error creating buffer %i. glError: 0x%04X", glName, err);
}
}
else
{
glBindBuffer(GL_ARRAY_BUFFER,
_glVertexAttributeBufferID);
}
[self buildFBO];
glBindFramebuffer(GL_FRAMEBUFFER, _pickFBO);
//glViewport(0, 0, _width, _height);
//???
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 12 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 12 * sizeof(GLfloat), (GLvoid*) (sizeof(float) * 9));
GLKMatrix4 modelViewMatrixForParparit = GLKMatrix4MakeTranslation(0.0f, 0.3f, -3.5f);
modelViewMatrixForParparit = GLKMatrix4Scale(modelViewMatrixForParparit, 1.0, 1.0, 1.0);
self.effect.transform.modelviewMatrix = modelViewMatrixForParparit;
self.effect.constantColor = GLKVector4Make(0.8f, 0.3f, 0.3f, 1.0f);
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, sizeof(parparit51OBJVertices)/sizeof(Vertex));
const GLfloat width = [glView drawableWidth];
const GLfloat height = [glView drawableHeight];
NSAssert(0 < width && 0 < height, @"Invalid drawble size");
int blackPixelsCounter = 0;
int coloredPixelsCounter = 0;
GLubyte savePixelColor[4] = {0, };
bool bFoundDifferentColors = NO;
GLubyte pixelColor[4]; // Red, Green, Blue, Alpha color
glReadPixels(50,
50,
1,
1,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixelColor);
//#ifdef DEBUG
{ // Report any errors
GLenum error = glGetError();
if(GL_NO_ERROR != error)
{
NSLog(@"GL Error: 0x%x", error);
}
}
//#endif
savePixelColor[0] = pixelColor[0];
savePixelColor[1] = pixelColor[1];
savePixelColor[2] = pixelColor[2];
for (GLint xx=0; xx<_width; xx++) {
for (GLint yy=0; yy<_height; yy++) {
glReadPixels(xx,
yy,
1,
1,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixelColor);
//#ifdef DEBUG
{ // Report any errors
GLenum error = glGetError();
if(GL_NO_ERROR != error)
{
NSLog(@"GL Error: 0x%x", error);
}
}
//#endif
if ((savePixelColor[0] != pixelColor[0]) || (savePixelColor[1] != pixelColor[1]) || (savePixelColor[2] != pixelColor[2]))
{
bFoundDifferentColors = YES;
}
if ((pixelColor[0] !=0) || (pixelColor[1] !=0) || (pixelColor[2] !=0)) {
//NSLog(@"pixelColor[0]=%i, pixelColor[1]=%i, pixelColor[2]=%i", pixelColor[0], pixelColor[1], pixelColor[2]);
coloredPixelsCounter++;
}
else
{
blackPixelsCounter++;
}
}
}
NSLog(@"colored pixels=%i black pixels=%i", coloredPixelsCounter, blackPixelsCounter);
if (bFoundDifferentColors)
{
NSLog(@"Found at least 2 different pixels colors in picking buffer !");
}
else
{
NSLog(@"All pixels have the same color: %i, %i, %i", savePixelColor[0], savePixelColor[1], savePixelColor[2]);
}
NSLog(@"******* 9");
//--- at the end !!! -------
// Restore OpenGL state that pickTerrainEffect changed
glBindFramebuffer(GL_FRAMEBUFFER, 0); // default frame buffer
//glViewport(0, 0, _width, _height); // full area of glView
//#ifdef DEBUG
{ // Report any errors
GLenum error = glGetError();
if(GL_NO_ERROR != error)
{
NSLog(@"GL Error: 0x%x", error);
}
}
//#endif
NSLog(@"******* 10");
return 0;
}
//tap-11
-(void) buildFBO
{
NSLog(@"before: buildFBO._pickFBO=%i", _pickFBO);
if (0 == _pickFBO)
{
NSLog(@"buildFBO._pickFBO=%i", _pickFBO);
GLuint colorRenderbuffer;
//GLuint framebuffer;
glGenFramebuffers(1, &_pickFBO);
glBindFramebuffer(GL_FRAMEBUFFER, _pickFBO);
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, _width, _height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER, colorRenderbuffer);
GLuint depthRenderbuffer;
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _width, _height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
GL_FRAMEBUFFER_COMPLETE)
{
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
//+++tbd+++UtilityPickTerrainEffectDestroyFBO(fboName);
return;
}
//#ifdef DEBUG
// { // Report any errors
GLenum error = glGetError();
if(GL_NO_ERROR != error)
{
NSLog(@"GL Error: 0x%x", error);
}
// }
//#endif
}
}
왜 외막에 관심이 있습니까? –
예수, 이것은 색 따기라는 이름의 알려진 방법입니다. 우리는 각 메쉬에 대해 고유 한 색으로 오프 스크린 버퍼에 렌더링합니다. 사용자가 화면을 두 드렸을 때 그는 그가 두드린 색깔을 얻습니다. 즉, 메쉬가 화면과 오프 스크린 버퍼 모두에 렌더링됩니다. 화면에서 원래 텍스처로 렌더링하고 오프 스크린 버퍼에 각 메쉬의 고유 한 색상으로 렌더링합니다. – user2492853
정말 잘 모르겠지만 도려내기를 사용하지 않으셨습니까? 당신이 깊이 테스트를하지는 않았지만 도려내는 걸 봤습니다. –