我是 OpenGL 的新手,我一直在使用红皮书和超级圣经。在 SB 中,我已经了解了有关使用从文件加载的对象的部分。到目前为止,我认为我理解正在发生的事情以及如何做没有问题,但这让我开始考虑在我自己的应用程序中制作我自己的网格 - 本质上是一个建模应用程序。我已经通过我的参考资料和互联网进行了大量搜索,但我还没有找到一个很好的教程来将这些功能实现到自己的应用程序中。我找到了一个仅提供此功能的API,但我正在尝试了解实现;不仅仅是界面。
到目前为止,我已经创建了一个“应用程序”(我轻描淡写地使用了这个术语),它为您提供了一个可以单击并添加顶点的视图。顶点不连接,只是显示在您单击的位置。我担心的是,我在试验时偶然发现的这种方法不是我应该实施这个过程的方式。
我正在使用 Mac 并在 Xcode 中使用 Objective-C 和 C。
MyOpenGLView.m #import "MyOpenGLView.h"
@interface MyOpenGLView () {
NSTimer *_renderTimer
Gluint VAO, VBO;
GLuint totalVertices;
GLsizei bufferSize;
}
@end
@implementation MyOpenGLView
/* Set up OpenGL view with a context and pixelFormat with doubleBuffering */
/* NSTimer implementation */
- (void)drawS3DView {
currentTime = CACurrentMediaTime();
NSOpenGLContext *currentContext = self.openGLContext;
[currentContext makeCurrentContext];
CGLLockContext([currentContext CGLContextObj]);
const GLfloat color[] = {
sinf(currentTime * 0.2),
sinf(currentTime * 0.3),
cosf(currentTime * 0.4),
1.0
};
glClearBufferfv(GL_COLOR, 0, color);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glPointSize(10);
glDrawArrays(GL_POINTS, 0, totalVertices);
CGLFlushDrawable([currentContext CGLContextObj]);
CGLUnlockContext([currentContext CGLContextObj]);
}
#pragma mark - User Interaction
- (void)mouseUp:(NSEvent *)theEvent {
NSPoint mouseLocation = [theEvent locationInWindow];
NSPoint mouseLocationInView = [self convertPoint:mouseLocation fromView:self];
GLfloat x = -1 + mouseLocationInView.x * 2/(GLfloat)self.bounds.size.width;
GLfloat y = -1 + mouseLocationInView.y * 2/(GLfloat)self.bounds.size.height;
NSOpenGLContext *currentContext = self.openGLContext;
[currentContext makeCurrentContext];
CGLLockContext([currentContext CGLContextObj]);
[_renderer addVertexWithLocationX:x locationY:y];
CGLUnlockContext([currentContext CGLContextObj]);
}
- (void)addVertexWithLocationX:(GLfloat)x locationY:(GLfloat)y {
glBindBuffer(GL_ARRAY_BUFFER, VBO);
GLfloat vertices[(totalVertices * 2) + 2];
glGetBufferSubData(GL_ARRAY_BUFFER, 0, (totalVertices * 2), vertices);
for (int i = 0; i < ((totalVertices * 2) + 2); i++) {
if (i == (totalVertices * 2)) {
vertices[i] = x;
} else if (i == (totalVertices * 2) + 1) {
vertices[i] = y;
}
}
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
totalVertices ++;
}
@end
该应用程序应该获取鼠标单击的位置并提供它是一个顶点位置。对于每个添加的顶点,我首先绑定 VBO 以确保它处于活动状态。接下来,我创建一个新数组来保存我当前的顶点位置(totalVertices)加上一个顶点的空间(x 和 y 为 + 2)。然后我使用 glGetBufferSubData 从 VBO 取回数据并将其放入这个数组中。使用 for 循环,我将 X 和 Y 数字添加到数组的末尾。最后,我将这些数据发送回 GPU 到 VBO 并调用 totalVertices++,这样我就知道下次我想添加一个顶点时数组中有多少个顶点。
这让我想到了我的问题:我这样做对吗?换句话说,我是否应该在 CPU 端保留 BufferData 的副本,这样我就不必调用 GPU 并将数据发送回进行编辑?这样,我不会调用 glGetBufferSubData,我会创建一个更大的数组,将新顶点添加到末尾,然后调用 glBufferData 以使用更新的顶点数据重新分配 VBO。
** 我试图包含我的思考过程,以便像我这样在编程方面非常缺乏经验的人可以希望能够理解我想要做什么。我不希望任何人因为我对我所做的解释而感到生气。**