Opengl 只绘制创建的第一个对象
Opengl only draw the first object create
我无法使用 openGl 渲染多个三角形,只显示 1 个对象。
我只查看了第一个对象,我已经创建了。
对我来说,问题在于索引或 glBufferData() 或 glVertexAttribPointer()。
对于演示仅使用顶点和索引。
顶点是 Float 类型,索引是 unsigned int 类型。
void Objets::createShader() {
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* adapter[1];
string temp = readShaderCode("VertexShaderCode.glsl");
adapter[0] = temp.c_str();
glShaderSource(vertexShaderID, 1, adapter, 0);
temp = readShaderCode("FragmentShaderCode.glsl");
adapter[0] = temp.c_str();
glShaderSource(fragmentShaderID, 1, adapter, 0);
glCompileShader(vertexShaderID);
glCompileShader(fragmentShaderID);
//checkShaders(vertexShaderID, fragmentShaderID); no error
programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
//checkProgram(programID); no error
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &vertexBufferID);
glGenBuffers(1, &colorBufferID);
glGenBuffers(1, &indexBufferID);
}
我在使用 sfml 创建 window 后使用 createShader()。
我创建了 2 个形状并加载了我的 2 个形状:
graphiques3d.createShapeAndBufferit(Shapes::loadFromFileObj("objs/Cube.004.obj"));
graphiques3d.createShapeAndBufferit(Shapes::loadFromFileObj("objs/Cube.007.obj"));
Shapes Shapes::loadFromFileObj(string nameFile) {
Shapes shape;
string newString;
string buf;
string line;
ifstream myfile(nameFile);
if (myfile.is_open())
{
while (getline(myfile, line))
{
std::stringstream ss;
if (line.rfind(shape.verticesS, 0) == 0) {
newString = line.substr(2, line.length());
ss.str(newString);
while (ss >> buf) {
shape.vertices.push_back((GLfloat)stof(buf));
}
}
else if (line.rfind(shape.indicesS, 0) == 0) {
newString = line.substr(2, line.length());
ss.str(newString);
while (ss >> buf) {
GLuint valBuffer = (GLuint)atoi(buf.c_str());
shape.indices.push_back((GLuint)(valBuffer - 1));
}
}
}
myfile.close();
}
else cout << "Unable to open file";
return shape;
}
然后它使用 createShapeAndBufferit(Shapes shape);
void Objets::createShapeAndBufferit(Shapes shape) {
for (int a = 0; a < shape.getVertices().size(); a++)
vertices.push_back(shape.getVertices().at(a));
for (int b = 0; b < shape.getIndices().size(); b++)
indices.push_back(shape.getIndices().at(b));
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
}
当我打印我的形状时,我有这个:
/1/1/-3/1/-1/-3/1/1/-1/1/-1/-1/-1/1/-3/-1/-1/ -3/-1/1/-1/-1/-1/-1 大小顶点:24
:4:2:0:2:7:3:6:5:7:1:7:5:0:3:1:4:1:5:4:6:2:2:6:7:6 :4:5:1:3:7:0:2:3:4:0:1 sizeIndices: 36
/3/1/1/3/-1/1/3/1/3/3/-1/3/1/1/1/1/-1/1/1/1/3 /1/-1/3 sizeVertices: 24
:4:2:0:2:7:3:6:5:7:1:7:5:0:3:1:4:1:5:4:6:2:2:6:7:6 :4:5:1:3:7:0:2:3:4:0:1 sizeIndices: 36
然后我画画:
void Objets::dessiner(float x, float y, float z) {
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
glUseProgram(programID);
mat4 projectionMatrix = glm::perspective(90.f, width / height, 0.1f, 100.f);
mat4 modelTransformMatrix = glm::translate(vec3(x, y, z));
mat4 modelFullTransformMatrix = projectionMatrix * modelTransformMatrix;
GLint modelTransformMatrixUniformLocation =
glGetUniformLocation(programID, "modelFullTransformMatrix");
glUniformMatrix4fv(modelTransformMatrixUniformLocation,
1, GL_FALSE, &modelFullTransformMatrix[0][0]);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (GLvoid*)0);
glBindVertexArray(0);
}
我不知道你是否需要fragmentShader和vertexShader,所以我把它放在:
片段着色器:
#version 330 core
out vec4 FragColor;
in vec3 color;
void main()
{
FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
uniform mat4 modelFullTransformMatrix;
out vec3 color;
void main()
{
vec4 v = vec4(aPos, 1.0);
gl_Position = modelFullTransformMatrix*v;
color = aColor;
}
所以如果我理解你的解释正确,你的问题是你加载了两个单独的网格 ('shapes'),并且每个网格的索引从零开始,但你想将它们都绘制在一个单个绘制调用?
也许 glMultiDrawElementsBaseVertex 就是您想要的?
除了基本的 DrawArrays / DrawElements 之外,另请参阅 https://www.khronos.org/opengl/wiki/Vertex_Rendering 了解其他替代方案。
我无法使用 openGl 渲染多个三角形,只显示 1 个对象。
我只查看了第一个对象,我已经创建了。
对我来说,问题在于索引或 glBufferData() 或 glVertexAttribPointer()。 对于演示仅使用顶点和索引。
顶点是 Float 类型,索引是 unsigned int 类型。
void Objets::createShader() {
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* adapter[1];
string temp = readShaderCode("VertexShaderCode.glsl");
adapter[0] = temp.c_str();
glShaderSource(vertexShaderID, 1, adapter, 0);
temp = readShaderCode("FragmentShaderCode.glsl");
adapter[0] = temp.c_str();
glShaderSource(fragmentShaderID, 1, adapter, 0);
glCompileShader(vertexShaderID);
glCompileShader(fragmentShaderID);
//checkShaders(vertexShaderID, fragmentShaderID); no error
programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
//checkProgram(programID); no error
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &vertexBufferID);
glGenBuffers(1, &colorBufferID);
glGenBuffers(1, &indexBufferID);
}
我在使用 sfml 创建 window 后使用 createShader()。
我创建了 2 个形状并加载了我的 2 个形状:
graphiques3d.createShapeAndBufferit(Shapes::loadFromFileObj("objs/Cube.004.obj"));
graphiques3d.createShapeAndBufferit(Shapes::loadFromFileObj("objs/Cube.007.obj"));
Shapes Shapes::loadFromFileObj(string nameFile) {
Shapes shape;
string newString;
string buf;
string line;
ifstream myfile(nameFile);
if (myfile.is_open())
{
while (getline(myfile, line))
{
std::stringstream ss;
if (line.rfind(shape.verticesS, 0) == 0) {
newString = line.substr(2, line.length());
ss.str(newString);
while (ss >> buf) {
shape.vertices.push_back((GLfloat)stof(buf));
}
}
else if (line.rfind(shape.indicesS, 0) == 0) {
newString = line.substr(2, line.length());
ss.str(newString);
while (ss >> buf) {
GLuint valBuffer = (GLuint)atoi(buf.c_str());
shape.indices.push_back((GLuint)(valBuffer - 1));
}
}
}
myfile.close();
}
else cout << "Unable to open file";
return shape;
}
然后它使用 createShapeAndBufferit(Shapes shape);
void Objets::createShapeAndBufferit(Shapes shape) {
for (int a = 0; a < shape.getVertices().size(); a++)
vertices.push_back(shape.getVertices().at(a));
for (int b = 0; b < shape.getIndices().size(); b++)
indices.push_back(shape.getIndices().at(b));
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
}
当我打印我的形状时,我有这个:
/1/1/-3/1/-1/-3/1/1/-1/1/-1/-1/-1/1/-3/-1/-1/ -3/-1/1/-1/-1/-1/-1 大小顶点:24 :4:2:0:2:7:3:6:5:7:1:7:5:0:3:1:4:1:5:4:6:2:2:6:7:6 :4:5:1:3:7:0:2:3:4:0:1 sizeIndices: 36
/3/1/1/3/-1/1/3/1/3/3/-1/3/1/1/1/1/-1/1/1/1/3 /1/-1/3 sizeVertices: 24 :4:2:0:2:7:3:6:5:7:1:7:5:0:3:1:4:1:5:4:6:2:2:6:7:6 :4:5:1:3:7:0:2:3:4:0:1 sizeIndices: 36
然后我画画:
void Objets::dessiner(float x, float y, float z) {
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
glUseProgram(programID);
mat4 projectionMatrix = glm::perspective(90.f, width / height, 0.1f, 100.f);
mat4 modelTransformMatrix = glm::translate(vec3(x, y, z));
mat4 modelFullTransformMatrix = projectionMatrix * modelTransformMatrix;
GLint modelTransformMatrixUniformLocation =
glGetUniformLocation(programID, "modelFullTransformMatrix");
glUniformMatrix4fv(modelTransformMatrixUniformLocation,
1, GL_FALSE, &modelFullTransformMatrix[0][0]);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (GLvoid*)0);
glBindVertexArray(0);
}
我不知道你是否需要fragmentShader和vertexShader,所以我把它放在:
片段着色器:
#version 330 core
out vec4 FragColor;
in vec3 color;
void main()
{
FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
uniform mat4 modelFullTransformMatrix;
out vec3 color;
void main()
{
vec4 v = vec4(aPos, 1.0);
gl_Position = modelFullTransformMatrix*v;
color = aColor;
}
所以如果我理解你的解释正确,你的问题是你加载了两个单独的网格 ('shapes'),并且每个网格的索引从零开始,但你想将它们都绘制在一个单个绘制调用?
也许 glMultiDrawElementsBaseVertex 就是您想要的?
除了基本的 DrawArrays / DrawElements 之外,另请参阅 https://www.khronos.org/opengl/wiki/Vertex_Rendering 了解其他替代方案。