OpenGL纹理状态使用警告:

时间:2019-06-10 13:11:57

标签: c++ opengl

OpenGL向我发送错误Severity: GL_DEBUG_SEVERITY_LOW, Source: GL_DEBUG_SOURCE_API, Type: GL_DEBUG_TYPE_OTHER Texture state usage warning: The texture object (1) bound to texture image unit 0 does not have a defined base level and cannot be used for texture mapping. 或只是glDrawElements出现段错误。原因是为我的游戏引擎设置了纹理。

我尝试设置glPixelStorei(GL_UNPACK_ALIGNMENT, 1);。其他解决方案是无稽之谈或理论上的。通过其他解决方案,我的意思是与我的问题类似的问题/答案。

在从中等大小的游戏引擎中剥离了opengl代码后,下面是代码:

#include <iostream>
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <string>
#include <stb_image.h>
#include <cstring>

#include <stdint.h>
#include <string>

typedef uint64_t uint64;
typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t uint8;

typedef int64_t int64;
typedef int32_t int32;
typedef int16_t int16;
typedef int8_t int8;

typedef uint32 uint;

typedef uint8 byte;

typedef std::string String;

static const char* SeverityString(GLenum severity)
{
    switch(severity)
    {
        case GL_DEBUG_SEVERITY_HIGH: return "GL_DEBUG_SEVERITY_HIGH";
        case GL_DEBUG_SEVERITY_MEDIUM: return "GL_DEBUG_SEVERITY_MEDIUM";
        case GL_DEBUG_SEVERITY_LOW: return "GL_DEBUG_SEVERITY_LOW";
        default: return "Unkown severity type!";
    }
}

static const char* SourceString(GLenum source)
{
    switch(source)
    {
        case GL_DEBUG_SOURCE_API_ARB: return "GL_DEBUG_SOURCE_API";
        case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "GL_DEBUG_SOURCE_WINDOW_SYSTEM";
        case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "GL_DEBUG_SOURCE_SHADER_COMPILER";
        case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "GL_DEBUG_SOURCE_THIRD_PARTY";
        case GL_DEBUG_SOURCE_APPLICATION_ARB: return "GL_DEBUG_SOURCE_APPLICATION";
        case GL_DEBUG_SOURCE_OTHER_ARB: return "GL_DEBUG_SOURCE_OTHER";
        default: return "Unkown source type!";
    }
}

static const char* TypeString(GLenum type)
{
    switch(type)
    {
        case GL_DEBUG_TYPE_ERROR_ARB: return "GL_DEBUG_TYPE_ERROR";
        case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR";
        case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB";
        case GL_DEBUG_TYPE_PORTABILITY_ARB: return "GL_DEBUG_TYPE_PORTABILITY";
        case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "GL_DEBUG_TYPE_PERFORMANCE";
        case GL_DEBUG_TYPE_OTHER_ARB: return "GL_DEBUG_TYPE_OTHER";
        default: return "Unkown type!";
    }
}

static void APIENTRY GLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
                const GLchar *message, const void *userParam)
{
    #if 0
    if (type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR || 
        type == GL_DEBUG_TYPE_PERFORMANCE || 
        type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR ||
        type == GL_DEBUG_TYPE_PORTABILITY)
    {
        BZ_CORE_WARN("Severity: {0}, Source: {1}, Type: {2}. {3}.", SeverityString(severity), SourceString(source), TypeString(type), message);
    }
    else if (type == GL_DEBUG_TYPE_OTHER)
    {
        BZ_CORE_TRACE("Severity: {0}, Source: {1}, Type: {2}. {3}.", SeverityString(severity), SourceString(source), TypeString(type), message);
    }
    else
    {
        BZ_CORE_ERROR("Severity: {0}, Source: {1}, Type: {2}. {3}.", SeverityString(severity), SourceString(source), TypeString(type), message);
    }
    #else
    printf("Severity: %s, Source: %s, Type: %s %s\n", SeverityString(severity), SourceString(source), TypeString(type), message);
    #endif
}

int main()
{  
    if (!glfwInit())
    {
        printf("Failed to initialize glfw!\n");
        return EXIT_FAILURE;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow(960, 540, 
            "Houston we got a problem", nullptr, nullptr);

    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        printf("Faield to initialzie glad!\n");
        return EXIT_FAILURE;
    }

    glEnable(GL_DEBUG_OUTPUT);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
    glDebugMessageCallback(GLDebugCallback, NULL);
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);


    glClearColor(0.2f, 0.3f, 0.8f, 1.0f);

    uint32 vao;
    uint32 vbo;
    uint32 ibo;

    float vertices[] = {
        /* Position */          /* Colors */        /* texture coords */
        -0.5f,  0.5f, 1.0f,     1.0f, 0.0f, 0.0f,   1.0f, 1.0f,
         0.5f,  0.5f, 0.0f,     0.0f, 1.0f, 0.0f,   1.0f, 0.0f,
         0.5f, -0.5f, 0.0f,     0.0f, 0.0f, 1.0f,   0.0f, 0.0f,
        -0.5f, -0.5f, 1.0f,     1.0f, 1.0f, 0.0f,   0.0f, 1.0f
    };

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));

    uint32 indices[] = { 0, 1, 2, 2, 3, 0 };
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * sizeof(uint32), indices, GL_STATIC_DRAW);

    std::string vertexSrc = R"(
        #version 330 core
        #extension GL_ARB_separate_shader_objects : enable

        layout (location = 0) in vec3 in_Position;
        layout (location = 1) in vec3 in_Color;
        layout (location = 2) in vec2 in_TexCoords;

        out vec3 v_Position;
        out vec3 v_Color;
        out vec2 v_TexCoords;

        void main()
        {
            v_Position = in_Position;
            v_Color = in_Color;
            v_TexCoords = in_TexCoords;
            gl_Position = vec4(in_Position, 1.0f);
        }
    )";

    std::string fragmentSrc = R"(
        #version 330 core
        #extension GL_ARB_separate_shader_objects : enable

        layout (location = 0) out vec4 color;

        in vec3 v_Position;
        in vec3 v_Color;
        in vec2 v_TexCoords;

        uniform sampler2D u_Texture1;
        uniform sampler2D u_Texture2;

        void main()
        {
            color = mix(texture(u_Texture1, v_TexCoords), texture(u_Texture2, v_TexCoords), 0.2);
        }
    )";

    uint32 program = glCreateProgram();
    uint32 vs = glCreateShader(GL_VERTEX_SHADER);
    const char* src1 = vertexSrc.c_str();
    glShaderSource(vs, 1, &src1, nullptr);
    glCompileShader(vs);

    int32 result;
    glGetShaderiv(vs, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        int length;
        glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &length);
        char* message = new char[length];
        glGetShaderInfoLog(vs, length, &length, message);
        printf("Cannot compile vertex shader!\n");
        printf("%s\n", message);
        delete[] message;
        glDeleteShader(vs);

        return 0;
    }

    uint32 fs = glCreateShader(GL_FRAGMENT_SHADER);
    const char* src2 = fragmentSrc.c_str();
    glShaderSource(fs, 1, &src2, nullptr);
    glCompileShader(fs);

    glGetShaderiv(fs, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        int length;
        glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &length);
        char* message = new char[length];
        glGetShaderInfoLog(fs, length, &length, message);
        printf("Cannot compile fragment shader!\n");
        printf("%s\n", message);
        delete[] message;
        glDeleteShader(fs);

        return 0;
    }

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

    int32 linkStatus = 0;
    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
    if (linkStatus == GL_FALSE)
    {
        int length = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);

        char* message = new char[length + 1];
        memset(message, 0, length + 1);
        glGetProgramInfoLog(program, length, &length, message);
        glDeleteProgram(program);
        printf("Program failed to link.\n%s", message);
        delete[] message;
        return 0;
    }

    glValidateProgram(program);

    glDetachShader(program, vs);
    glDetachShader(program, fs);

    glDeleteShader(vs);
    glDeleteShader(fs);

    glUseProgram(program);

    stbi_set_flip_vertically_on_load(1);
    int32 width, height, bpp;
    byte* bytes = stbi_load("textures/wall.jpg", &width, &height, &bpp, 4);

    uint32 texture1;
    glGenTextures(1, &texture1);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1);

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

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);
    stbi_image_free(bytes);

    stbi_set_flip_vertically_on_load(1);
    bytes = stbi_load("textures/awesomeface.png", &width, &height, &bpp, 4);
    uint32 texture2;
    glGenTextures(1, &texture2);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);

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

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);
    stbi_image_free(bytes);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);

    glUniform1i(glGetUniformLocation(program, "u_Texture1"), 0);
    glUniform1i(glGetUniformLocation(program, "u_Texture2"), 1);

    /* Main loop */
    while(!glfwWindowShouldClose(window))
    {

        glBindVertexArray(vao);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glUseProgram(program);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);

        glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(uint32), GL_UNSIGNED_INT, nullptr);

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, 0);
        glUseProgram(0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(vao);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    /* End */
    glDeleteTextures(1, &texture1);
    glDeleteTextures(1, &texture2);
    glDeleteProgram(program);
    glDeleteBuffers(1, &ibo);
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);

    glfwDestroyWindow(window);
    glfwTerminate();
}

我如何编译它:

#!/bin/bash

echo ----------spdlog output----------
cd Dependencies/spdlog
g++ -c ./src/spdlog.cpp -std=c++17 -I./include/ -DSPDLOG_COMPILED_LIB -o ../../bin/spdlog.o
cd ../../
ar rcs ./bin/libspdlog.a ./bin/spdlog.o
rm -rf ./bin/spdlog.o
echo ----------glfw output----------
cd Dependencies/glfw
gcc -c ./src/context.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/context.o
gcc -c ./src/init.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi  -o ../../bin/init.o 
gcc -c ./src/input.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/input.o
gcc -c ./src/monitor.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/monitor.o
#gcc -c ./src/vulkan.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -ldl -o ../../bin/vulkan.o
gcc -c ./src/window.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/window.o
gcc -c ./src/x11_init.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/x11_init.o
gcc -c ./src/x11_monitor.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/x11_monitor.o
gcc -c ./src/x11_window.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/x11_window.o
gcc -c ./src/xkb_unicode.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/xkb_unicode.o
gcc -c ./src/posix_time.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/posix_time.o
gcc -c ./src/posix_thread.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/posix_thread.o
gcc -c ./src/glx_context.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/glx_context.o
gcc -c ./src/egl_context.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/egl_context.o
gcc -c ./src/osmesa_context.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/osmesa_context.o
gcc -c ./src/linux_joystick.c -fPIC -std=c11 -I./include/ -D_GLFW_X11 -lX11 -lXxf86vm -lXrandr -lXi -o ../../bin/linux_joystick.o
cd ../../
ar rcs ./bin/libglfw.a ./bin/*.o
rm -rf ./bin/*.o
echo ----------Glad output----------
cd Dependencies/Glad
gcc -c ./src/glad.c -fPIC -I./include/ -o ../../bin/glad.o
cd ../../
ar rcs ./bin/libglad.a ./bin/glad.o
rm -rf ./bin/glad.o
echo ----------stb_image output----------
cd Dependencies/stb_image
g++ -c ./src/stb_image.cpp -fPIC -I./include -o ../../bin/stb_image.o
cd ../../
ar rcs ./bin/libstbimage.a ./bin/stb_image.o
rm -rf ./bin/stb_image.o

echo ---------- Main.cpp ----------
g++ main.cpp -ggdb -O0 -Wall -pedantic -std=c++17 -L./bin/ -I./Dependencies/glm/include/ -I./Dependencies/spdlog/include/ -I./Dependencies/glfw/include/ -I./Dependencies/Glad/include -I./Dependencies/stb_image/include -lstbimage -lspdlog -lglfw -lglad -lX11 -lXxf86vm -lXrandr -lXi -lGLU -ldl -lz -lpthread -lm -DGLFW_INCLUDE_NONE -o ./bin/Problem
echo ----------End of compile----------

我包含了整个文件,因为您会问我:顶点缓冲区是如何生成的,等等。

编辑:添加一些缺少的代码后。 Opengl错误现在为Severity: GL_DEBUG_SEVERITY_LOW, Source: GL_DEBUG_SOURCE_API, Type: GL_DEBUG_TYPE_OTHER Texture state usage warning: The texture object (1) bound to texture image unit 0 does not have a defined base level and cannot be used for texture mapping.Severity: GL_DEBUG_SEVERITY_LOW, Source: GL_DEBUG_SOURCE_API, Type: GL_DEBUG_TYPE_OTHER Texture state usage warning: The texture object (2) bound to texture image unit 1 does not have a defined base level and cannot be used for texture mapping.

1 个答案:

答案 0 :(得分:3)

您似乎误解了sizeof运算符的作用:它返回基础数据类型的大小以字节为单位

glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(vertices), vertices, GL_STATIC_DRAW);

肯定会在前sizeof(vertices)个字节之后读取越界。当前,您尝试读取的字节数是vertices数组的三倍。 size参数应仅为sizeof(vertices)

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * sizeof(uint32), indices, GL_STATIC_DRAW);

这里也一样。将sizeof(indices) * sizeof(uint32)替换为sizeof(indices)

glDrawElements(GL_TRIANGLES, sizeof(indices), GL_UNSIGNED_INT, nullptr);

此行尝试绘制sizeof(indices) == 6 * sizeof(uint32) == 6 * 4 == 24顶点。由于索引缓冲区仅包含6个有效索引,因此代码段错误取决于您从第二条有问题的行读取的随机数据。

OpenGL消息仅仅是信息。它们不足以警告。可能是由于第一次绑定纹理时您具有活动的着色器引起的。由于这些纹理不包含任何数据,因此OpenGL会通知您它们不能用于采样。

如果要消除此错误,请在初始化纹理之前尝试解除绑定着色器。