gpt4 book ai didi

ios - 在 iOS 上使用 OpenGLES 进行多图协作

转载 作者:行者123 更新时间:2023-11-29 12:31:27 25 4
gpt4 key购买 nike

我正在开发一个配置的应用程序:

  • 硬编码存储 100 个点的数组 A
  • 用户可以在屏幕上用手指自由绘画。

现在我使用 OpenGLES 绘图。在这段时间内有 2 个 Action :

  • 用户绘图
  • 从数组A自动绘制

我的意思是当用户用他的手指在屏幕上画画时,代码会自动遍历数组 A 将它的点画到屏幕上。

我配置了 2 个名为 vboId 和 vboId_1 的缓冲区来绑定(bind)每个 Action 的点,vboId 将绑定(bind)用户绘制的顶点,vboId_1 将绑定(bind)数组 A 中的顶点。以下是绘图代码(假设 openGLES 的所有初始化上下文、帧缓冲区、渲染缓冲区等已准备就绪)

- (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end isOwner:(BOOL)owner {
static GLfloat* vertexBuffer = NULL;
static NSUInteger vertexMax = 64;
NSUInteger vertexCount = 0,
count,
i;

[EAGLContext setCurrentContext:context];
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);

// Convert locations from Points to Pixels
CGFloat scale = self.contentScaleFactor;
start.x *= scale;
start.y *= scale;
end.x *= scale;
end.y *= scale;

// Allocate vertex array buffer
if(vertexBuffer == NULL)
vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat));

// Add points to the buffer so there are drawing points every X pixels
count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1);
for(i = 0; i < count; ++i) {
if(vertexCount == vertexMax) {
vertexMax = 2 * vertexMax;
vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
}

vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
vertexCount += 1;
}

// Draw
if (drawing_by_user) {
// Draw vertex from user
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);

glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);

glBindTexture(GL_TEXTURE_2D, brushTexture.id);

glUseProgram(program[PROGRAM_POINT_USER].id);
glDrawArrays(GL_POINTS, 0, (int)vertexCount);
} else {
// draw vertex automatically
glBindBuffer(GL_ARRAY_BUFFER, vboId_1);
glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);

glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);

glBindTexture(GL_TEXTURE_2D, brushTexture.id);

glUseProgram(program[PROGRAM_POINT_AUTO].id);
glDrawArrays(GL_POINTS, 0, (int)vertexCount);
}


// Display the buffer
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
}

实际上此代码有效,发生了 2 个操作,但它不符合我的预期。画的时候,有时会卡住,漏点,掉点,不流畅,用户体验不好。

如果只是用户绘制或者从数组A中绘制都可以,很顺利

我想我不能同时将 2 个 Action 绑定(bind)到帧缓冲区和渲染缓冲区,并发性或者我必须使用一些更高的机制来实现

更新 1:我意识到问题似乎是由应用程序在数组 A 上自动绘制点时无法接收触摸事件引起的。我的意思是在数组 A 上绘制点时无法识别某些函数 touchBegan、touchMove 和 touchEnd。

这太奇怪了,如果只绘制其中一个,它会起作用,我看不出有什么区别,只绘制其中一个也会执行这些操作(绑定(bind)缓冲区,渲染缓冲区...),仍然绘制它们使用这些功能。为什么不触发这些触摸事件。

谁能帮帮我

最佳答案

首先,我建议您阅读有关在 iOS 应用程序中使用 OpenGL ES 的文档。例如,

因为您从 touchesBegan 等调用了 EAGLContext -presentRenderbuffer:。这是一种非常低效的方式。

来自 Apple 文档“A GLKit View Controller Animates OpenGL ES Content”

By default, a GLKView object renders its contents on demand. That said, a key advantage to drawing with OpenGL ES is its ability to use graphics processing hardware for continuous animation of complex scenes—apps such as games and simulations rarely present static images. For these cases, the GLKit framework provides a view controller class that maintains an animation loop for the GLKView object it manages. This loop follows a design pattern common in games and simulations, with two phases: update and display. Figure 3-2 shows a simplified example of an animation loop.

Figure 3-2 animation loop

通常使用 OpenGL ES 的应用程序使用像这个 GLKit 文档这样的动画循环。在更新阶段,更新 3D 对象的位置、3D 模型的运动、计算线的下一个点,等等。在显示阶段,应用程序使用 OpenGL ES API 来渲染 3D 对象、3D 模型、线条等。

所以你可能需要如下实现。

  • 在触摸事件中,将触摸的位置保存在内存中。不渲染任何东西,此时不使用 OpenGL ES API。
  • 在更新阶段,决定渲染哪个点,用户触摸的位置,或者自动绘制数组的位置。然后准备顶点数据。你根本不需要计时器。
  • 在绘制阶段,使用 OpenGL ES API 渲染线条。你可以找到一种方法来减少渲染时间,例如,保留渲染缓冲区或其他东西。
  • 在绘制阶段结束时,调用 EAGLContext -presentRenderbuffer:。如果您使用 GLKit 或某种框架,它会自动从框架中调用。你不需要调用它。

关于ios - 在 iOS 上使用 OpenGLES 进行多图协作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27557817/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com