使用纹理进行OpenGL ES 2.0渲染

15

iPhone SDK中有一个使用ES 2.0与(Vertex&Fragment) GLSL着色器渲染带有不同颜色的盒子的示例。是否有关于如何使用此API呈现简单纹理的示例?我想基本上要取一个四边形,然后将纹理绘制到其上。

旧的ES 1.1 API已经不再起作用了,因此我需要一些帮助入门。大多数着色器参考主要讨论高级着色主题,但我真的不确定如何告诉着色器使用绑定的纹理以及如何引用UV。


你说的“旧的ES 1.1 API不再起作用”是什么意思?我正在使用GL ES 1.1,它完美地工作着。 - Goles
我想表达的是,你不能直接将 ES 1.1 函数调用插入到 ES 2.0 初始化的上下文中。当然,你可以初始化 ES 1.1 并使用它,但你无法利用着色器。 - Kalen
4个回答

15

网站上有一个很好的教程,与书籍OpenGL ES 2相配套。该书的示例都在www.opengles-book.com上。

第9章Simple_Texture2D正是你想要的。它设置了一个采样纹理的着色器,初始化它,并使用纹理对三角形进行着色。

着色器程序接近于:

varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main() {
  gl_FragColor = texture2D(s_texture, v_texCoord);
}

然后你这样设置:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, userData->textureId);
// Set the sampler texture unit to 0
glUniform1i(userData->samplerLoc, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

但是请查看我上面提供的链接中的实际代码,以真正了解示例。


1
这只是半个答案。您需要解释userData等是什么。我来到这里是因为我已经有那本书了,但当他们到达纹理章节时,作者放弃了;书中的代码质量下降,解释变得简短和过时(专注于GL 1而不是GL 2等)。最终,你被迫把书扔进垃圾桶,在互联网上下载源代码,并尝试在没有作者帮助的情况下弄清楚它。如果您正在iPad上浏览,那就毫无帮助。 - Adam
参考我的下面回答,我最终弄清楚了所有缺失的部分。完整代码如下... - Adam
2
"glEnableVertexAttribArray(0); glEnableVertexAttribArray(1);" 任何一本使用硬编码数字而不是将它们存储在变量中(由ogl分配)的书籍,我都会远离。谁知道他们还在尝试教授什么其他糟糕的东西呢。 - Kevin

9
这是我能制作的最简单的可以正常工作的版本:
设置(在为您的顶点数组执行glVertexAttribPointer之后立即进行)
GLint program; // your shader-program, pre-filled

...

// AFTER you've created *and set* the EAGLContext
GLKTextureInfo* appleTexture = [GLKTextureLoader
         textureWithContentsOfFile:... options:... error:...];
// NB: make sure that the returned texture is not nil!
// if it's nil, you'll get black objects, and need to check
// your path to your texture file

...

// INSIDE your VAO setup (usually "setupGL" in Apple's template),
// assuming you're using VAO,
// i.e. after "glBindVertexArrayOES"
GLint _textureBuffer; // an empty buffer that we'll create and fill
glEnableVertexAttribArray( glGetAttribLocation(program, "a_textureCoordinate") );
glGenBuffers(1, &_textureBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer);
glBufferData(GL_ARRAY_BUFFER, 
        self.currentScene.meshNumVertices * sizeof( (*self->sharedMeshTextureCoords) ),
        self->sharedMeshTextureCoords, GL_DYNAMIC_DRAW);
glVertexAttribPointer( glGetAttribLocation(program, "a_textureCoordinate"),
        2, GL_FLOAT, GL_FALSE, 0, 0);

glActiveTexture(GL_TEXTURE0);

渲染(在调用glDrawArrays或类似函数之前的最后一步)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, [appleTexture name]);
glUniform1i( glGetUniformLocation( program, "s_texture"), 0); // No idea

纹理着色器:
attribute vec4 position;
attribute vec2 a_textureCoordinate;

varying vec2 v_textureCoordinate;

uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

void main()
{
    v_textureCoordinate = a_textureCoordinate;
    gl_Position = modelViewProjectionMatrix * position;
}

片段着色器:

uniform sampler2D s_texture;
varying mediump vec2 v_textureCoordinate;

void main(void)
{
    gl_FragColor = texture2D( s_texture, v_textureCoordinate );
}

5

不幸的是,OpenGL ES 2.0使用了GLSL 1.4版本,这是一个较低版本。大多数人发布的教程在这个版本下不起作用。所有辅助变量(如ftransform和gl_TexCoord [0])都已被删除。找到超越基础知识的特定ES 2.0教程很困难。

OpenGL ES 2.0是一个完全可编程的管道,他们取消了任何固定功能。如果你想使用它,你必须提供自己的矩阵来跟踪原来的模型视图和投影矩阵。

我知道你几个月前发布过,但如果有人仍在寻找信息,请在opengl.org上搜索与OpenGL 3.0相关的内容。那里有许多好的源代码可以参考。那里的论坛也是一个非常好的信息来源。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接