-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;
}
請提供[最小可驗證示例](http://stackoverflow.com/幫助/ mcve) – PRP
你有沒有試過用調試器來看看你的矢量會發生什麼? – Chris
'8 * 2^kthLevel'這可能是一個錯誤 - '^'是一個按位異或運算符,並不像您想象的那樣是兩個冪。 – ybungalobill