OpenGL 纹理状态使用警告:

OpenGL Texture state usage warning:

本文关键字:警告 状态 纹理 纹理状 OpenGL      更新时间:2023-10-16

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 %sn", 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("%sn", 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("%sn", 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.

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

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

在前sizeof(vertices)个字节之后读取肯定越界。目前,您尝试读取的字节数是顶点数组所包含的字节数的三倍。大小参数应该只是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 会通知您它们不能用于采样。

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