简体   繁体   English

纹理映射导致纹理的纯色为1像素

[英]Texture mapping results in solid color of 1 pixel from texture

Beforehand, sorry for a lot of posted code. 事先,对于很多已发布的代码,我们深表歉意。 I will try to be as straightforward as possible. 我将尝试变得尽可能简单。

My texture is 4x4 texture image in bmp format (if someone interested here it is -> 我的纹理是bmp格式的4x4纹理图像(如果有人对此感兴趣-> 4x4纹理图像 ). )。 And as a result of mapping i get color of top leftpixel (0.0, 1.0) (i checked it, it is always color of top left pixel) and my triangle color results in color of that pixel, which is white. 作为映射的结果,我得到了左上像素的颜色(0.0,1.0)(我检查了一下,它始终是左上像素的颜色),而我的三角形颜色得到的是该像素的颜色,即白色。 在此处输入图片说明 I tried changing GL_NEAREST to GL_LINEAR in GL_TEXTURE_MAG_FILTER 我尝试在GL_TEXTURE_MAG_FILTER GL_NEAREST更改为GL_LINEAR

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

and i get bottom right pixel (1.0, 0.0), which is some kind of green: 我得到右下像素(1.0,0.0),这是某种绿色: 在此处输入图片说明 I am loading texture using stb_image . 我正在使用stb_image加载纹理。 So in my Texture.cpp : 所以在我的Texture.cpp中

Texture::Texture(const std::string& fileName)
{
    int width, height, numComponents;
    unsigned char* imageData = stbi_load(fileName.c_str(), &width, &height, &numComponents, 4);
    if (imageData == NULL)
    {
        std::cerr << "Error: Texture load failed for texture: " << fileName << std::endl;
    }

    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &_texture);

    glBindTexture(GL_TEXTURE_2D, _texture);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

    stbi_image_free(imageData);
}
Texture::~Texture(void)
{
    glDeleteTextures(1, &_texture);
}

void Texture::Bind(unsigned int unit)
{
    assert(unit >= 0 && unit <= 31);
    glActiveTexture(GL_TEXTURE0 + unit);
    glBindTexture(GL_TEXTURE_2D, _texture);
}

In my vertex shader : 在我的顶点着色器中

#version 150

in vec3 position;
in vec2 texCoord;

out vec2 texCoord0;

void main(void)
{
    texCoord0 = texCoord;
    gl_Position = vec4(position, 1.0);
}

In my fragment shader : 在我的片段着色器中

#version 150

in vec2 textCoord0;
uniform sampler2D texture;

void main(void)
{
    gl_FragColor = texture2D(texture, textCoord0);
}

In my main.cpp 在我的main.cpp中

#include <iostream>
#include <GL/glew.h>
#include "Display.h"
#include "Shader.h"
#include "Mesh.h"
#include "Texture.h"
int main(int argc, char** argv)
{
    Display display(800, 600, " ");
    display.Clear(0.0f, 0.15f, 0.3f, 1.0f);
    Vertex vertices[] = {
                            Vertex(glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec2(0.0f, 0.0f)),
                            Vertex(glm::vec3( 0.0f,  1.0f, 0.0f), glm::vec2(0.5f, 1.0f)),
                            Vertex(glm::vec3( 1.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f))
    };
    Texture texture("./res/a.bmp");
    Shader shader("./res/testShader");
    Mesh mesh(vertices, sizeof(vertices) / sizeof(vertices[0]));
    while (display.IsClosed() != true)
    {
        shader.Bind();
        texture.Bind(0);
        mesh.Draw();
        display.Update();
    }
    return 0;
} 

In Mesh.cpp i am splitting Vertices attributes (glm::vec3 _position and glm::vec2 _texture) into 2 stl vectors and using 2 buffers ("0" - for position of vertex and "1" - for texture) : Mesh.cpp中,我将顶点属性(glm :: vec3 _position和glm :: vec2 _texture)拆分为2个stl向量,并使用2个缓冲区(“ 0”-用于顶点位置,“ 1”-用于纹理):

Mesh::Mesh(Vertex* vertices, unsigned int numVertices, GLenum usage)
{
    _drawCount = numVertices;

    glGenVertexArrays(1, &_vertexArrayObject);

    glBindVertexArray(_vertexArrayObject);

    std::vector<glm::vec3> positions;
    std::vector<glm::vec2> texCoords;

    positions.reserve(numVertices);
    texCoords.reserve(numVertices);

    for (unsigned int i = 0; i < numVertices; ++i)
    {
        positions.push_back(*vertices[i].Position());
        texCoords.push_back(*vertices[i].TexCoord());
    }
    glGenBuffers(NUM_BUFFERS, _vertexArrayBuffers);


    glBindBuffer(GL_ARRAY_BUFFER, _vertexArrayBuffers[POSITION_VB]);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(positions[0]), positions.data(), usage);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);


    glBindBuffer(GL_ARRAY_BUFFER, _vertexArrayBuffers[TEXCOORD_VB]);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(texCoords[0]), texCoords.data(), usage);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);


    glBindVertexArray(0);
}


Mesh::~Mesh(void)
{
    glDeleteVertexArrays(1, &_vertexArrayObject);
}

void Mesh::Draw(GLenum mode)
{
    glBindVertexArray(_vertexArrayObject);
    glDrawArrays(mode, 0, _drawCount);
    glBindVertexArray(0);
}

In Shader.cpp i binded atributes like this: Shader.cpp中,我这样绑定属性:

glBindAttribLocation(_program, 0, "position");
glBindAttribLocation(_program, 1, "texCoord");

----------------------------EDIT--------------------------------- After changing vertex shader to: - - - - - - - - - - - - - - 编辑 - - - - - - - - - - - ------------将顶点着色器更改为:

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;

out vec2 TexCoord;

void main()
{
    gl_Position = vec4(position, 1.0f);
    TexCoord = texCoord;
}

and fragment shader to: 和片段着色器可以:

#version 330 core
in vec2 TexCoord;

out vec4 color;

uniform sampler2D ourTexture;

void main()
{
    color = texture(ourTexture, TexCoord);
}

texture is mapped correctly. 纹理正确映射。

But i still want to know why my first solution doesn't work. 但是我仍然想知道为什么我的第一个解决方案不起作用。

But i still want to know why my first solution doesn't work. 但是我仍然想知道为什么我的第一个解决方案不起作用。

Because you're using 因为你在用

#version 330 core

and texture2D is deprecated since version 130 自版本130不推荐使用 texture2D

The shader compiler should've warned or errored about that. 着色器编译器应该对此进行警告或错误。 Check your shader logs via glGetShaderInfoLog and glGetProgramInfoLog . 通过glGetShaderInfoLogglGetProgramInfoLog检查着色器日志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM