[英]Drawing 2D bitmap in OpenGL ES (iOS)
我一直在挣扎了几个小时试图渲染的OpenGL ES(IOS)一个简单的2D位图。 虽然在OpenGL中我可以简单地使用glDrawPixels,但它在OpenGL ES中不存在,glBegin也不存在。 好像glVertexPointer现在也已被弃用。
(注意:我正在渲染的位图以60 FPS不断变化,因此与使用纹理相比,glDrawPixels 是更好的解决方案)
我找不到使用现有API绘制位图的任何文档示例代码。
简而言之:给定一个像素数组(例如RGBX格式),我如何渲染它,可能使用OpenGL ES使用最近的邻居缩放?
简短的答案是渲染带纹理的四边形并实现模型矩阵以执行各种变换(例如缩放)。
首先,您需要使用四边形的顶点位置构建一个VBO:
float[] positions = {
+0.5f, +0.5f, +0f, // top right
-0.5f, +0.5f, +0f, // top left
+0.5f, -0.5f, +0f, // bottom right
-0.5f, -0.5f, +0f // bottom left
};
int positionVBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
glBufferData(GL_ARRAY_BUFFER, floatBuffer(positions), GL_STATIC_DRAW);
然后将必要的信息传递给您的顶点着色器:
int positionAttribute = glGetAttribLocation(shader, "position");
glEnableVertexAttribArray(positionAttribute);
glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, false, 0, 0);
现在,我们将执行相同的操作,但使用四边形的纹理坐标:
float[] texcoords = {
1f, 0f, // top right
0f, 0f, // top left
1f, 1f, // bottom right
0f, 1f // bottom left
};
int texcoordVBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, texcoordVBO);
glBufferData(GL_ARRAY_BUFFER, floatBuffer(texcoords), GL_STATIC_DRAW);
int textureAttribute = glGetAttribLocation(shader.getId(), "texcoord");
glEnableVertexAttribArray(textureAttribute);
glVertexAttribPointer(textureAttribute, 2, GL_FLOAT, false, 0, 0);
您可以将这些数据插入单个VBO中,但我将留给读者。 无论如何,我们都已将所有四边形顶点数据提交给GPU,并告诉着色器如何访问它。
接下来,假设我们有一个名为image
的对象,我们将构建纹理缓冲区:
int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.getWidth(), image.getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.getPixels());
并将该信息传递给着色器:
int textureUniform = glGetUniformLocation(shader, "image");
glUniform1i(textureUniform, 0);
有关纹理的更多信息,请参见open.gl的页面 。
最后,着色器:
顶点
attribute vec3 position;
attribute vec2 texcoord;
varying vec2 uv;
void main()
{
gl_Position = vec4(position, 1.0);
uv = texcoord;
}
片段
varying vec2 uv;
uniform sampler2D image;
void main()
{
gl_FragColor = texture(image, uv);
}
在没有其他GL状态更改的情况下,这将呈现以下内容:
注意:由于我无权访问iOS开发环境,因此此示例是用Java编写的。 但是原理是一样的。
编辑:如何建立着色器程序
着色器程序由一系列着色器组成。 最低限度是一个顶点和片段着色器。 这就是我们从上面的两个着色器构建着色器程序的方式:
String vertexSource = loadShaderSource("vertex.glsl");
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, vertexSource);
glCompileShader(vertexShader);
String fragmentSource = loadFileAsString("fragment.glsl");
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, fragmentSource);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
创建后,您将通过glVertexAttribPointer
和glUniform
与它进行通信。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.