2017-11-25 104 views
1

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

这是我试图提取

质地和这是结果,当我运行程序

enter image description here

我通过编辑纹理试验在左下方(原点)有一些蓝色,并且它是这样出来的

enter image description here

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

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

主循环

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

我真的一直试图解决这个问题,我不知道。如果任何人都能弄清楚为什么它用一种颜色而不是纹理渲染,那将会非常感激。

回答

2

你不使用你texcoords:

这是我的顶点着色器

[...] 
out vec2 o_texCoord; 

我的片段着色器

[...] 
in vec2 i_texCoord; 

你的顶点着色器输出的名称必须匹配你的frag的渲染着色器输入。由于他们不这样做,你的片段着色器会看到一个输入值,根据规范,它将只是undefined

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

+0

哦,我的天啊,你完全正确,谢谢!直到现在,我还不知道顶点和片段必须是相同的名称。 –