OpenGL 纹理无法正常工作 - 黑屏

OpenGL texture does not work with no errors - black screen

我只是不明白为什么它不起作用 - 它只是显示白屏...(或黑屏,因为 glClearColor) PS。 > 纹理也打破了其他一切...... 我检查了着色器和代码:没有错误,没有响应,什么都没有。包括质地。 我认为着色器是正确的,但我不知道其他任何事情。我还有所有的库:GLEW、GLFW、OPENGL,从 stb_image...

复制的单个头文件

代码如下:

#include <iostream>
#include <fstream>
#include <string>
#include "GL/glew.h"
#include "GLFW/glfw3.h"

#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));

#define STB_IMAGE_IMPLEMENTATION
#include "extern/stb_image/stb_image_vendor/stb_image.h"

void OpenGlClError() {
    while (glGetError());
}
bool OpenGlError(const char* func, int line, const char* file) {
    while (GLenum error = glGetError()) {
        std::cout << "GLTest: OPENGL ERROR: " << error << " in function " << func << " at line " << line << ", FILE: " << file << "\n";
        return false;
    }
    return true;
}

#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));

class Texture {
private:
    unsigned int TextID;
    std::string FilePath;
    unsigned char* LocalBuffer;
    int Width, Height, BytesPixel;
public:
    Texture(const std::string path)
        : TextID(0), FilePath(path), LocalBuffer(nullptr), Width(0), Height(0), BytesPixel(0) {
        CALL(glGenTextures(1, &TextID));
        CALL(glBindTexture(GL_TEXTURE_2D, TextID));

        stbi_set_flip_vertically_on_load(1);
        LocalBuffer = stbi_load(path.c_str(), &Width, &Height, &BytesPixel, 4);

        CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
        CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
        CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
        CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

        CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, LocalBuffer));
        CALL(glBindTexture(GL_TEXTURE_2D, 0));

        if (LocalBuffer) { //if localbuffer exists
            stbi_image_free(LocalBuffer);
        }
    }
    ~Texture() {
        glDeleteTextures(1, &TextID);
    }
    void Bind(unsigned int slot = 0){
        CALL(glActiveTexture(GL_TEXTURE0 + slot));
        CALL(glBindTexture(GL_TEXTURE_2D, TextID));
    }
    void Unbind() {
        glBindTexture(GL_TEXTURE_2D, 0);
    }
};

static std::string ReadShader(const std::string& filename) {
    std::ifstream stream;
    std::string line;
    std::string str;
    stream.open(filename);
    while (getline(stream, line)) {
        str.append(line).append("\n");
    }
    std::cout << str;
    stream.close();
    return str;
}
static unsigned int CompileShader(const std::string& source, unsigned int type) {
    unsigned int shader = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(shader, 1, &src, nullptr);
    glCompileShader(shader);
    int result;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
    // i - int
    // v - vector
    if (result == GL_FALSE) {
        std::cout << "Shader cannot be compiled.\n" << (type == GL_VERTEX_SHADER ? "vertex s." : "fragments.") << "\n";
        int length;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
        char* message = (char*)_malloca(length * sizeof(char));
        glGetShaderInfoLog(shader, length, &length, message);
        std::cout << message << "\n";
        glDeleteShader(shader);
    }
    return shader;
}
static int CreateShader(const std::string& vShader, const std::string& fShader) {
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(vShader, GL_VERTEX_SHADER);
    unsigned int fs = CompileShader(fShader, GL_FRAGMENT_SHADER);
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);
    glDeleteShader(vs);
    glDeleteShader(fs);
    return program;
}

int main() {
    glfwInit();
    //make window
    GLFWwindow* window;
    //std::cout << "GLTest:" << glGetString(GL_VERSION) << "\n";
    window = glfwCreateWindow(800, 500, "Modern OpenGL Test", NULL, NULL);
    glfwMakeContextCurrent(window);
    glewInit();

    float texver[16] = {
         -1.0f, -1.0f , 0.0f, 0.0f,
         1.0f, -1.0f, 1.0f, 0.0f,
         1.0f, 1.0f, 1.0f, 1.0f,
         -1.0f, -1.0f, 0.0f, 1.0f
    };

    float texindex[6] = {
        0, 1, 2,
        2, 3, 0
    };

    float vertices[12] = {
         1.0f, 1.0f,
         0.0f, -1.0f,
         1.0f, -1.0f,

         -1.0f, 1.0f,
          0.0f, 1.0f,
         -1.0f, -1.0f
    };

    //unsigned int varray; //< dont actually need it...
    //glGenVertexArrays(1, &varray);
    //glBindVertexArray(varray);

    //unsigned int vb;
    //glGenBuffers(1, &vb);
    //glBindBuffer(GL_ARRAY_BUFFER, vb);
    //glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), vertices, GL_STATIC_DRAW);
    //
    //glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); //said hey we have this set up like that, links in vertex array
    //glEnableVertexAttribArray(0); //yea remember it

    unsigned int tb;
    glGenBuffers(1, &tb);
    glBindBuffer(GL_ARRAY_BUFFER, tb);
    glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); //said hey we have this set up like that, links in vertex array
    glEnableVertexAttribArray(0); //yea remember it

    unsigned int shaders = CreateShader(ReadShader("shaders/basic_texture_vertex.shader"), ReadShader("shaders/basic_texture_fragment.shader"));
    glUseProgram(shaders);
    
    Texture tt("../!Assets/editor/img/intro_logo.png");
    tt.Bind();

    CALL(int location = glGetUniformLocation(shaders, "u_Texture"));
    CALL(glUniform1i(location, 0));

    CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(1, 1, 1, 1);
        //Drawing
        glDrawArrays(GL_TRIANGLES, 0, 6 * 2);


        glfwSwapBuffers(window);
        glfwPollEvents();

    }
    glDeleteProgram(shaders);
    glfwTerminate();
}

您错过了为纹理坐标指定顶点属性。例如

unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);

// vertex cooridnates
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
glEnableVertexAttribArray(0);

// texture coordinates
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2));
glEnableVertexAttribArray(1);

glDrawArrays的最后一个参数是顶点数。由于您只有 4 个顶点,因此参数不能是 6*2.
无论如何,由于您已经指定了一个数组索引,因此您似乎想要为索引渲染指定一个 Index buffer. You have to use glDrawElements

索引必须是整数数据类型:

int texindex[6] = {
    0, 1, 2,
    0, 2, 3
};

生成索引(GL_ELEMENT_ARRAY_BUFFER)缓冲区:

unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), texindex, GL_STATIC_DRAW); 

画出发声:

glDrawArrays(GL_TRIANGLES, 0, 6 * 2);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);