【问题标题】:OpenGL ES 2.0 - Textured QuadOpenGL ES 2.0 - 纹理四边形
【发布时间】:2012-11-19 14:15:06
【问题描述】:

每当我尝试渲染一个带纹理的四边形时,我最终都会得到一个扭曲的纹理三角形部分: .

纹理是在 GIMP 中创建的 PNG,我尝试了两种不同的加载纹理的方法(均来自 Apple 自己的示例代码)。每种加载纹理的方法都会产生不同的结果(我不知道是默认设置不同,还是纹理有问题),但我都无法正确渲染。

根据Fastest way to draw quads in OpenGL ES? 中发布的建议,我尝试以多种不同的方式设置我的索引/垂直/texices,但仍然没有成功。

我可能会错过什么?

加载纹理的代码

- (GLuint)setupTexture:(NSString *)fileName {    
    CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage;
    if (!spriteImage) {
        NSLog(@"Failed to load image %@", fileName);
        exit(1);
    }
    size_t width = CGImageGetWidth(spriteImage);
    size_t height = CGImageGetHeight(spriteImage);
    GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte));
    CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, 
    CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);    
    CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
    CGContextRelease(spriteContext);
    GLuint texName;
    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
    free(spriteData);        
    return texName;    
}

纹理坐标和垂直

const GLfloat texices[] =
    { 0,1,
      1,1,
      0,0,
      1,0 };

glActiveTexture(GL_TEXTURE0);
glUniform1i(_texturedTextureUniformSlot, 0);
glVertexAttribPointer(_texturedTextureSlot, 2, GL_FLOAT, GL_FALSE, 0, texices);

GLfloat vertices[] = {-1, -1, 0, //bottom left corner
                  -1,  1, 0, //top left corner
                   1,  1, 0, //top right corner
                   1, -1, 0}; // bottom right rocner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                 0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexAttribPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

【问题讨论】:

  • 你的纹理幂是二吗?请显示更多代码。
  • 是的,它是 1024x1024。我也刚刚将setupTexture 函数附加到我的帖子中。
  • 请发布一些代码,其中为屏幕对齐的四边形指定纹理坐标。
  • 添加纹理坐标代码,我相信这些是生成截图的坐标。

标签: ios xcode opengl-es opengl-es-2.0


【解决方案1】:

看起来你的纹理坐标可能是错误的(注意纹理似乎环绕在左侧)。

这是我过去使用过的一段 sn-p 代码:

const float quadPositions[] = {  1.0,  1.0, 0.0, 
                                -1.0,  1.0, 0.0, 
                                -1.0, -1.0, 0.0, 
                                -1.0, -1.0, 0.0, 
                                 1.0, -1.0, 0.0, 
                                 1.0,  1.0, 0.0 };
const float quadTexcoords[] = { 1.0, 1.0, 
                                0.0, 1.0, 
                                0.0, 0.0, 
                                0.0, 0.0, 
                                1.0, 0.0, 
                                1.0, 1.0 };

// stop using VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);

// setup buffer offsets
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), quadPositions);
glVertexAttribPointer(ATTRIB_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), quadTexcoords);

// ensure the proper arrays are enabled
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_TEXCOORD0);

// draw
glDrawArrays(GL_TRIANGLES, 0, 2*3);

这应该在 z=0 处绘制两个三角形。您需要将投影的宽度和高度设置为 -1 到 1。

编辑:

这是您的代码的工作版本:

const GLfloat texices[] = { 0, 0,
                            0, 1,
                            1, 1,
                            1, 0 };


const GLfloat vertices[] = { -1, -1, 0,  // bottom left corner
                             -1,  1, 0,  // top left corner
                              1,  1, 0,  // top right corner
                              1, -1, 0}; // bottom right corner

const GLubyte indices[] = { 0, 2, 1,     // first triangle (bottom left - top left - top right)
                            0, 3, 2 };


// ensure no VBOs or IBOs are bound
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);    

glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), vertices);
glVertexAttribPointer(ATTRIB_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), texices);

// ensure the proper arrays are enabled
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_TEXCOORD0);

glDisable(GL_CULL_FACE);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

【讨论】:

  • 我没有发现纹理坐标和纹理顶点的组合有效。您可能仍然是对的,但我非常怀疑,因为我的代码是直接从 OpenGL ES 2.0 教程中删除的。唯一的区别是上述教程不是为 2D 渲染编写的。是否有可能我需要调用一些函数才能使在 Z=0.0f 上渲染的三角形正确显示?
  • 我查看了我的glDrawElements 方法,我认为发生的事情是glDrawElements 在索引不是单调增加时没有选择正确的纹理坐标。因此glDrawElements 在处理纹理时毫无意义。 Drawing cube using glDrawElements and glTexCoordPointer
  • 我还不确定问题是什么;我认为在这种情况下您应该可以使用glDrawElements。一个问题可能是glVertexPointer 的使用——这仅对 ES 1.0 有效。
  • 对不起,我的代码示例中要写glVertexAttribPointer(我不使用glVertexPointer)。我刚刚编辑了我原来的帖子来解决这个问题。
  • 我在上面的代码中添加了一个编辑。
猜你喜欢
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
相关资源
最近更新 更多