c++ OpenGL示例化显示奇怪的形状

zzoitvuj  于 2022-12-05  发布在  其他
关注(0)|答案(1)|浏览(121)

我正在用OpenGL制作一个简单的游戏,游戏中有一个玩家和多个气泡,所有气泡都是球体。不幸的是,示例化并不像预期的那样工作,并导致一些奇怪的效果。我是示例化新手,看不到可能导致问题的原因。
播放器类中的Draw方法:

void Player::draw(glm::mat4 ViewMat, GLfloat aspect, glm::vec3 light, GLfloat zoom)
{
    bindProgram();
    bindBuffers();

    glm::mat4 Projection = glm::perspective(zoom, aspect, 0.1f, 100.0f);

    glm::mat4 Model = glm::mat4(1.0f);
    glm::mat4 MVP = Projection * ViewMat * Model; 

    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MVP"), 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "M"), 1, GL_FALSE, &Model[0][0]);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "V"), 1, GL_FALSE, &ViewMat[0][0]);
    glUniform3f(glGetUniformLocation(shaderProgram, "origin"), origin.x, origin.y, origin.z);
    glUniform3f(glGetUniformLocation(shaderProgram, "lightPosWorld"), light.x, light.y, light.z);
    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size() / 3); 
}

Bubble类中的静态绘制方法:

void Bubble::drawAll(glm::mat4 ViewMat, GLfloat aspect, glm::vec3 light, GLfloat zoom,
                     std::vector<Bubble *> allInstances)
{
    std::vector<float> origins;
    uint count = 0;
    for (auto b : allInstances)
    {
        origins.push_back(b->origin.x);
        origins.push_back(b->origin.y);
        origins.push_back(b->origin.z);
        count++;
    }
    allInstances[0]->bindProgram();
    allInstances[0]->bindBuffers();
    glBufferData(GL_ARRAY_BUFFER, origins.size() * sizeof(origins), origins.data(), GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, originsBuffer);
    glVertexAttribPointer(1,        // attribute. No particular reason for 0, but must match the layout in the shader.
                          3,        // size
                          GL_FLOAT, // type
                          GL_FALSE, // normalized?
                          0,        // stride
                          (void *)0 // array buffer offset
    );

    glm::mat4 Projection = glm::perspective(zoom, aspect, 0.1f, 100.0f);

    glm::mat4 Model = glm::mat4(1.0f);
    glm::mat4 MVP = Projection * ViewMat * Model;

    GLuint programID = allInstances[0]->shaderProgram;
    glVertexAttribDivisor(0, 0);
    glVertexAttribDivisor(1, 1);
    glUniformMatrix4fv(glGetUniformLocation(programID, "MVP"), 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(glGetUniformLocation(programID, "M"), 1, GL_FALSE, &Model[0][0]);
    glUniformMatrix4fv(glGetUniformLocation(programID, "V"), 1, GL_FALSE, &ViewMat[0][0]);
    glUniform3f(glGetUniformLocation(programID, "lightPosWorld"), light.x, light.y, light.z);

    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, allInstances[0]->vertices.size() / 3, count);
}

播放器顶点着色器:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;
uniform vec3 origin;
uniform vec3 lightPosWorld;
uniform vec3 cameraPos;

out vec3 vertexPosWorld;
out vec3 vertexNormal;
out vec3 eyeDirectionCamera;
out vec3 lightDirectionCamera;

void main()
{
    gl_Position =  MVP * vec4(vertexPosition_modelspace + origin,1);

    vertexPosWorld = (M * vec4(vertexPosition_modelspace + origin,1)).xyz;

    vertexNormal = normalize(vertexPosWorld - origin);
}

气泡顶点着色器:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 origin;

uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;
uniform vec3 lightPosWorld;
uniform vec3 cameraPos;

out vec3 vertexPosWorld;
out vec3 vertexNormal;
out vec3 eyeDirectionCamera;
out vec3 lightDirectionCamera;

void main()
{
    gl_Position =  MVP * vec4(vertexPosition_modelspace + origin,1);

    vertexPosWorld = (M * vec4(vertexPosition_modelspace + origin,1)).xyz;

    vertexNormal = normalize(vertexPosWorld - origin);
}

这是我得到的:Effect
但是我想得到两个看起来和玩家一模一样的泡泡(画得正确)。

mrwjdhj3

mrwjdhj31#

代码中有2个问题:

  1. sizeof(origins)std::vector的字节大小,但不是其基础类型。它应该是sizeof(float)
    1.在修改缓冲区的数据和属性之前,应该先呼叫glBindBuffer
    它应该有助于:
glBindBuffer(GL_ARRAY_BUFFER, originsBuffer);
    glBufferData(GL_ARRAY_BUFFER, origins.size() * sizeof(float), origins.data(), GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1,        // attribute. No particular reason for 0, but must match the layout in the shader.
                          3,        // size
                          GL_FLOAT, // type
                          GL_FALSE, // normalized?
                          0,        // stride
                          (void *)0 // array buffer offset
    );

相关问题