Ios 渲染顶点缓冲区阵列OenGL ES2

Ios 渲染顶点缓冲区阵列OenGL ES2,ios,iphone,opengl-es,opengl-es-2.0,vertex-buffer,Ios,Iphone,Opengl Es,Opengl Es 2.0,Vertex Buffer,我正在尝试渲染VBO数组,但结果不正确。当我第一次使用GLPaint(OpenGLES v2)设置绘制它们时,我正在将它们保存到一个数组中。这是我的样本项目,如果你想帮助我 在renderLineFromPoint(从GLPaint)中绘制时存储VBO -(void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end { 静态GLfloat*vertexBuffer=NULL; 静态整数vertexMax=64; NSU整数vertex

我正在尝试渲染VBO数组,但结果不正确。当我第一次使用GLPaint(OpenGLES v2)设置绘制它们时,我正在将它们保存到一个数组中。这是我的样本项目,如果你想帮助我

在renderLineFromPoint(从GLPaint)中绘制时存储VBO -(void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end { 静态GLfloat*vertexBuffer=NULL; 静态整数vertexMax=64; NSU整数vertexCount=0, 计数 我 [EagleContext setCurrentContext:context]; glBindFramebuffer(GL_FRAMEBUFFER,viewFramebuffer); //将位置从点转换为像素 CGFloat scale=self.contentScaleFactor; start.x*=刻度; start.y*=刻度; end.x*=刻度; 结束。y*=刻度; //分配顶点数组缓冲区 if(vertexBuffer==NULL) vertexBuffer=malloc(vertexMax*2*sizeof(GLfloat)); //向缓冲区添加点,以便每X像素有一个绘图点 计数=最大值(ceilf(sqrtf((end.x-start.x)*(end.x-start.x)+(end.y-start.y)*(end.y-start.y))/kBrushPixelStep),1); 对于(i=0;i 这基本上是一个撤销。。。当按下“撤消”时,它应该只删除3,因为这是最后一个笔划,但它会删除所有笔划并绘制第二幅图像中显示的点


我在下面几行找到了这个问题的答案

//分配顶点数组缓冲区
如果(vertexBuffer==NULL)
vertexBuffer=malloc(vertexMax*2*sizeof(GLfloat))


问题是存储的顶点数组都是相同的!当vertexBuffer为空时,它在init上只分配了一次内存。其他一些代码有一些更改,如果您需要更新,请告诉我。

应使用智能设计模式处理撤消,而不是使用任何特定于API的功能。如果我是你,我会研究memento设计模式,这将允许你将文档存储为一系列命令,其中每个命令存储以前的状态。当需要呈现文档时,只需重放所有命令即可。当需要撤消命令时,您可以使用先前状态的副本(速度快,但内存不足),也可以按顺序重放命令。这是对您先前问题的回答;关于这个问题,我想知道为什么一个名为
SavedVertexBufferes
的函数每次调用时都会向VBO发送新数据?如果是这样的话,那真的没有任何意义。我会考虑使用顶点数组对象,因为这是iOS特定的——不是所有的GL ES 2实现都支持它们,但是IOS确实。你指的是ReDraveSaveDeXBuffes函数吗?如果是这样,那就是我试图重新绘制已绘制并存储在数组中的顶点缓冲区的地方。然后,我在该数组中创建一个标志,让我知道最后一条线是何时绘制的,然后我可以删除顶点缓冲区直到该点,并重新绘制剩余的缓冲区,这基本上是一个“撤消”。但我对VBOs的工作原理和OpenGLES还不是很在行。我需要一个很好的图形图来解释所有部分之间的关系。对,但实际上你并没有重新绘制那些VBO。实际上,您正在重新分配它们并向它们提供新数据,因为您正在对它们调用
glBufferData(…)
。如果您真的想重用它们,那么就取消对
glBufferData(…)
的调用。如果使用顶点数组对象,实际上可以删除99%的API调用,只需绑定VAO并调用
gldrawArray(…)
。。。顶点缓冲区存储图形信息,并与glBufferData()一起传入。然后,调用glDrawArrays()将呈现该数据。我现在使用的方法似乎是正确的,但当它重新绘制时,似乎丢失了一些数据,或者我只是绘制了一些缓冲区。正如您在第二张图像中看到的,这些点位于ri中
////// Store VBOs when drawing this is done in renderLineFromPoint (from GLPaint)
- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
{

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;
}

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);

// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);

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

// Store VBO for undo
VBOHolder *vboHolder = [[VBOHolder alloc]init];
vboHolder.vertexCount = vertexCount;
vboHolder.vbo = vertexBuffer;
[vboHolderArray addObject:vboHolder];

}

////// Here is the problem: I clear the screen and then try to re-render the VBOs
-(void)renderSavedVertexBufferes
{

  for (VBOHolderModel *vboh in vboHolderArray)
  {
    if (vboh.vertexCount == 0)
    {
        continue;
    }

    NSUInteger vertexCount = vboh.vertexCount;

    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vboh.vbo, GL_DYNAMIC_DRAW);

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

    // Render the vertex array
    glVertexPointer(2, GL_FLOAT, 0, vboh.vbo);
    glDrawArrays(GL_POINTS, 0, vertexCount);

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

  }
}


////// VBOHolderModel looks like this, it wraps the vbo so it can be put in NSMutableArray
@interface VBOHolderModel : NSObject
{
   GLfloat *vbo;
   NSUInteger vertexCount;

}