2016-09-24 79 views
-3

無法在矢量中插入多個元素;當我用整數向量進行測試時工作得很好。試過如下:只在opengl代碼中的矢量中插入一個值

  • 的push_back功能
  • 插入功能
  • 分配功能

的問題是在createObjects()函數這個錯誤是由於我寫的方式了OpenGL碼...? 非常感謝您

// Include standard headers 
#include <stdio.h> 
#include <stdlib.h> 
#include <vector> 
#include <array> 
#include <sstream> 
// Include GLEW 
#include <GL/glew.h> 
// Include GLFW 
#include <glfw3.h> 
// Include GLM 
#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/quaternion.hpp> 
#include <glm/gtx/quaternion.hpp> 
using namespace glm; 
// Include AntTweakBar 
#include <AntTweakBar.h> 

#include <common/shader.hpp> 
#include <common/controls.hpp> 
#include <common/objloader.hpp> 
#include <common/vboindexer.hpp> 

typedef struct Vertex { 
    float XYZW[4]; 
    float RGBA[4]; 
    void SetCoords(float *coords) { 
     XYZW[0] = coords[0]; 
     XYZW[1] = coords[1]; 
     XYZW[2] = coords[2]; 
     XYZW[3] = coords[3]; 
    } 
    void SetColor(float *color) { 
     RGBA[0] = color[0]; 
     RGBA[1] = color[1]; 
     RGBA[2] = color[2]; 
     RGBA[3] = color[3]; 
    } 
}; 

// ATTN: USE POINT STRUCTS FOR EASIER COMPUTATIONS 
typedef struct point { 
    float x, y, z; 
    point(const float x = 0, const float y = 0, const float z = 0) : x(x), y(y), z(z) {}; 
    point(float *coords) : x(coords[0]), y(coords[1]), z(coords[2]) {}; 
    point operator -(const point& a)const { 
     return point(x - a.x, y - a.y, z - a.z); 
    } 
    point operator +(const point& a)const { 
     return point(x + a.x, y + a.y, z + a.z); 
    } 
    point operator *(const float& a)const { 
     return point(x*a, y*a, z*a); 
    } 
    point operator /(const float& a)const { 
     return point(x/a, y/a, z/a); 
    } 
    float* toArray() { 
     float array[] = { x, y, z, 1.0f }; 
     return array; 
    } 
}; 

// function prototypes 
int initWindow(void); 
void initOpenGL(void); 
void createVAOs(Vertex[], unsigned short[], size_t, size_t, int); 
void createObjects(void); 
void pickVertex(void); 
void moveVertex(void); 
void drawScene(void); 
void cleanup(void); 
static void mouseCallback(GLFWwindow*, int, int, int); 
static void keyCallback(GLFWwindow*, int, int, int, int); 

// GLOBAL VARIABLES 
GLFWwindow* window; 
const GLuint window_width = 1024, window_height = 768; 

glm::mat4 gProjectionMatrix; 
glm::mat4 gViewMatrix; 

GLuint gPickedIndex; 
std::string gMessage; 

GLuint programID; 
GLuint pickingProgramID; 

GLuint kthLevel = 0; 

// ATTN: INCREASE THIS NUMBER AS YOU CREATE NEW OBJECTS 
const GLuint NumObjects = 3; // number of different "objects" to be drawn 
GLuint VertexArrayId[NumObjects] = { 0, 1, 2 }; 
GLuint VertexBufferId[NumObjects] = { 0, 1, 2 }; 
GLuint IndexBufferId[NumObjects] = { 0, 1, 2 }; 
size_t NumVert[NumObjects] = { 0, 1, 2 }; 

GLuint MatrixID; 
GLuint ViewMatrixID; 
GLuint ModelMatrixID; 
GLuint PickingMatrixID; 
GLuint pickingColorArrayID; 
GLuint pickingColorID; 
GLuint LightID; 

// Define objects 
Vertex Vertices[] = 
{ 
    { { 1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 0.0f, 0.0f, 1.0f } }, // 0 
    { { 0.0f, 1.4f, 0.0f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }, // 1 
    { { -1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } }, // 2 
    { { -1.4f, 0.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 1.0f, 1.0f } }, // 3 
    { { -1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // 4 
    { { 0.0f, -1.4f, 0.0f, 1.0f },{ 1.0f, 0.0f, 1.0f, 1.0f } },// 5 
    { { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 0.0f, 1.0f } }, // 6 
    { { 1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 7 
}; 
Vertex OriginalVertices[] = 
{ 
    { { 1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 0.0f, 0.0f, 1.0f } }, // 0 
    { { 0.0f, 1.4f, 0.0f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }, // 1 
    { { -1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } }, // 2 
    { { -1.4f, 0.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 1.0f, 1.0f } }, // 3 
    { { -1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // 4 
    { { 0.0f, -1.4f, 0.0f, 1.0f },{ 1.0f, 0.0f, 1.0f, 1.0f } },// 5 
    { { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 0.0f, 1.0f } }, // 6 
    { { 1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 7 
}; 
Vertex LineVertices[] = 
{ 
    { { 1.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 0 
    { { 0.0f, 1.4f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 1 
    { { -1.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 2 
    { { -1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 3 
    { { -1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 4 
    { { 0.0f, -1.4f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 5 
    { { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 6 
    { { 1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 7 
}; 
Vertex *kVertices; 
Vertex *kPlusOneVertices; 
unsigned short *kIndices; 
unsigned short *kPlusOneIndices; 

//Vertex VTwo[32]; 
//Vertex VThree[64]; 
//unsigned short IOne[]; 
//unsigned short ITwo[]; 
//unsigned short IThree[]; 
std::vector<Vertex>TaskTwoVerticesN; 
std::vector<unsigned short>TaskTwoIndicesN; 
std::vector<Vertex>TaskTwoVerticesNPlusOne; 
std::vector<unsigned short>TaskTwoIndicesNPlusOne; 

unsigned short Indices[] = { 
    0, 1, 2, 3, 4, 5, 6, 7 
}; 
unsigned short LineIndices[] = { 
    0, 1, 2, 3, 4, 5, 6, 7 
}; 

const size_t IndexCount = sizeof(Indices)/sizeof(unsigned short); 
// ATTN: DON'T FORGET TO INCREASE THE ARRAY SIZE IN THE PICKING VERTEX SHADER WHEN YOU ADD MORE PICKING COLORS 
float pickingColor[IndexCount] = { 0/255.0f, 1/255.0f, 2/255.0f, 3/255.0f, 4/255.0f, 5/255.0f, 6/255.0f, 7/255.0f }; 

// ATTN: ADD YOU PER-OBJECT GLOBAL ARRAY DEFINITIONS HERE 

**void createObjects(void) 
{ 
    // ATTN: DERIVE YOUR NEW OBJECTS HERE: 
    // each has one vertices {posCurrent;color} and one indices array (no picking needed here) 
    if (kthLevel > 4 || kthLevel == 0) { 
     kthLevel = 0; 
     TaskTwoVerticesN.clear(); 
     for (int i = 0;i < 8;i++) { 
      TaskTwoVerticesN.push_back(Vertex()); 
      printf("pushed"); 
      TaskTwoVerticesN[i].XYZW[0] = Vertices[i].XYZW[0]; 
      TaskTwoVerticesN[i].XYZW[1] = Vertices[i].XYZW[1]; 
      TaskTwoVerticesN[i].XYZW[2] = Vertices[i].XYZW[2]; 
      TaskTwoVerticesN[i].XYZW[3] = Vertices[i].XYZW[3]; 
      TaskTwoVerticesN[i].RGBA[0] = Vertices[i].RGBA[0]; 
      TaskTwoVerticesN[i].RGBA[1] = Vertices[i].RGBA[1]; 
      TaskTwoVerticesN[i].RGBA[2] = Vertices[i].RGBA[2]; 
      TaskTwoVerticesN[i].RGBA[3] = Vertices[i].RGBA[3]; 
     } 
     TaskTwoVerticesN.insert(TaskTwoVerticesN.begin(), Vertices, Vertices + 8); 
     TaskTwoIndicesN.clear(); 
     TaskTwoIndicesN.insert(TaskTwoIndicesN.begin(), Indices, Indices + (sizeof(Indices)/sizeof(Indices[0]))); 
     printf("\n size of vertices %d\n ", sizeof(TaskTwoVerticesN)/sizeof(TaskTwoVerticesN[0])); 
     //TaskTwoVerticesNPlusOne = TaskTwoVerticesN; 
     //TaskTwoIndicesNPlusOne = TaskTwoIndicesN; 
     kVertices = &TaskTwoVerticesN[0]; 
     kIndices = &TaskTwoIndicesN[0]; 
     //kPlusOneVertices = &TaskTwoVerticesNPlusOne[0]; 
     //kPlusOneIndices = &TaskTwoIndicesNPlusOne[0]; 
    } 
    else { 
     GLint numberOfPoints = sizeof(TaskTwoVerticesN)/sizeof(TaskTwoVerticesN[0]); 
     GLint newPointsLength = (8 * 2^kthLevel); 
     GLint oldPointsLength = newPointsLength/2; 
     printf("\n%d\n", newPointsLength); 
     Vertex newVertexOne, newVertexTwo; 
     newVertexOne.RGBA[0] = 0.0f; 
     newVertexOne.RGBA[1] = 1.0f; 
     newVertexOne.RGBA[2] = 0.0f; 
     newVertexOne.RGBA[3] = 1.0f; 
     newVertexOne.XYZW[2] = 0.0f; 
     newVertexOne.XYZW[3] = 1.0f; 
     newVertexTwo = newVertexOne; 

     for (GLint i = 0; i < oldPointsLength; i++) 
     { 
      GLint posMinusTwo = abs(oldPointsLength + i - 2) % oldPointsLength; 
      GLint posMinusOne = abs(oldPointsLength + i - 1) % oldPointsLength; 
      GLint posCurrent = abs(i) % oldPointsLength; 
      GLint posPlusOne = abs(oldPointsLength + i + 1) % oldPointsLength; 

      GLint newPosOne = abs(2 * i) % newPointsLength; 
      GLint newPosTwo = abs((2 * i) + 1) % newPointsLength; 

      float xMinusTwo = TaskTwoVerticesN[posMinusTwo].XYZW[0]; 
      float xMinusOne = TaskTwoVerticesN[posMinusOne].XYZW[0]; 
      float xCurrent = TaskTwoVerticesN[posCurrent].XYZW[0]; 
      float xPlusOne = TaskTwoVerticesN[posPlusOne].XYZW[0]; 

      float yMinusTwo = TaskTwoVerticesN[posMinusTwo].XYZW[1]; 
      float yMinusOne = TaskTwoVerticesN[posMinusOne].XYZW[1]; 
      float yCurrent = TaskTwoVerticesN[posCurrent].XYZW[1]; 
      float yPlusOne = TaskTwoVerticesN[posPlusOne].XYZW[1]; 

      newVertexOne.XYZW[0] = (xMinusTwo + (10 * xMinusOne) + (5 * xCurrent))/16; 
      newVertexOne.XYZW[1] = (yMinusTwo + (10 * yMinusOne) + (5 * yCurrent))/16; 
      TaskTwoVerticesNPlusOne.insert(TaskTwoVerticesNPlusOne.begin() + newPosOne, newVertexOne); 
      TaskTwoIndicesNPlusOne.insert(TaskTwoIndicesNPlusOne.begin() + newPosOne, newPosOne); 

      printf("\nIn createObjects"); 

      newVertexTwo.XYZW[0] = (xMinusOne + (10 * xCurrent) + (5 * xPlusOne))/16; 
      newVertexTwo.XYZW[1] = (yMinusOne + (10 * yCurrent) + (5 * yPlusOne))/16; 
      TaskTwoVerticesNPlusOne.insert(TaskTwoVerticesNPlusOne.begin() + newPosTwo, newVertexTwo); 
      TaskTwoIndicesNPlusOne.insert(TaskTwoIndicesNPlusOne.begin() + newPosTwo, newPosTwo); 
     } 
     TaskTwoVerticesN.clear(); 
     TaskTwoVerticesN = TaskTwoVerticesNPlusOne; 
     TaskTwoIndicesN = TaskTwoIndicesNPlusOne;// is this possible? 
               //TaskTwoVerticesN.assign(TaskTwoIndicesNPlusOne.begin(), TaskTwoIndicesNPlusOne.end()); 
     kVertices = &TaskTwoVerticesN[0]; 
     kIndices = &TaskTwoIndicesN[0]; 
     kPlusOneVertices = &TaskTwoVerticesNPlusOne[0]; 
     kPlusOneIndices = &TaskTwoIndicesNPlusOne[0]; 
    } 
    printf("\n%d", kthLevel); 
    kthLevel++; 
}** 

void drawScene(void) 
{ 
    // Dark blue background 
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f); 
    // Re-clear the screen for real rendering 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glUseProgram(programID); 
    { 
     glm::mat4 ModelMatrix = glm::mat4(1.0); // TranslationMatrix * RotationMatrix; 
     glm::mat4 MVP = gProjectionMatrix * gViewMatrix * ModelMatrix; 

     // Send our transformation to the currently bound shader, 
     // in the "MVP" uniform 
     glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); 
     glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]); 
     glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &gViewMatrix[0][0]); 
     glm::vec3 lightPos = glm::vec3(4, 4, 4); 
     glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z); 

     glEnable(GL_PROGRAM_POINT_SIZE); 

     glBindVertexArray(VertexArrayId[0]); // draw Vertices 
     glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[0]); 
     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices), Vertices);    // update buffer data 
                         //glDrawElements(GL_LINE_LOOP, NumVert[0], GL_UNSIGNED_SHORT, (void*)0); 
     glDrawElements(GL_POINTS, NumVert[0], GL_UNSIGNED_SHORT, (void*)0); 
     // ATTN: OTHER BINDING AND DRAWING COMMANDS GO HERE, one set per object: 
     //glBindVertexArray(VertexArrayId[<x>]); etc etc 
     glBindVertexArray(0); 
     glBindVertexArray(VertexArrayId[1]); // draw Vertices 
     glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[1]); 
     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(LineVertices), LineVertices);    // update buffer data 
     glDrawElements(GL_LINE_STRIP, NumVert[1], GL_UNSIGNED_SHORT, (void*)0); 
     glBindVertexArray(1); 

     glBindVertexArray(VertexArrayId[2]); // draw Vertices 
     glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[2]); 
     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(kPlusOneIndices), kPlusOneVertices);    // update buffer data 
     glDrawElements(GL_LINE_STRIP, NumVert[2], GL_UNSIGNED_SHORT, (void*)0); 
     glBindVertexArray(2); 
    } 
    glUseProgram(0); 
    // Draw GUI 
    TwDraw(); 

    // Swap buffers 
    glfwSwapBuffers(window); 
    glfwPollEvents(); 
} 

void pickVertex(void) 
{ 
    // Clear the screen in white 
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glUseProgram(pickingProgramID); 
    { 
     glm::mat4 ModelMatrix = glm::mat4(1.0); // TranslationMatrix * RotationMatrix; 
     glm::mat4 MVP = gProjectionMatrix * gViewMatrix * ModelMatrix; 

     // Send our transformation to the currently bound shader, in the "MVP" uniform 
     glUniformMatrix4fv(PickingMatrixID, 1, GL_FALSE, &MVP[0][0]); 
     glUniform1fv(pickingColorArrayID, NumVert[0], pickingColor); // here we pass in the picking marker array 

                     // Draw the ponts 
     glEnable(GL_PROGRAM_POINT_SIZE); 
     glBindVertexArray(VertexArrayId[0]); 
     glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[0]); 
     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices), Vertices); // update buffer data 
     glDrawElements(GL_POINTS, NumVert[0], GL_UNSIGNED_SHORT, (void*)0); 
     glBindVertexArray(0); 
    } 
    glUseProgram(0); 
    // Wait until all the pending drawing commands are really done. 
    // Ultra-mega-over slow ! 
    // There are usually a long time between glDrawElements() and 
    // all the fragments completely rasterized. 
    glFlush(); 
    glFinish(); 

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    // Read the pixel at the center of the screen. 
    // You can also use glfwGetMousePos(). 
    // Ultra-mega-over slow too, even for 1 pixel, 
    // because the framebuffer is on the GPU. 
    double xpos, ypos; 
    glfwGetCursorPos(window, &xpos, &ypos); 
    unsigned char data[4]; 
    glReadPixels(xpos, window_height - ypos, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top 

                        // Convert the color back to an integer ID 
    gPickedIndex = int(data[0]); 

    // Uncomment these lines to see the picking shader in effect 
    //glfwSwapBuffers(window); 
    //continue; // skips the normal rendering 
} 

// fill this function in! 
void moveVertex(void) 
{ 
    double xpos, ypos; 
    glfwGetCursorPos(window, &xpos, &ypos); 
    unsigned char data[4]; 
    glReadPixels(xpos, 768 - ypos, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top 
    glm::mat4 ModelMatrix = glm::mat4(1.0); 
    GLint viewport[4]; 
    glGetIntegerv(GL_VIEWPORT, viewport); 
    glm::vec4 vp = glm::vec4(viewport[0], viewport[1], viewport[2], viewport[3]); 
    // retrieve your cursor position 
    // get your world coordinates 
    // move points 

    if (gPickedIndex == 255) { // Full white, must be the background ! 
     gMessage = "background"; 
    } 
    else { 
     std::ostringstream oss; 
     oss << "point " << gPickedIndex; 
     gMessage = oss.str(); 
    } 
    if ((glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)) == GLFW_PRESS) { 
     printf("\n pressed"); 
     Vertices[gPickedIndex].RGBA[0] = 0.5f; 
     Vertices[gPickedIndex].RGBA[1] = 0.5f; 
     Vertices[gPickedIndex].RGBA[2] = 0.5f; 
     Vertices[gPickedIndex].RGBA[3] = 1.0f; 
     GLint viewport[4]; 
     glGetIntegerv(GL_VIEWPORT, viewport); 

     glm::vec3 vertex = glm::unProject(glm::vec3(xpos, 768 - ypos, 0.0), ModelMatrix, gProjectionMatrix, vp); 
     Vertices[gPickedIndex].XYZW[0] = -vertex[0]; 
     Vertices[gPickedIndex].XYZW[1] = vertex[1]; 
     LineVertices[gPickedIndex].XYZW[0] = -vertex[0]; 
     LineVertices[gPickedIndex].XYZW[1] = vertex[1]; 
    } 
    else { 
     printf("released"); 
     Vertices[gPickedIndex].RGBA[0] = OriginalVertices[gPickedIndex].RGBA[0]; 
     Vertices[gPickedIndex].RGBA[1] = OriginalVertices[gPickedIndex].RGBA[1]; 
     Vertices[gPickedIndex].RGBA[2] = OriginalVertices[gPickedIndex].RGBA[2]; 
     Vertices[gPickedIndex].RGBA[3] = OriginalVertices[gPickedIndex].RGBA[3]; 
    } 
} 

int initWindow(void) 
{ 
    // Initialise GLFW 
    if (!glfwInit()) { 
     fprintf(stderr, "Failed to initialize GLFW\n"); 
     return -1; 
    } 

    glfwWindowHint(GLFW_SAMPLES, 4); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 

    // Open a window and create its OpenGL context 
    window = glfwCreateWindow(window_width, window_height, "Lastname,FirstName(ufid)", NULL, NULL); 
    if (window == NULL) { 
     fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); 
     glfwTerminate(); 
     return -1; 
    } 
    glfwMakeContextCurrent(window); 

    // Initialize GLEW 
    glewExperimental = true; // Needed for core profile 
    if (glewInit() != GLEW_OK) { 
     fprintf(stderr, "Failed to initialize GLEW\n"); 
     return -1; 
    } 

    // Initialize the GUI 
    TwInit(TW_OPENGL_CORE, NULL); 
    TwWindowSize(window_width, window_height); 
    TwBar * GUI = TwNewBar("Picking"); 
    TwSetParam(GUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1"); 
    TwAddVarRW(GUI, "Last picked object", TW_TYPE_STDSTRING, &gMessage, NULL); 

    // Set up inputs 
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_FALSE); 
    glfwSetCursorPos(window, window_width/2, window_height/2); 
    glfwSetMouseButtonCallback(window, mouseCallback); 
    glfwSetKeyCallback(window, keyCallback); 
    return 0; 
} 

void initOpenGL(void) 
{ 
    // Dark blue background 
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f); 

    // Enable depth test 
    glEnable(GL_DEPTH_TEST); 
    // Accept fragment if it closer to the camera than the former one 
    glDepthFunc(GL_LESS); 
    // Cull triangles which normal is not towards the camera 
    glEnable(GL_CULL_FACE); 

    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units 
    //glm::mat4 ProjectionMatrix = glm::perspective(45.0f, 4.0f/3.0f, 0.1f, 100.0f); 
    // Or, for an ortho camera : 
    gProjectionMatrix = glm::ortho(-4.0f, 4.0f, -3.0f, 3.0f, 0.0f, 100.0f); // In world coordinates 

                      // Camera matrix 
    gViewMatrix = glm::lookAt(
     glm::vec3(0, 0, -5), // Camera is at (4,3,3), in World Space 
     glm::vec3(0, 0, 0), // and looks at the origin 
     glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down) 
    ); 

    // Create and compile our GLSL program from the shaders 
    programID = LoadShaders("StandardShading.vertexshader", "StandardShading.fragmentshader"); 
    pickingProgramID = LoadShaders("Picking.vertexshader", "Picking.fragmentshader"); 

    // Get a handle for our "MVP" uniform 
    MatrixID = glGetUniformLocation(programID, "MVP"); 
    ViewMatrixID = glGetUniformLocation(programID, "V"); 
    ModelMatrixID = glGetUniformLocation(programID, "M"); 
    PickingMatrixID = glGetUniformLocation(pickingProgramID, "MVP"); 
    // Get a handle for our "pickingColorID" uniform 
    pickingColorArrayID = glGetUniformLocation(pickingProgramID, "PickingColorArray"); 
    pickingColorID = glGetUniformLocation(pickingProgramID, "PickingColor"); 
    // Get a handle for our "LightPosition" uniform 
    LightID = glGetUniformLocation(programID, "LightPosition_worldspace"); 

    createVAOs(Vertices, Indices, sizeof(Vertices), sizeof(Indices), 0); 
    createVAOs(LineVertices, LineIndices, sizeof(LineVertices), sizeof(LineIndices), 1); 
    createVAOs(kPlusOneVertices, kPlusOneIndices, sizeof(kPlusOneVertices), sizeof(kPlusOneIndices), 2); 
    printf("\nVAO"); 
    createObjects(); 

    // ATTN: create VAOs for each of the newly created objects here: 
    // createVAOs(<fill this appropriately>); 

} 

void createVAOs(Vertex Vertices[], unsigned short Indices[], size_t BufferSize, size_t IdxBufferSize, int ObjectId) { 

    NumVert[ObjectId] = IdxBufferSize/(sizeof GLubyte); 

    GLenum ErrorCheckValue = glGetError(); 
    size_t VertexSize = sizeof(Vertices[0]); 
    size_t RgbOffset = sizeof(Vertices[0].XYZW); 

    // Create Vertex Array Object 
    glGenVertexArrays(1, &VertexArrayId[ObjectId]); 
    glBindVertexArray(VertexArrayId[ObjectId]); 

    // Create Buffer for vertex data 
    glGenBuffers(1, &VertexBufferId[ObjectId]); 
    glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[ObjectId]); 
    glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW); 

    // Create Buffer for indices 
    glGenBuffers(1, &IndexBufferId[ObjectId]); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[ObjectId]); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, IdxBufferSize, Indices, GL_STATIC_DRAW); 

    // Assign vertex attributes 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, VertexSize, 0); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid*)RgbOffset); 

    glEnableVertexAttribArray(0); // position 
    glEnableVertexAttribArray(1); // color 

            // Disable our Vertex Buffer Object 
    glBindVertexArray(0); 

    ErrorCheckValue = glGetError(); 
    if (ErrorCheckValue != GL_NO_ERROR) 
    { 
     fprintf(
      stderr, 
      "ERROR: Could not create a VBO: %s \n", 
      gluErrorString(ErrorCheckValue) 
     ); 
    } 
} 

void cleanup(void) 
{ 
    // Cleanup VBO and shader 
    for (int i = 0; i < NumObjects; i++) { 
     glDeleteBuffers(1, &VertexBufferId[i]); 
     glDeleteBuffers(1, &IndexBufferId[i]); 
     glDeleteVertexArrays(1, &VertexArrayId[i]); 
    } 
    glDeleteProgram(programID); 
    glDeleteProgram(pickingProgramID); 

    // Close OpenGL window and terminate GLFW 
    glfwTerminate(); 
} 

static void mouseCallback(GLFWwindow* window, int button, int action, int mods) 
{ 
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { 
     pickVertex(); 
    } 
} 

static void keyCallback(GLFWwindow* window, int button, int scancode, int action, int mods) { 
    if (button == GLFW_KEY_1 && action == GLFW_PRESS) { 
     createObjects(); 
     //printf("\n1 pressed"); 
    } 
} 

int main(void) 
{ 
    // initialize window 
    int errorCode = initWindow(); 
    if (errorCode != 0) 
     return errorCode; 
    // initialize OpenGL pipeline 
    initOpenGL(); 

    // For speed computation 
    double lastTime = glfwGetTime(); 
    int nbFrames = 0; 
    do { 
     // Measure speed 
     double currentTime = glfwGetTime(); 
     nbFrames++; 
     if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1sec ago 
              // printf and reset 
      printf("%f ms/frame\n", 1000.0/double(nbFrames)); 
      nbFrames = 0; 
      lastTime += 1.0; 
     } 
     glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); 
     // DRAGGING: move current (picked) vertex with cursor 
     if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)) 
      moveVertex(); 

     // DRAWING SCENE 
     glfwSetKeyCallback(window, keyCallback); 
     //createObjects(); // re-evaluate curves in case vertices have been moved 
     drawScene(); 


    } // Check if the ESC key was pressed or the window was closed 
    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && 
     glfwWindowShouldClose(window) == 0); 

    cleanup(); 

    return 0; 
} 
+3

請提供[最小可驗證示例](http://stackoverflow.com/幫助/ mcve) – PRP

+0

你有沒有試過用調試器來看看你的矢量會發生什麼? – Chris

+0

'8 * 2^kthLevel'這可能是一個錯誤 - '^'是一個按位異或運算符,並不像您想象的那樣是兩個冪。 – ybungalobill

回答

0

你嘗試使用數組這樣

bool MAP::InsertVertex(long obj, GLdouble x, GLdouble y, GLdouble z,GLfloat r 
           ,GLfloat g, GLfloat b, GLfloat a,GLfloat nx, GLfloat ny 
           ,GLfloat nz, GLfloat fogdepth) 

{

 MAP_VERTEX new_vertex; 
     long rgb = GenerateVertexColor(obj); 
     if(obj>header.max_objects||obj<0) 
           return (false); 
    new_vertex.xyz[0]   =x; 
    new_vertex.xyz[1]   =y; 
    new_vertex.xyz[2]   =z; 
    new_vertex.rgba[0]   =r; 
    new_vertex.rgba[1]   =g; 
    new_vertex.rgba[2]   =b; 
    new_vertex.rgba[3]   =a; 
    new_vertex.normal[0]   =nx; 
    new_vertex.normal[1]   =ny; 
    new_vertex.normal[2]   =nz; 
    new_vertex.fogdepth   =fogdepth; 
    new_vertex.select_rgb[0]  = GetRValue(rgb); 
    new_vertex.select_rgb[1]  = GetGValue(rgb); 
    new_vertex.select_rgb[2]  = GetBValue(rgb); 

    if(object[obj].max_vertices==0) object[obj].vertex = new MAP_VERTEX 
     [object[obj].max_vertices+1]; 
     else{ 
     //Backing up the vertices that are already there 
       MAP_VERTEX *temp = new MAP_VERTEX[object[obj].max_vertices+1]; 
     for(long i=0;i<object[obj].max_vertices;i++) 
      temp[i] = object[obj].vertex[i]; 
     //Deleting the old vertices that were allocated earlier 
     delete [] object[obj].vertex; 
     //Now allocating new memory for vertex with an extra buffer 
     object[obj].vertex = new MAP_VERTEX[object[obj].max_vertices+2]; 
      for(long i=0;i<object[obj].max_vertices;i++) 
      object[obj].vertex[i] =temp[i]; 
      delete [] temp; 
      temp = NULL; 

     } 
     //Insert a new Vertex 
     object[obj].vertex[object[obj].max_vertices] = new_vertex; 
       object[obj].max_vertices++; 

      return (true); 

}