OpenGL纹理绘制为一种颜色

art*_*mer 3 c++ opengl glsl sdl-2

我在这里找到了类似的帖子,但没有一个能帮助我解决我的问题。我只是使用基本的 OpenGL,并尝试绘制一个应用了纹理的三角形。但出于某种原因,三角形是一种纯色。这种颜色恰好与纹理的背景颜色相同。

这是我试图绘制的纹理

这是我运行程序时的结果

在此处输入图片说明

我已经尝试通过编辑纹理在左下角(原点)有一些蓝色,结果是这样的

在此处输入图片说明

我的猜测是它插入红色和蓝色给我紫色。但我不知道为什么它会首先插入颜色而不是像我想要的那样绘制纹理。

这是我的代码相关部分的一些零碎部分:

在主循环之前启用事物

glClearColor(0, 0, 0, 1);

glEnable(GL_BLEND);
glEnable(GL_TEXTURE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Run Code Online (Sandbox Code Playgroud)

加载着色器

auto vertString = getSource("test.vert");
auto vertSource = vertString.c_str();
GLint vertLength = vertString.length();

auto fragString= getSource("test.frag");
auto fragSource = fragString.c_str();
GLint fragLength = fragString.length();

auto vertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertShader, 1, &vertSource, &vertLength);

auto fragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShader, 1, &fragSource, &fragLength);

//compile shaders
glCompileShader(vertShader);
checkShaderCompilation(vertShader, "vertex shader");

glCompileShader(fragShader);
checkShaderCompilation(fragShader, "fragment shader");

auto program = glCreateProgram();

glAttachShader(program, vertShader);
glAttachShader(program, fragShader);

glBindAttribLocation(program, 0, "i_position");
glBindAttribLocation(program, 1, "i_texCoord");

//link program
glLinkProgram(program);
checkProgramLinkage(program, "vertex shader", "fragment shader");

glDetachShader(program, vertShader);
glDetachShader(program, fragShader);

glDeleteShader(vertShader);
glDeleteShader(fragShader);
Run Code Online (Sandbox Code Playgroud)

加载纹理

SDL_Surface* surface = IMG_Load("Numel.png");

if (!surface)
{
    std::cout << "Unable to load texture." << std::endl;
    return 0;
}

auto width = surface->w;
auto height = surface->h;
GLuint texture = 0;

//generate the id
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

auto mode = surface->format->BytesPerPixel == 4 ? GL_RGBA : GL_RGB;

glTexImage2D(GL_TEXTURE_2D, 0, mode, surface->w, surface->h, false, mode, GL_UNSIGNED_BYTE, surface->pixels);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

SDL_FreeSurface(surface);

glBindTexture(GL_TEXTURE_2D, 0);
Run Code Online (Sandbox Code Playgroud)

顶点结构

struct Vertex
{
    Vector2 position;
    Vector2 texCoord;
};
Run Code Online (Sandbox Code Playgroud)

生成顶点数组

Vertex data[] = {
    -0.5, -0.5, 0, 0,
    0.5, -0.5, 1, 0,
    0.5, 0.5, 1, 1
};

GLuint vertexBuffer = 0, vertexArray = 0;

glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*3, data, GL_STATIC_DRAW);

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

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, 0, sizeof(Vertex), (char*)offsetof(Vertex, position));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, 0, sizeof(Vertex), (char*)offsetof(Vertex, texCoord));
Run Code Online (Sandbox Code Playgroud)

并在主循环中绑定/绘制所有内容

glClear(GL_COLOR_BUFFER_BIT);

//texture
glBindTexture(GL_TEXTURE_2D, texture);

//shader
auto colorLoc = glGetUniformLocation(program, "u_color");
glUniform3f(colorLoc, 0, 0, 1);

auto useTextureLoc = glGetUniformLocation(program, "u_usingTexture");
glUniform1i(useTextureLoc, 1);

auto textureLoc = glGetUniformLocation(program, "u_sampler");
glUniform1i(textureLoc, 0);

glUseProgram(program);

//vertex array
glBindVertexArray(vertexArray);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 3);

SDL_GL_SwapWindow(window);
Run Code Online (Sandbox Code Playgroud)

这是我的顶点着色器

#version 420

in vec2 i_position;
in vec2 i_texCoord;

out vec2 o_texCoord;

void main()
{
    o_texCoord=i_texCoord;
    gl_Position=vec4(i_position, 0, 1);
}
Run Code Online (Sandbox Code Playgroud)

还有我的片段着色器

#version 420

uniform vec3 u_color;
uniform sampler2D u_sampler;
uniform bool u_usingTexture;

in vec2 i_texCoord;

out vec4 o_color;

void main()
{
    if(u_usingTexture)
        o_color=texture(u_sampler, i_texCoord);
    else
        o_color=vec4(u_color, 1);
}
Run Code Online (Sandbox Code Playgroud)

我确实已经尝试解决这个问题好几天了,但我不知道。如果有人能弄清楚为什么它用一种颜色而不是纹理进行渲染,我们将不胜感激。

der*_*ass 5

你没有使用你的 texcoords:

这是我的顶点着色器

[...]
out vec2 o_texCoord;
Run Code Online (Sandbox Code Playgroud)

还有我的片段着色器

[...]
in vec2 i_texCoord;
Run Code Online (Sandbox Code Playgroud)

顶点着色器输出的名称必须与片段着色器输入的名称相匹配。由于它们没有,您的片段着色器会看到一个输入值,该值将根据规范未定义

在链接期间不会出错的唯一原因是您i_texCoord以某种条件方式(“动态使用”)在片段着色器中使用。如果您i_texCoord在片段着色器中静态使用,您实际上会收到链接错误。但是,由于编译器/链接器不能排除您永远不会访问该变量,因此根据规范,此代码是允许的,并且不得导致编译错误。但是,如果您实际访问这些值,则它们是未定义的。