Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

orangeiris

macrumors newbie
Original poster
Since Open GL requires the use of "power of 2" sized images, there must be a way to use only a portion of an image as an actual texture, but I can't for the life of me figure out how. I starting playing around with glTexSubImage2D, but got no where.

I've taken the GL Sprite demo code and I'm trying to create a shape that will act as a background image. Since 320x480 is not a "power of 2" dimension, I can create a background by creating a 512x512 sized object and positioning it appropriately, but I'd rather create a 320x480 sized object and offset a 512x512 sized image within it to use as a texture. Can this be done?

Here's the code I'm working with so far:

Code:
const GLfloat spriteVertices[] = {
-1.6f, -1.6f,
1.6f, -1.6f,
-1.6f,  1.6f,
1.6f,  1.6f,
};

const GLshort spriteTexcoords[] = {
0, 0,
1, 0,
0, 1,
1, 1,
};

Some setup code:

Code:
glVertexPointer(2, GL_FLOAT, 0, spriteVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_SHORT, 0, spriteTexcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

spriteImage = [UIImage imageNamed:@"BackgroundCopy.png"].CGImage;
width = CGImageGetWidth(spriteImage);
height = CGImageGetHeight(spriteImage);

if (spriteImage) {
	spriteData = (GLubyte *) malloc(width * height * 4);
	spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
	CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);
	CGContextRelease(spriteContext);
	
	glGenTextures(1, &spriteTexture);
	glBindTexture(GL_TEXTURE_2D, spriteTexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
	free(spriteData);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glEnable(GL_TEXTURE_2D);
	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);
}

Drawing code:

Code:
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);	
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
 
I think the best way to do this is to change your texture coordinates. 0,0 is the top left, 1,1 is the bottom right. So if you had this:

Code:
const GLshort spriteTexcoords[] = {
  0,            0,
  480.0/512.0,  0,
  0,            320.0/512.0,
  480.0/512.0,  320.0/512.0,
};

or some variation therof, it should only show the 320x480 top left portion of your map.
 
I think the best way to do this is to change your texture coordinates. 0,0 is the top left, 1,1 is the bottom right. So if you had this:

Code:
const GLshort spriteTexcoords[] = {
  0,            0,
  480.0/512.0,  0,
  0,            320.0/512.0,
  480.0/512.0,  320.0/512.0,
};

or some variation therof, it should only show the 320x480 top left portion of your map.

I think you better use these (s,t) tex coords:

sMin = 0.5 / textureWidth;
sMax = spriteWidth - 0.5 / textureWidth;
tMin = 0.5 / textureHeight;
tMax = spriteHeight - 0.5 / textureHeight;

...to sample each texel at the center and avoid sampling artifacts at the boundaries.

(check this out)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.