2016-10-09 3 views
0

私はウィンドウ上のどこかをクリックして、クリックごとに正確なカーソル座標でポイントを作成できるOpenGLプログラムを作成しようとしています。それらの点を通って曲線を描画します。私はその部分を実装し、すべての点を一直線に描いていましたが、今はcatmull-romを使ってその線を曲線にする必要があります。私はこの概念が初めてで、関数glm:catmullRom()がどのように機能するかの例を見つけましたが、カーブを描画するためにプログラムの他の部分とどのように動作するかの例は見つかりません。私はそれを使用しようとしましたが、今私は窓から切り離された直線を取得します。私はこの設定に正しくアプローチする方法を知る必要があります。基本的に、これは私がこれまで何をやったかである:私は与えられたコントロールポイントを使ってCatmull-Romスプラインを描くのに助けが必要です

double* cursorX = new double; 
double* cursorY = new double; 
vector<GLfloat>controlPoints = {0.0, 0.0, 0.0}; // Default value (can't pass in an empty vector to VBO) 
glm::vec3 point1; 
glm::vec3 point2; 
glm::vec3 point3; 
glm::vec3 point4; 
vector<glm::vec3>interpolatedPoints; 

void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) 
{ 
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) 
    { 
     glfwGetCursorPos(window, cursorX, cursorY); 
     controlPoints.push_back(*cursorX); // X-coordinate 
     controlPoints.push_back(*cursorY); // Y-coordinate 
     controlPoints.push_back(0);  // Z-coordinate (always fixed at 0) 
    } 
} 

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) 
{ 

    if (key == GLFW_KEY_ENTER && action == GLFW_PRESS) 
    { 
     // Test with 8 points, each point having X,Y, and Z, meaning 24 indices in total! 
     point1 = { controlPoints[1], controlPoints[2], controlPoints[3] }; 
     point2 = { controlPoints[4], controlPoints[5], controlPoints[6] }; 
     point3 = { controlPoints[7], controlPoints[8], controlPoints[9] }; 
     point4 = { controlPoints[10], controlPoints[11], controlPoints[12] }; 
     interpolatedPoints.push_back(glm::catmullRom(point1, point2, point3, point4, 0)); 

     point1 = { controlPoints[13], controlPoints[14], controlPoints[15] }; 
     point2 = { controlPoints[16], controlPoints[17], controlPoints[18] }; 
     point3 = { controlPoints[19], controlPoints[20], controlPoints[21] }; 
     point4 = { controlPoints[22], controlPoints[23], controlPoints[24] }; 
     interpolatedPoints.push_back(glm::catmullRom(point1, point2, point3, point4, 0.5)); 
    } 
} 

// Initialize VAO and VBO 
GLuint VAO, VBO; 
glGenVertexArrays(1, &VAO); 
glGenBuffers(1, &VBO); 

// Bind VAO 
glBindVertexArray(VAO); 

// Bind and implement VBO 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 

glBufferData(GL_ARRAY_BUFFER, controlPoints.size() * sizeof(GLfloat), &controlPoints.front(), GL_STATIC_DRAW); 

// Connecting coordinates to shader 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(0); 

    while (!glfwWindowShouldClose(window)) 
    { 
     // Check if any events have been activated (key pressed, mouse moved etc.) and call corresponding response functions 
     glfwPollEvents(); 

     // Render 
     // Clear the colorbuffer 
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT); 

     glBindVertexArray(VAO); 

     // Update VBO 
     glBufferData(GL_ARRAY_BUFFER, interpolatedPoints.size() * sizeof(glm::vec3), &interpolatedPoints.front(), GL_STATIC_DRAW); 

     glDrawArrays(GL_LINE_STRIP, 0, interpolatedPoints.size() * sizeof(glm::vec3)); 

    // ... 
    } 
    // ... 
} 

答えて

0

std::vectorインデックスが0で始まるが、あなたのコードは、1からインデックス作成を開始するので、それに応じてそれを修正します。また、いくつかの理由のためにあなたはそれが実際には3から始まることを意味しているcontrolPointsにダミーポイントをプッシュ:

point1 = { controlPoints[3], controlPoints[4], controlPoints[5] }; 
    point2 = { controlPoints[6], controlPoints[7], controlPoints[8] }; 
    // ... 

より良い解決策はglm::vec3のベクトルに変更し、そのダミーの要素を削除することです。あなたは次のようにそれを行う:

vector<glm::vec3> controlPoints; 

controlPoints.push_back(glm::vec3(*cursorX, *cursorY, 0)); 

interpolatedPoints.push_back(glm::catmullRom(controlPoints[0], 
    controlPoints[1], controlPoints[2], controlPoints[3], 0)); 

glBufferData(GL_ARRAY_BUFFER, controlPoints.size() * sizeof(glm::vec3), controlPoints.data(), GL_STATIC_DRAW); 

また、ヒープ上cursorXcursorYを割り当てません。これを行う理由は全くありません:

double cursorX, cursorY; 
glfwGetCursorPos(window, &cursorX, &cursorY); 
controlPoints.push_back(glm::vec3(cursorX, cursorY, 0)); 
+0

glBufferData呼び出しを除いて、あなたの提案は意味があります。 controlPointsではなく、interpolatedPointsからデータを取得するべきではありませんか?私は2つのglBufferData呼び出しを持っていることに留意してください。開始時にVBOをバインドするものと、ゲームループで常に更新されるものがあります。また、私のglDrawArraysが正しく呼び出されますか?私はinterpolatedPointsまたはcontrolPointsのサイズをとるかどうかについてはあまりよく分かりませんでした。 編集:interpolatedPointsでglBufferBataを使用すると、ポイントに関係なく直線が得られます。 controlPointsを使用すると、線は点を通って接続されますが、点は曲線ではありません。 – Jonathan

関連する問題