【问题标题】:OpenGL Texture drawing as one colorOpenGL纹理绘制为一种颜色
【发布时间】:2018-05-09 09:28:24
【问题描述】:

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

这是我正在尝试绘制的纹理

这是我运行程序时的结果

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

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

这是我的代码相关部分的一些点点滴滴:

在主循环之前启用事物

glClearColor(0, 0, 0, 1);

glEnable(GL_BLEND);
glEnable(GL_TEXTURE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

加载着色器

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);

加载纹理

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);

顶点结构

struct Vertex
{
    Vector2 position;
    Vector2 texCoord;
};

生成顶点数组

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));

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

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);

这是我的顶点着色器

#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);
}

还有我的片段着色器

#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);
}

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

【问题讨论】:

    标签: c++ opengl glsl sdl-2


    【解决方案1】:

    你没有使用你的 texcoords:

    这是我的顶点着色器

    [...]
    out vec2 o_texCoord;
    

    还有我的片段着色器

    [...]
    in vec2 i_texCoord;
    

    顶点着色器输出的名称​​必须匹配片段着色器输入的名称。由于它们没有,因此您的片段着色器会看到一个输入值,根据规范,该值将只是 undefined

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

    【讨论】:

    • 天哪,你说得对,谢谢!直到现在我才知道顶点输出和片段输入必须是相同的名称。
    猜你喜欢
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多