私は OpenGL を初めて使用し、Red Book と Super Bible を使用しています。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) ともう 1 つの頂点のスペース (x と y の + 2) を保持する新しい配列を作成します。次に、glGetBufferSubData を使用して VBO からデータを戻し、この配列に入れました。for ループを使用して、X と Y の数値を配列の末尾に追加します。最後に、このデータを GPU の VBO に送り返し、totalVertices++ を呼び出して、次に頂点を追加するときに配列内にいくつの頂点があるかを確認します。
これは私の質問につながります:私はこれを正しくやっていますか?別の言い方をすれば、CPU 側で BufferData のコピーを保持して、GPU を呼び出して編集のためにデータを送り返す必要がないようにする必要がありますか? その方法では、glGetBufferSubData を呼び出さず、より大きな配列を作成し、新しい頂点を最後に追加してから、glBufferData を呼び出して、更新された頂点データで VBO を再割り当てします。
** プログラミングの経験が非常に浅い私のような人が、私のやろうとしていることをうまく理解できるように、私の思考プロセスを含めようとしました。私がしたことについての私の説明によって、だれも気分を害したくありません。**