glDrawArrays绘图不正确

8

我制作了一个绘画程序,一切都按照我预期的方式工作。但在绘制时,有时会发生一些奇怪的事情。

我运行应用程序,在图像上按下左键。它应该从代码中绘制一个点:

glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, brushTextura);
glPointSize(100);
glVertexPointer(2, GL_FLOAT, 0,GLVertices);
glDrawArrays(GL_POINTS, 0, count);
glDisableClientState(GL_VERTEX_ARRAY);

在我按下鼠标的位置,mouseDown(鼠标按下)记录了鼠标按下的位置,并将其转换为NSValue,发送到数组中,然后在绘制之前,我会提取NSValue以获取CGPoint并将其发送到GLfloat以便能够通过glDrawArrays绘制。但是,无论我在图像上单击鼠标的位置在哪里,它都会在坐标(0,0)处绘制点。之后每件事情都正常工作。请参见以下图片:

mouse click

这是第一个问题。第二个问题是当我使用它进行绘画(拖动鼠标)时,有时会出现未绘制的点。图片如下:

mouse drag

当我继续拖动它时,它就消失了。经过一段拖动后,它又出现了,然后再次消失。如下图所示:

enter image description here

有什么想法为什么会发生这种情况吗?我将在下面发布代码:
鼠标按下:
- (void) mouseDown:(NSEvent *)event
{
    location = [self convertPoint: [event locationInWindow] fromView:self];
    NSValue *locationValue = [NSValue valueWithPoint:location];
    [vertices addObject:locationValue];

        [self drawing];
}

鼠标拖动:

- (void) mouseDragged:(NSEvent *)event
{
    location = [self convertPoint: [event locationInWindow] fromView:self];
    NSValue *locationValue = [NSValue valueWithPoint:location];
    [vertices addObject:locationValue];

        [self drawing];
}

绘图:

- (void) drawing {
int count = [vertices count] * 2;
NSLog(@"count: %d", count);
int currIndex = 0;
GLfloat *GLVertices = (GLfloat *)malloc(count * sizeof(GLfloat));
for (NSValue *locationValue in vertices) {
    CGPoint loc = locationValue.pointValue;
    GLVertices[currIndex++] = loc.x;
    GLVertices[currIndex++] = loc.y;    
 }
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, brushTextura);
glPointSize(100);
glVertexPointer(2, GL_FLOAT, 0, GLVertices);
glDrawArrays(GL_POINTS, 0, count);
glDisableClientState(GL_VERTEX_ARRAY);
}
3个回答

7
你正在设置你的count变量(在glDrawArrays中使用)为[vertices count] * 2,这似乎很奇怪。 glDrawArrays的最后一个参数是要绘制的顶点数,而在你的代码中,你似乎将其设置为了双倍(也许你认为它是浮点数的数量?),这意味着你只能在前面的count个顶点之后绘制垃圾数据。

如果我将其更改为[vertices count],那么在开始绘制时它会出错。有一些点被正确绘制,之后就会显示错误:Thread 1: EXC_BAD_ACCESS (code=13, adress=0x0)glDrawArrays(GL_POINTS, 0, count); 或者 NSValue *locationValue = [NSValue valueWithPoint:vieta]; 的错误是 Thread 1: signal SIGABRT。有时一个错误,其他时候另一个错误。我不知道为什么,但错误并不总是相同的。 - hockeyman
有时在中断时,控制台会显示以下消息:OGL(896,0x7fff79c93960)malloc:***错误对象0x100151a98的校验和不正确:释放后可能已修改对象。***设置一个断点在malloc_error_break以进行调试 - hockeyman
@JuliusPetraška 可能的原因是您在 GLVerticesmalloc 中也使用了它,因此顶点数组太小,您再次读取了过多的顶点(这一次导致崩溃)。当然,GLVertices 数组的大小必须为 [vertices count] * 2,因为它包含每个顶点的 2 个浮点数。但是,您只需要在 glDrawArrays 中绘制 [vertices count] 个完整的顶点即可。 - Christian Rau
非常感谢您。P.S. 我现在无法向您授予赏金,因为它显示我还需要等待23个小时。 - hockeyman

1

顶点没有在您单击的确切位置呈现,这表明问题在于您没有正确确定视图中的命中点。

您的代码如下:

location = [self convertPoint: [event locationInWindow] fromView: self];

该代码告诉视图将点从其坐标系(self)转换为相同视图的坐标系(self),即使该点实际上是相对于窗口的。

要将点从窗口坐标系转换为视图坐标系,请将该行更改为以下内容:

location = [self convertPoint: [event locationInWindow] fromView: nil];

0

glDrawArrays的参数定义为(GLenum mode,GLint first,GLsizei count)。

第二个参数定义了绘制时使用的顶点属性的第一个索引。您将1作为第一个索引传递,这使得您的顶点坐标不匹配。我假设您想在那里使用0。

http://www.opengl.org/sdk/docs/man/xhtml/glDrawArrays.xml


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