我在iOS上使用OpenGL ES 2渲染(相对)巨大的2D网格,其中正方形("像素")是脱节的 - 间隔而不是棋盘图案 - 并且概述了,并且我正在尝试最糟糕的时间找出一种有效的绘制方法,使得该正方形的每个正方形和轮廓可以分配不同的颜色,因为这是绘图应用程序.网格必须能够表示高达1024x1024"像素".
最初,我尝试了将所有顶点数据放在一个大型缓冲区中的方法,并且glDrawArrays
每帧只需一次调用就可以渲染它,但正如您所料,内存使用情况不合理,只有轮廓(用GL_LINES制作) ) - 没有填充.进一步的研究让我了解了实例绘图,我现在正在做的glDrawArraysInstancedEXT
,但是,当然,1024*1024实例绘制调用正在杀死CPU/FPS.我猜这个问题的解决方案介于两种方法之间 - 使用简并顶点绘制一个更大的"分组"GL_TRIANGLE_STRIPs原语来分隔生成的方块......但是我不认为我可以给每个方格它自己的颜色.不用说,我还在学习; 人们通常如何绘制大量简单,相同但色彩鲜艳的多边形?
相关代码......
static const int numColumns = 1024; static const int numRows = 1024; static const GLfloat outlineVertices[] = { 0.1f, -0.1f, 0.9f, -0.1f, 0.1f, -0.9f, 0.9f, -0.9f }; static const GLfloat innerVertices[] = { 0.2f, -0.2f, 0.8f, -0.2f, 0.2f, -0.8f, 0.8f, -0.8f }; - (void)setupGL { [EAGLContext setCurrentContext:self.context]; [self loadShaders]; glDisable(GL_DEPTH_TEST); glGenVertexArraysOES(1, &_vertexArray); glBindVertexArrayOES(_vertexArray); glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(outlineVertices), outlineVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); } - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.65f, 0.65f, 0.65f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArrayOES(_vertexArray); glUseProgram(_program); glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); glUniform1i(uniforms[NUM_COLUMNS], numColumns); glUniform1i(uniforms[NUM_ROWS], numRows); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(outlineVertices), outlineVertices, GL_STATIC_DRAW); glUniform1i(uniforms[DRAWING_INNER], 0); glDrawArraysInstancedEXT(GL_TRIANGLE_STRIP, 0, 4, numColumns * numRows); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(innerVertices), innerVertices, GL_STATIC_DRAW); glUniform1i(uniforms[DRAWING_INNER], 1); glDrawArraysInstancedEXT(GL_TRIANGLE_STRIP, 0, 4, numColumns * numRows); } vshader: #extension GL_EXT_draw_instanced : enable attribute vec4 vertices; varying lowp vec4 colorVarying; uniform int numColumns; uniform int numRows; uniform mat4 modelViewProjectionMatrix; uniform int drawingInner; void main() { if (drawingInner == 0) { colorVarying = vec4(1.0, 0.0, 1.0, 1.0); } else { colorVarying = vec4(0.0, 0.0, 1.0, 1.0); } float column = mod(float(gl_InstanceIDEXT), float(numColumns)); float row = -(float(gl_InstanceIDEXT / numColumns)); gl_Position = vec4(vertices.x + column, vertices.y + row, vertices.zw) * modelViewProjectionMatrix; }
任何帮助表示赞赏,包括最佳实践提示.有没有办法有效地绘制这个庞大的网格,而无需根据用户当前看到的内容更改数据...某种手动剔除?谢谢!
最好在片段着色器中执行此操作.这样,您可以使用普通的普通纹理,并且可以忘记必须渲染多于一个四边形的东西.这是一个绘制网格的着色器,每个像素具有不同的前景/背景颜色.它被编写为在ShaderToy中运行,因此您必须根据您的程序进行调整.
我在ShaderToy上放了一个现场演示(这与下面的代码略有不同,所以它可以在ShaderToy上运行).
precision mediump float;
// Texture coordinates, from 0 to 1
varying vec2 TexCoord;
uniform sampler2D FGTex;
uniform sampler2D BGTex;
// Texture size, in pixels.
uniform vec2 TexSize;
// Width of grid lines, from 0 to 1
uniform float GridWidth;
void main() {
// Get the foreground and background colors
vec4 fgColor = texture2D(FGTex, TexCoord);
vec4 bgColor = texture2D(BGTex, TexCoord);
// Calculate the grid
vec2 gridPos = fract(TexCoord * TexSize + GridWidth * 0.5);
vec2 gridFrac = step(GridWidth, gridPos);
gl_FragColor = mix(bgColor, fgColor, gridFrac.x * gridFrac.y);
}
请注意,网格线是不一致的,除非你完全正确的数学运算使它们排成一行,但你必须这样做.