【问题标题】:OpenGL ignoring ShadersOpenGL忽略着色器
【发布时间】:2014-06-02 18:17:08
【问题描述】:

OpenGl 似乎忽略了我的着色器,没有缩放,也没有改变颜色。 Screenshot

我也没有通过错误处理程序收到任何错误。 我已经做了几个小时了,我做错了什么?

我正在使用 freeglut 和 glew(不知道这很重要)。

我正在这样做:

  • OpenGL 4.3

  • Radeon HD 6800

  • Windows 8.1 企业版

顶点着色器:

#version 120

attribute vec3 position;

void main()
{
    gl_Position = vec4(position*2.0,1.0);

}       

片段着色器:

#version 120

void main()
{
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}

着色器.cpp

#include "Shader.h"
#include <fstream>
#include "ErrorHandler.h"

namespace{
    std::string VERTEX_SHADER_EXTENSION = ".vs";
    std::string FRAGMENT_SHADER_EXTENSION = ".fs";
}

Shader::Shader(const std::string& fileName)
{
    m_program = glCreateProgram();
    m_shaders[0] = CreateShader(LoadShader(fileName + VERTEX_SHADER_EXTENSION), GL_VERTEX_SHADER);
    m_shaders[1] = CreateShader(LoadShader(fileName + FRAGMENT_SHADER_EXTENSION), GL_FRAGMENT_SHADER);

    for (unsigned int i = 0; i < NUM_SHADERS; i++)
    {
        glAttachShader(m_program, m_shaders[i]);
    }
            glBindAttribLocation(m_program, 0, "position");

    glLinkProgram(m_program);
    CheckShaderError(m_program, GL_LINK_STATUS, true, "Program linking failed: ");
    glValidateProgram(m_program);
    CheckShaderError(m_program, GL_VALIDATE_STATUS, true, "Program is invalid: ");
}

void Shader::Bind()
{
    glUseProgram(m_program);
}

Shader::~Shader()
{
    for (unsigned int i = 0; i < NUM_SHADERS; i++)
    {
        glDetachShader(m_program, m_shaders[i]);
        glDeleteShader(m_shaders[i]);
    }
    glDeleteProgram(m_program);
}

GLuint Shader::CreateShader(const std::string& text, GLenum shaderType)
{
    GLuint shader = glCreateShader(shaderType);
    if (shader == 0)
    {
        ErrorHandler::LogError("Error: Shader creation failed!");
    }
    const GLchar* shaderSourceStrings[1];
    GLint shaderSourceStringLength[1];

    shaderSourceStringLength[0] = text.length();
    shaderSourceStrings[0] = text.c_str();

    glShaderSource(shader, 1, shaderSourceStrings, shaderSourceStringLength);
    glCompileShader(shader);
    CheckShaderError(shader, GL_COMPILE_STATUS, false, "Shader compilation failed: ");
    return shader;
}
std::string Shader::LoadShader(const std::string& fileName)
{
    std::ifstream file;
    file.open((fileName).c_str());
    std::string output;
    std::string line;

    if (file.is_open())
    {
        while(file.good())
        {
            getline(file, line);
            output.append(line + "\n");
        }
    }
    else
    {
        ErrorHandler::LogError("Unable to load shader: " + fileName);
    }
    return output;

}
void Shader::CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
{
    GLint success = 0;
    GLchar error[1024] = { 0 };

    if (isProgram)
        glGetProgramiv(shader, flag, &success);
    else
        glGetShaderiv(shader, flag, &success);

    if (success == GL_FALSE)
    {
        if (isProgram)
            glGetProgramInfoLog(shader, sizeof(error), NULL, error);
        else
            glGetShaderInfoLog(shader, sizeof(error), NULL, error);

        ErrorHandler::LogError(errorMessage + ": " + error + "'");
    }
}

游戏循环:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Shaders[0].Bind();
Meshes[0].Draw();
glutSwapBuffers();

Mesh.cpp:

#include "Mesh.h"


Mesh::Mesh(Vertex* vertices, unsigned int numVertices)
{
    m_drawCount = numVertices;
    glGenVertexArrays(1, &m_vertexArrayObject);
    glBindVertexArray(*m_vertexArrayBuffers);
    glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);
    glBindBuffer(GL_ARRAY_BUFFER,m_vertexArrayBuffers[POSITION_VB]);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glBindVertexArray(0);
}


Mesh::~Mesh()
{
    glDeleteVertexArrays(1, &m_vertexArrayObject);
}

void Mesh::Draw()
{
    glBindVertexArray(m_vertexArrayObject);
    glDrawArrays(GL_TRIANGLES, 0, m_drawCount);
    glBindVertexArray(0);
}

主函数和初始化函数:

int init(int argc, char** argv)
{
    //init glut
    glutInit(&argc, argv);
    Display display(800, 600, "OpenGL Playground");
    //init glew
    GLenum err = glewInit();
    if (GLEW_OK != err){
        ErrorHandler::LogError(std::string(reinterpret_cast<const char*>(glewGetErrorString(err))));
        return 1;
    }

    //bind functions
    glutDisplayFunc(draw);//Drawloop
    return 0;
}
int main(int argc, char** argv)
{
    int i = init(argc, argv);
    Vertex verts[3];
    verts[0] = Vertex(Vector3f(-0.5f, -0.5f, 0.0f));
    verts[1] = Vertex(Vector3f(0.0f, 0.5f, 0.0f));
    verts[2] = Vertex(Vector3f(0.5f, -0.5f, 0.0f));
    Meshes.push_back(Mesh(verts, (sizeof(verts)/sizeof(verts[0]))));
    Shaders.push_back(Shader("./res/basicShader"));
    if (i == 0)
    {
        glutMainLoop();
    }
    else
    {
        cin.ignore(1);
        return 1;
    }
    return 0;
}

显示.cpp:

#include "Display.h"
#include <GL\glut.h>
#include <GL\freeglut.h>
#include <iostream>
#include "ErrorHandler.h"

Display::Display(int width, int height, const std::string& title)
{
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);
    glutInitWindowSize(width, height);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(title.c_str());
    glClearColor(0.0f, 0.2f, 0.2f, 1.0f);
}


Display::~Display()
{
}

【问题讨论】:

  • 顶点着色器代码行中间的分号是否只是 StackOverflow 中的拼写错误,还是存在于您的实际代码中?
  • 哦,是的,这只是 StackOverflow 帖子的一部分。我现在就修。
  • 你怎么知道GLSL编译器把position放在属性索引0上?
  • @genpfault 哦,我想我在模拟代码以尝试修复它时删除了它,但我最初有 glBindAttribLocation(m_program, 0, "position");。我把它加回来了,但它没有修复它。

标签: c++ opengl glsl glew freeglut


【解决方案1】:

Mesh 构造函数中的这段代码看起来不正确:

glGenVertexArrays(1, &m_vertexArrayObject);
glBindVertexArray(*m_vertexArrayBuffers);
glGenBuffers(NUM_BUFFERS, m_vertexArrayBuffers);

您可能打算将 m_vertexArrayObject 作为参数传递给 glBindVertexArray()

【讨论】:

  • 天啊,这太可怕了(谁画了一个三角形)。但它并没有真正解决着色器不工作的问题。不过还是谢谢。
  • 由于我没有发现任何问题,所以我尝试了您的代码。不得不填写一些小件,主要是申报。但它对我有用,所以我认为你的 OpenGL 调用没有任何问题。不过,基于在您的代码中看到Shaders[0]Meshes[0],我有一个偷偷摸摸的怀疑。你能说明ShadersMeshes 是如何声明和初始化的吗?我怀疑您可能在上下文当前之前构造了这些对象,或者您不小心复制了这些对象,这会清除封装在 C++ 对象中的 OpenGL 对象。
  • 添加了主循环和初始化的东西。再次感谢您花时间查看它。
  • 不用花时间,我的声明有问题。我在绘制调用开始时定义了一组着色器和网格(我知道),它们像梦一样工作。再次感谢 1000 次,你真的让我度过了一周。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
  • 2015-03-02
  • 1970-01-01
相关资源
最近更新 更多