Искажение пикселей в iPhone при масштабировании контента OpenGL ES для приложения Paint - PullRequest
2 голосов
/ 31 января 2012

У меня странная проблема с openGL ES. Я работаю над приложением рисования для iphone [используя ссылку из приложения GLPaint]. В своем коде я использую imageView, который содержит контурное изображение, на которое я помещаю [CAEAGLLayer] paintView для заливки цветов. Я заполняю цвета контурного изображения линиями рисунков на экране в зависимости от того, где пользователь касается. Я использую функцию "renderLineFromPoint", чтобы нарисовать линию между двумя точками, используя "touchesMoved" для получения начальной и конечной точек.

- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end{

// Рисование линии на экране в зависимости от того, где пользователь касается

static GLfloat*     vertexBuffer = NULL;
static NSUInteger   vertexMax = 64;

NSUInteger          vertexCount = 0,
                    count,
                    i;

[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

// Convert locations from Points to Pixels
//CGFloat scale = self.contentScaleFactor;
CGFloat scale;
if ([self respondsToSelector: @selector(contentScaleFactor)])
{

    scale=self.contentScaleFactor;

}
else{


//scale = 1.000000;

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00) {
        // RETINA DISPLAY

        scale = 2.000000;
    }
    else {
        scale = 1.000000;
    }

}




start.x *= scale;
start.y *= scale;
end.x *= scale;
end.y *= scale;

float dx = end.x - start.x;
float dy = end.y - start.y;
float dist = (sqrtf(dx * dx + dy * dy)/ kBrushPixelStep);

// Allocate vertex array buffer
if(vertexBuffer == NULL)    
vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat));


// Add points to the buffer so there are drawing points every X pixels

count = MAX(ceilf(dist), 1);

//NSLog(@"count %d",count);

for(i = 0; i < count; ++i) {
    if(vertexCount == vertexMax) {
        vertexMax = 2 * vertexMax;
        vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));

    //  NSLog(@"if loop");

    }



    vertexBuffer[2 * vertexCount + 0] = start.x + (dx) * ((GLfloat)i / (GLfloat)count);
    vertexBuffer[2 * vertexCount + 1] = start.y + (dy) * ((GLfloat)i / (GLfloat)count);

    vertexCount += 1;


}





// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);





glDrawArrays(GL_POINTS, 0, vertexCount);


    // Display the buffer



glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];


}

Теперь я масштабирую вид краски с помощью жеста:

 UIPinchGestureRecognizer *twoFingerPinch = 
[[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerPinch:)] autorelease];
[self addGestureRecognizer:twoFingerPinch];



- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer 
{



if([recognizer state] == UIGestureRecognizerStateBegan) {
    // Reset the last scale, necessary if there are multiple objects with different scales
    lastScale = [recognizer scale];
}

if ([recognizer state] == UIGestureRecognizerStateBegan || 
    [recognizer state] == UIGestureRecognizerStateChanged) {

    CGFloat currentScale = [[[recognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];

    // Constants to adjust the max/min values of zoom
    const CGFloat kMaxScale = 2.0;
    const CGFloat kMinScale = 1.0;

    CGFloat newScale = 1 -  (lastScale - [recognizer scale]); 
    newScale = MIN(newScale, kMaxScale / currentScale);   
    newScale = MAX(newScale, kMinScale / currentScale);
    CGAffineTransform transform = CGAffineTransformScale([self transform], newScale, newScale);
    self.transform = transform;

    lastScale = [recognizer scale];  // Store the prev

    textureScale = lastScale;




    [self setContentScaleFactor:2.0f];


    CGRect frame = self.bounds;


    NSLog(@"Scale %f Last scale %f width %f Height %f", newScale , lastScale, frame.size.width * newScale, frame.size.height * newScale);



}

}

Вышеупомянутый код работает, но после масштабирования линий в paintView искаженные пиксели [не отображение сетчатки].

Есть ли способ перерисовать содержимое открытых окон на основе масштаба увеличения.

Заранее благодарю,

1 Ответ

3 голосов
/ 31 января 2012

Это совсем не странно. Когда вы рисуете в OpenGL, вы рисуете с фиксированным разрешением, и это разрешение соответствует размеру вашего контекста OpenGL. Скорее всего, вы создаете контекст, соответствующий разрешению вашего экрана.

Вам придется создать свой контекст GL больше, чем экран, если вы хотите иметь возможность увеличивать изображение без интерполяции изображения. Например, если вы хотите увеличить масштаб до 200%, вам придется создать контекст с удвоенным количеством пикселей в качестве экрана.

...