To determine what I'm trying to do: I want to be able to take an arbitrary 2x2 × 2 PNG sprite image and display only the pixels of interest for a given x / y position on the screen.
My results - the problem - the main distortion - it looks awful! (Note that these SSs are in the iPhone sim, but on the real retina they look the same .. junky). Here is a screenshot of the original PNG in the “preview” - which looks great (any rendering options that I describe in this question look almost exactly like the younger one)
I used to ask a question about displaying non-permissions texture 2 as a sprite using OpenGL ES 2.0 (although this applies to any OpenGL as well). I am close, but I have some problems that I cannot solve. I think there are probably a few errors - I think there is some kind of error in which I basically smooth out what I show by rendering larger than crush x2 or vice versa, but I do not see this. In addition, there is one mistake, and I can not deal with them. I cannot visually identify them, but I know for sure that they are there.
I work in 960 x 640 landscape format (on the iPhone4 Retina screen). Therefore, I expect that 0-> 959 moves from left to right, 0-> 639 moves from bottom to top. (And I think I see the opposite - but this is not the issue in question)
To do everything that I try to achieve in this test case, FULL SCREEN 960x640 is displayed for the PNG file. Only one of them. First I show a red background so that it is obvious if I close the screen or not.
: , "glViewport" setFramebuffer . , , , 0,0 100 100, , . , . , , 0,0 → 480,320 ( "" ). . , , .
:
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
mat4 projectionMatrix = mat4( 2.0/640.0, 0.0, 0.0, -1.0,
0.0, 2.0/960.0, 0.0, -1.0,
0.0, 0.0, -1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
void main()
{
gl_Position = a_position;
gl_Position *= projectionMatrix;
v_texCoord = a_texCoord;
}
:
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main()
{
gl_FragColor = texture2D(s_texture, v_texCoord);
}
:
#define MYWIDTH 960.0f
#define MYHEIGHT 640.0f
#define BG_X_ORIGIN 0.0f
#define BG_X_DEST 640.0f
#define BG_Y_ORIGIN 0.0f
#define BG_Y_DEST 960.0f
#define BG_X_ZERO 0.0f
#define BG_Y_USEPERCENTAGE BG_X_DEST / 1023.0f
#define BG_Y_ZERO 0.0f
#define BG_X_USEPERCENTAGE BG_Y_DEST / 1023.0f
[(EAGLView *)self.view setFramebuffer];
static const GLfloat backgroundVertices[] = {
BG_X_ORIGIN, BG_Y_ORIGIN,
BG_X_DEST, BG_Y_ORIGIN,
BG_X_ORIGIN, BG_Y_DEST,
BG_X_DEST, BG_Y_DEST
};
static const GLfloat backgroundTexCoords[] = {
BG_X_ZERO, BG_Y_USEPERCENTAGE,
BG_X_USEPERCENTAGE, BG_Y_USEPERCENTAGE,
BG_X_ZERO, BG_Y_ZERO,
BG_X_USEPERCENTAGE, BG_Y_ZERO
};
glEnable(GL_TEXTURE_2D);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, backgroundVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, 0, 0, backgroundTexCoords);
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, background->textureId);
glUniform1f(uniforms[UNIFORM_SAMPLERLOC], 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[(EAGLView *)self.view presentFramebuffer];
[1]:
BG_X_DEST 639.0f, 640 , . - , 0 640, 641 , 640!!! 639f 640f
BG_Y_DEST 959.0f, show throug.
, 958f 960 959f
, .
: [2] - OpenGL ES 2 Xcode
- (void)setFramebuffer
{
if (context)
{
[EAGLContext setCurrentContext:context];
if (!defaultFramebuffer)
[self createFramebuffer];
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
glViewport(0, 0, framebufferWidth, framebufferHeight);
}
}
[3]: - OpenGL ES 2 Xcode
- (BOOL)presentFramebuffer
{
BOOL success = FALSE;
if (context)
{
[EAGLContext setCurrentContext:context];
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
success = [context presentRenderbuffer:GL_RENDERBUFFER];
}
return success;
}
[4] - ( PNG - , ... , ARGB RGBA, - A = 1.0 , , , RGBA .): update: CG/ImageIO, , , - , ( , ..)
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glGenTextures(1, &(newTexture->textureId));
glBindTexture(GL_TEXTURE_2D, newTexture->textureId);
NSString *path = [[NSBundle mainBundle]
pathForResource:[NSString stringWithUTF8String:newTexture->filename.c_str()] ofType:@"png"];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
if (image == nil)
NSLog(@"Do real error checking here");
newTexture->width = CGImageGetWidth(image.CGImage);
newTexture->height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc(newTexture->height * newTexture->width * 4 );
CGContextRef myContext = CGBitmapContextCreate
(imageData, newTexture->width, newTexture->height, 8, 4 * newTexture->width, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease(colorSpace);
CGContextClearRect(myContext, CGRectMake(0, 0, newTexture->width, newTexture->height));
CGContextDrawImage(myContext, CGRectMake(0, 0, newTexture->width, newTexture->height), image.CGImage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newTexture->width, newTexture->height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, imageData);
CGContextRelease(myContext);
free(imageData);
[image release];
[texData release];