绘制opengl纹理的一部分

Posted

技术标签:

【中文标题】绘制opengl纹理的一部分【英文标题】:drawing part of open gl texture 【发布时间】:2013-10-22 10:01:02 【问题描述】:

我正在尝试仅绘制我的精灵表的一部分。但它只是缩放图像并且没有绘制图像宽度的 1/3。如何裁剪图像以便仅显示 1/3。文字如下(ios 7,opengl es 2)-(GLKMatrix4)modelMatrix

GLKMatrix4 modelMatrix = GLKMatrix4Identity;
modelMatrix = GLKMatrix4Translate(modelMatrix, x, y, 0);
return modelMatrix;


- (void)setSprite:(NSString *)fileName effect:(GLKBaseEffect *)newEffect 

// 1
self.effect = newEffect;

// 2
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithBool:YES],
                              GLKTextureLoaderOriginBottomLeft,
                              nil];

// 3
NSError * error;
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];

// 4
self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
if (self.textureInfo == nil) 
    NSLog(@"Error loading file: %@", [error localizedDescription]);
        return ;


TexturedQuad newQuad;
newQuad.bl.geometryVertex = CGPointMake(0, 0);
newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0);
newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width, self.textureInfo.height);

newQuad.bl.textureVertex = CGPointMake(0, 1);
newQuad.br.textureVertex = CGPointMake(1, 1);
newQuad.tl.textureVertex = CGPointMake(0, 0);
newQuad.tr.textureVertex = CGPointMake(1, 0);

self.quad = newQuad;



- (void)render 

// 1
self.effect.texture2d0.name = self.textureInfo.name;
self.effect.texture2d0.enabled = YES;

// 2
y++;
self.effect.transform.modelviewMatrix = self.modelMatrix;
[self.effect prepareToDraw];

// 3
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);


// 4
TexturedQuad q;
q.bl.textureVertex = CGPointMake(0, 1);
q.br.textureVertex = CGPointMake(1, 1);
q.tl.textureVertex = CGPointMake(0, 0);
q.tr.textureVertex = CGPointMake(1, 0);
q.bl.geometryVertex = CGPointMake(0, 0);
q.br.geometryVertex = CGPointMake(self.textureInfo.width/3, 0);
q.tl.geometryVertex = CGPointMake(0, self.textureInfo.height);
q.tr.geometryVertex = CGPointMake(self.textureInfo.width/3, self.textureInfo.height);
long offset2 =(long)&q;
//long offset = (long)&_quad;
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset2 + offsetof(TexturedVertex, geometryVertex)));
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset2 + offsetof(TexturedVertex, textureVertex)));

// 5
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

更新: TexturedQuad 新四边形; newQuad.bl.geometryVertex = CGPointMake(0, 0); newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width/3, 0); newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height); newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width/3, self.textureInfo.height);

newQuad.bl.textureVertex = CGPointMake(0, 1);
newQuad.br.textureVertex = CGPointMake(.3, 1);
newQuad.tl.textureVertex = CGPointMake(0, 0);
newQuad.tr.textureVertex = CGPointMake(.3, 0);

【问题讨论】:

【参考方案1】:

这就是纹理坐标的用途。您的“textureVertex”指定映射到四边形的纹理的完整尺寸(0.0 到 1.0)。您需要将其中一些值更改为 1/3 或 2/3。例如:

newQuad.bl.textureVertex = CGPointMake(0, 0.33);
newQuad.br.textureVertex = CGPointMake(1, 1);
newQuad.tl.textureVertex = CGPointMake(0, 0.33);
newQuad.tr.textureVertex = CGPointMake(1, 0);

【讨论】:

但是我应该存储整个纹理然后在渲染方法中绘制主纹理的一部分吗? 是的,存储整个纹理。无论如何,在大多数嵌入式平台上,glTexSubImage2D() 并不比 glTexImage2D() 快多少。

以上是关于绘制opengl纹理的一部分的主要内容,如果未能解决你的问题,请参考以下文章

iOS OpenGL ES简单绘制纹理

像素区域的OpenGL纹理映射

Android音视频 OpenGL ES2.0 绘制图片纹理

Android音视频 OpenGL ES2.0 绘制图片纹理

OpenGL纹理不会绘制

我的OpenGL学习进阶之旅关于OpenGL ES 绘制纹理,因为加载纹理坐标设置错误,导致纹理无法渲染的问题