OpenGL +无法使用buffersubdata更新缓冲区数据
Posted
技术标签:
【中文标题】OpenGL +无法使用buffersubdata更新缓冲区数据【英文标题】:OpenGL + Can't update buffer data with buffersubdata 【发布时间】:2016-01-29 04:22:24 【问题描述】:我正在尝试使用 glNamedBufferSubData 或 glBufferSubData 来覆盖缓冲区中的顶点值,但它似乎没有做任何事情。
我有我想从 renderGeometry 函数调用的函数 updateGeometry 修改我的 SpringMass 对象的变量之一。我希望数据被完全覆盖,因此使用 - 作为偏移量。
const int NUM_VERTICES_PER_LINE = 2;
const int NUMFLOATSPERVERTICES = 6;
const int VERTEX_BYTE_SIZE = NUMFLOATSPERVERTICES * sizeof(float);
GLint numSpringIndices, numMassIndices;
#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a);
Spring::Spring() : anchorPosition 0.0f, 1.0f, 0.0f , mPosition 0.0f, 0.0f, 0.0f , displacement 0.0f, -0.3f, 0.0f
USING_ATLAS_GL_NS; //Short for atlas GL namespace
USING_ATLAS_MATH_NS;
glGenVertexArrays(1, &mVertexArrayObject);
glBindVertexArray(mVertexArrayObject);
//mSpringMass = ObjectGenerator::makeSpring(anchorPosition, stretch, d);
//mMass = ObjectGenerator::makeMass(calculateConnectionPoint(anchorPosition), massWidth, massHeight);
mSpringMass = ObjectGenerator::makeSpringMass(anchorPosition, stretch, d, massWidth, massHeight);
numSpringIndices = mSpringMass.numIndices;
glGenBuffers(1, &mVertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, mSpringMass.vertexBufferSize(), mSpringMass.vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VERTEX_BYTE_SIZE, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, VERTEX_BYTE_SIZE, (char*)(sizeof(float) * 3));
glGenBuffers(1, &springIndexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, springIndexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mSpringMass.indexBufferSize(), mSpringMass.indices, GL_STATIC_DRAW);
// Get the path where our shaders are stored.
std::string shaderDir = generated::ShaderPaths::getShaderDirectory();
// Now set up the information for our shaders.
std::vector<ShaderInfo> shaders
ShaderInfo GL_VERTEX_SHADER, shaderDir + "Spring.vs.glsl" ,
ShaderInfo GL_FRAGMENT_SHADER, shaderDir + "Spring.fs.glsl"
;
// Create a new shader and add it to our list.
mShaders.push_back(ShaderPointer(new Shader));
mShaders[0]->compileShaders(shaders);
mShaders[0]->linkShaders();
mShaders[0]->disableShaders();
Spring::~Spring()
glDeleteVertexArrays(1, &mVertexArrayObject);
glDeleteBuffers(1, &mSpringBuffer);
void Spring::renderGeometry(atlas::math::Matrix4 projection, atlas::math::Matrix4 view)
// To avoid warnings from unused variables, you can use the
//UNUSED macro.
UNUSED(projection);
UNUSED(view);
mShaders[0]->enableShaders();
updateGeometry();
GLint dispLocation = mShaders[0]->getUniformVariable("displacement");
GLint anchorLocation = mShaders[0]->getUniformVariable("anchorPosition");
glUniform3fv(anchorLocation, 1, &anchorPosition[0]);
glUniform3fv(dispLocation, 1, &displacement[0]);
glBindVertexArray(mVertexArrayObject);
glDrawElements(GL_LINES, numSpringIndices, GL_UNSIGNED_SHORT, 0);
mShaders[0]->disableShaders();
void Spring::updateGeometry()
//glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject);
GLfloat newD = d * 0;
mSpringMass = ObjectGenerator::makeSpringMass(anchorPosition, stretch, newD, massWidth, massHeight);
//glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(mSpringMass.vertices), mSpringMass.vertices);
glNamedBufferSubData(mVertexBufferObject, 0, sizeof(mSpringMass.vertices), mSpringMass.vertices);
编辑
为了澄清,这里是 ObjectGenerator 代码。
#include "ObjectGenerator.h"
#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a);
ShapeData ObjectGenerator::makeSpringMass(glm::vec3 anchorPosition, GLfloat stretch, GLfloat d, GLfloat width, GLfloat height)
ShapeData ret;
glm::vec3 springColor 1.0f, 0.0f, 0.0f , massColor 0.0f, 1.0f, 0.0f , connectionPoint anchorPosition.x, anchorPosition.y - (18 * d), 0.0f ;
static const Vertex vertices[] =
glm::vec3(anchorPosition.x, anchorPosition.y, 0.0f), // 0
springColor,
glm::vec3(anchorPosition.x, anchorPosition.y - d,0.0f), // 1
springColor,
glm::vec3(anchorPosition.x + stretch, anchorPosition.y - (2 * d), 0.0f), // 2
springColor,
glm::vec3(anchorPosition.x - stretch, anchorPosition.y - (4 * d), 0.0f), // 3
springColor,
glm::vec3(anchorPosition.x + stretch, anchorPosition.y - (6 * d), 0.0f), // 4
springColor,
glm::vec3(anchorPosition.x - stretch, anchorPosition.y - (8 * d), 0.0f), // 5
springColor,
glm::vec3(anchorPosition.x + stretch, anchorPosition.y - (10 * d), 0.0f), // 6
springColor,
glm::vec3(anchorPosition.x - stretch, anchorPosition.y - (12 * d), 0.0f), // 7
springColor,
glm::vec3(anchorPosition.x + stretch, anchorPosition.y - (14 * d), 0.0f), // 8
springColor,
glm::vec3(anchorPosition.x - stretch, anchorPosition.y - (16 * d), 0.0f), // 9
springColor,
glm::vec3(anchorPosition.x, anchorPosition.y - (17 * d), 0.0f), // 10
springColor,
connectionPoint, // 11
springColor,
//=================Mass==============//
glm::vec3(connectionPoint.x - width, connectionPoint.y, 0.0f), //top Left 12
massColor,
glm::vec3(connectionPoint.x + width, connectionPoint.y, 0.0f), //top Right 13
massColor,
glm::vec3(connectionPoint.x + width, connectionPoint.y - height, 0.0f), // bottom right 14
massColor,
glm::vec3(connectionPoint.x - width, connectionPoint.y - height, 0.0f), // bottom left 15
massColor,
;
ret.numVertices = NUM_ARRAY_ELEMENTS(vertices);
ret.vertices = new Vertex[ret.numVertices];
memcpy(ret.vertices, vertices, sizeof(vertices)); //memcpy(dest, source, size);
GLushort indices[] = 0,1 ,1,2, 2,3, 3,4, 4,5, 5,6, 6,7, 7,8, 8,9, 9,10, 10,11, 11,12, 12,13, 13,14, 14,15, 15,12;
//GLushort indices[] = 0,1 ,1,2, 2,3, 3,4, 4,5, 5,6, 6,7, 7,8, 8,9, 9,10, 10,11 ;
ret.numIndices = NUM_ARRAY_ELEMENTS(indices);
ret.indices = new GLushort[ret.numIndices];
memcpy(ret.indices, indices, sizeof(indices));
return ret;
【问题讨论】:
mSpringMass.vertices
的类型是什么?根据它是什么,sizeof(mSpringMass.vertices)
可能不是缓冲区的实际大小。你在原来的glBufferData()
调用中使用了mSpringMass.vertexBufferSize()
。
你试过GL_DYNAMIC_DRAW
而不是GL_STATIC_DRAW
,也许某些gl实现冻结了静态缓冲区...
mSpringMass.vertices 是一个 GLfloats 数组
【参考方案1】:
我想通了。
在我的对象生成器类中,顶点数据从未更新,因为我离开了static const
qualifiers。 glBuffersubData 运行良好,但它只是覆盖了完全相同的数据......
【讨论】:
以上是关于OpenGL +无法使用buffersubdata更新缓冲区数据的主要内容,如果未能解决你的问题,请参考以下文章