OpenGL glDrawElements 不渲染任何东西

问题描述

编辑:在 glDrawElements() 之后使用 glGetError() 时,我收到错误“警告统一 'u_Color' 不存在”。我正在使用如下所示的基本着色器,并在我的 RenderObject 管道中为着色器设置统一。有谁知道我需要添加什么才能识别制服?

大家好,我正在尝试将对象渲染到屏幕上,我已经使管道成功工作,但我似乎无法使用 glDrawElements 或 glDrawArrays 绘制任何内容。我通过在 renderer.Draw() 函数中调用 glClearColor(1.0f,0.0f,1.0f) 来测试管道,我得到了红色背景。我认为它要么与缓冲区数据以某种方式丢失有关,positionsArr 和indicesArr 具有额外分配的内存,这在传递给glDrawElements 时会导致问题,尽管这不会阻止glDrawArrays 工作,但它也不起作用,或也许我没有在 glGenBuffers 中分配足够的空间,或者我没有想到的东西。

管道:

void RenderObject(Renderer* renderer,std::vector<float> objectColor,std::vector<float> positions,std::vector<int> indices) {
        /*
       postions: float {
       x,x,y,z,z
       };

       indices (shape using class Shape): int {
       ex. 1,2,3
           2,3,1
       };

       translationCoord: float {
       x,z
       }

       textureColor: float {
       r,g,b,a
       }
       */


        /*
        positions = {
    -0.5f,-0.5f,0.5f,0.5f
    }

indices = {
    0,1,0
    }
    
    MAX_ARRAY_ALLOCATION = 15
    */

        float positionsArr[MAX_ARRAY_ALLOCATION];
        int indicesArr[MAX_ARRAY_ALLOCATION];
        VectorToArray<int>(indicesArr,indices);
        VectorToArray<float>(positionsArr,positions);

        VertexBuffer vb(positionsArr,positions.size() * sizeof(float));
        VertexBufferLayout layout;
        VertexArray va;
        layout.Push<float>((int)positions.size() / 2);
        va.AddBuffer(vb,layout);

        if (!firstObjectRender) {
            if (!firstTextureRender) {
                Shader shader(SHADER_SOURCE);
                appShader = shader;
                firstObjectRender = true;
            }
        }
        
        IndexBuffer ib(indicesArr,indices.size());

        appShader.Bind();
        appShader.SetUniform4f("u_Color",glm::vec4(objectColor[0],objectColor[1],objectColor[2],objectColor[3]));
        va.Bind();
        vb.Bind();
        renderer->Draw(va,ib,appShader,indicesArr);

        va.Unbind();
        vb.Unbind();
        ib.Unbind();
        appShader.Unbind();         
    }

VectorToArray 函数:

template<typename T> void VectorToArray(T* arr,std::vector<T> vect) {
            for (int i = 0; i < vect.size(); i++) {
                try {
                    if (i == MAX_ARRAY_ALLOCATION) throw(true);
                    arr[i] = vect[i];
                }
                catch (bool error) {
                    std::cout << "nano::Nano::VectorToArray vector greater than max array size\n";
                }
            }
        }

着色器:

const char* shaderProgram = "#version 330 core\n"
    "layout(location = 0) in vec4 position;\n"
    "void main() {\n"
    "gl_Position = position;\n"
    "}\0";

const char* fragmentProgram = "#version 330 core\n"
    "layout(location = 0) out vec4 color;\n"
    "uniform vec4 u_Color;\n"
    "void main() {\n"
    "gl_FragColor = u_Color;\n"
    "}\n\0";

VertexBuffer 类:

VertexBuffer::VertexBuffer() {

}

VertexBuffer::VertexBuffer(const void* data,unsigned int size) {
    glGenBuffers(1,&m_RendererID);
    glBindBuffer(GL_ARRAY_BUFFER,m_RendererID);
    glBufferData(GL_ARRAY_BUFFER,size,data,GL_STATIC_DRAW);
}

VertexBuffer::~VertexBuffer() {
    glDeleteBuffers(1,&m_RendererID);
}

void VertexBuffer::Bind() const {
    glBindBuffer(GL_ARRAY_BUFFER,m_RendererID);
}

void VertexBuffer::Unbind() const {
    glBindBuffer(GL_ARRAY_BUFFER,0);
}

VertexBufferLayout 类:

struct VertexBufferElement {
unsigned int count;
unsigned int type;
unsigned char normalized;

static unsigned int GetSizeOfType(unsigned int type) {
    switch (type) {
    case GL_FLOAT: return 4;
    case GL_UNSIGNED_INT: return 4;
    case GL_UNSIGNED_BYTE : return 1;
    }

    return 0;
}
};

class VertexBufferLayout {
private:
std::vector<VertexBufferElement> m_Elements;
unsigned int m_Stride;
public:
VertexBufferLayout() : m_Stride(0) {};

template<typename T> void Push(unsigned int count) {
    static_assert(false);
}

template<> void Push<float>(unsigned int count) {
    VertexBufferElement ve = { GL_FLOAT,count,GL_FALSE };
    m_Elements.push_back(ve);
    m_Stride += count * VertexBufferElement::GetSizeOfType(GL_FLOAT);
}

template<> void Push<unsigned int>(unsigned int count) {
    VertexBufferElement ve = { GL_UNSIGNED_INT,GL_FALSE };
    m_Elements.push_back(ve);
    m_Stride += count * VertexBufferElement::GetSizeOfType(GL_UNSIGNED_INT);
}

template<> void Push<unsigned char>(unsigned int count) {
    VertexBufferElement ve = { GL_UNSIGNED_BYTE,GL_TRUE };
    m_Elements.push_back(ve);
    m_Stride += count * VertexBufferElement::GetSizeOfType(GL_UNSIGNED_BYTE);
}

inline const std::vector<VertexBufferElement> GetElements() const { return m_Elements; }
inline unsigned int GetStride() const { return m_Stride; }
};

VertexArray 类:

    VertexArray::VertexArray() {
    glGenVertexArrays(1,&m_RendererID);
}

VertexArray::~VertexArray() {
    glDeleteVertexArrays(1,&m_RendererID);
}

void VertexArray::AddBuffer(const VertexBuffer& vb,const VertexBufferLayout& layout) {
Bind();
vb.Bind();
const auto& elements = layout.GetElements();
unsigned int offset = 0;

for (unsigned int i = 0; i < elements.size(); i++) {
    const auto& element = elements[i];
    glEnableVertexAttribArray(i);
    glVertexAttribPointer(i,element.count,element.type,element.normalized,layout.GetStride(),(const void*)offset);
    offset += element.count * VertexBufferElement::GetSizeOfType(element.type);
}
}

void VertexArray::Bind() const {
    glBindVertexArray(m_RendererID);
}

void VertexArray::Unbind() const {
    glBindVertexArray(0);
}

着色器类:

    Shader::Shader() {

}

Shader::Shader(const std::string& filepath) : m_FilePath(filepath),m_RendererID(0){
    m_RendererID = CreateShader(shaderProgram,fragmentProgram);

}

Shader::~Shader() {
    glDeleteProgram(m_RendererID);
}

void Shader::Bind() const {
    glUseProgram(m_RendererID);
}

void Shader::Unbind() const {
    glUseProgram(0);
}

unsigned int Shader::CreateShader(const std::string& vertexShader,const std::string&         fragmentShader) {
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(GL_VERTEX_SHADER,vertexShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER,fragmentShader);

    glAttachShader(program,vs);
    glAttachShader(program,fs);
    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(vs);
    glDeleteShader(fs);
    return program;
}

void Shader::SetUniform1i(const std::string& name,int value) {
    GLint location = GetUniformLocation(name);
    glUniform1i(location,value);
}

void Shader::SetUniform1f(const std::string& name,float value) {
    GLint location = GetUniformLocation(name);
    glUniform1f(location,value);
}

void Shader::SetUniform2f(const std::string& name,const glm::vec2& value) {
    GLint location = GetUniformLocation(name);
    glUniform2f(location,value.x,value.y);
}

void Shader::SetUniform3f(const std::string& name,const glm::vec3& value) {
    GLint location = GetUniformLocation(name);
    glUniform3f(location,value.y,value.z);
}

void Shader::SetUniform4f(const std::string& name,const glm::vec4& value) {
    GLint location = GetUniformLocation(name);
    glUniform4f(location,value.z,value.w);
}

void Shader::SetUniformMat4f(const std::string& name,const glm::mat4& matrix) {
    glUniformMatrix4fv(GetUniformLocation(name),GL_FALSE,&matrix[0][0]);
}

GLint Shader::GetUniformLocation(const std::string& name) {
    if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
        return m_UniformLocationCache[name];

    GLint location = glGetUniformLocation(m_RendererID,name.c_str());
    if (location == -1)
        std::cout << "Warining: uniform '" << name << "' doesn't exist!" << std::endl;
    

    m_UniformLocationCache[name] = location;

    return location;
}

渲染器类:

void Renderer::Clear() const {
    glClear(GL_COLOR_BUFFER_BIT);
}

void Renderer::Draw(const VertexArray& va,const IndexBuffer& ib,const Shader& shader,int indices[]) const {
    shader.Bind();
    va.Bind();
    ib.Bind();
    glDrawElements(GL_TRIANGLES,ib.GetCount(),GL_UNSIGNED_SHORT,indices);
    //glDrawArrays(GL_TRIANGLES,ib.GetCount());
}

我是如何实现的:

const unsigned int SCR_WIDTH = 960;
const unsigned int SCR_HEIGHT = 540;

class Test : public nano::Nano {
private:
std::vector<nano::Shape> shapes;
public:
Test() {

}

void InitializeObjects() {
    std::vector<float> positions = {
    -0.5f,0.5f
    };
    nano::Shape tempShape = nano::Shape::Shape("rect",positions);

    shapes.push_back(tempShape);
}

void OnCreate() override {
    InitializeObjects();
}

void OnRender(float deltaTime) override {
    Renderer renderer;
    std::vector<float> color = { 1.0f,1.0f };
    while (!glfwWindowShouldClose(nano::Nano::GetWindow()))
    {
        nano::Nano::OnInput();
        renderer.Clear();
        //glClearColor(1.0f,1.0f);

        for (auto& object : shapes) {
            nano::Nano::RenderObject(&renderer,color,object.GetPosition(),object.GetIndices());
        }

        nano::Nano::ManageRender();
    }
}

    void OnInput() override {
    
    }
};

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)