首先,在编译和链接着色器时,应检索错误消息:
GLint status = GL_TRUE;
char error_msg[1024];
GLsizei read;
GLuint vsp = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vsp, 1, &vertShader, nullptr);
glCompileShader(vsp);
glGetShaderiv( vsp, GL_COMPILE_STATUS, &status );
if ( status != GL_TRUE )
{
glGetShaderInfoLog( vsp, 1024, &read, error_msg );
std::cout << "compile error:" << std::endl << error_msg << std::endl;
}
GLuint fsp = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fsp, 1, &fragShader, nullptr);
glCompileShader(fsp);
glGetShaderiv( fsp, GL_COMPILE_STATUS, &status );
if ( status != GL_TRUE )
{
glGetShaderInfoLog( fsp, 1024, &read, error_msg );
std::cout << "compile error:" << std::endl << error_msg << std::endl;
}
GLuint shader_program = glCreateProgram();
glAttachShader(shader_program, fsp);
glAttachShader(shader_program, vsp);
glLinkProgram(shader_program);
glGetProgramiv( shader_program, GL_LINK_STATUS, &status );
if ( status != GL_TRUE )
{
glGetProgramInfoLog( shader_program, 1024, &read, error_msg );
std::cout << "compile error:" << std::endl << error_msg << std::endl;
}
您将收到的第一条错误消息是这样的:
0(1):错误C0205:配置文件“corelayout”无效
0(1):错误C0206:版本行中的令牌“”无效
这是因为你没有写这行的结尾
"\n"
在着色器代码的第一行之后(
"#version 330 core"
).
解决此问题后,您会收到下一条错误消息:
0(2):错误C1008:未定义变量“texture\u坐标”
您必须添加
in
变量
texture_coordinates
到片段着色器。
in vec2 texture_coordinates;
最终代码如下所示:
const char* vertShader =
"#version 330 core\n"
"layout(location = 0) in vec3 vertexPosition_modelspace;"
"layout(location = 1) in vec2 vt;"
"out vec2 texture_coordinates;"
"void main() {"
" texture_coordinates = vt;"
" gl_Position.xyz = vertexPosition_modelspace;"
" gl_Position.w = 1.0;"
"}";
const char* fragShader =
"#version 330 core\n"
"uniform sampler2D basic_texture;"
"out vec4 frag_color;"
"in vec2 texture_coordinates;"
"void main() {"
" vec4 texel = texture(basic_texture, texture_coordinates);"
" frag_color = texel;"
"}";
当然,您必须为顶点属性提供顶点数据
vertexPosition_modelspace
:
GLfloat texcoords[] = {
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
GLfloat vertex[] = {
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f
};
GLuint vert_vbo;
glGenBuffers(1, &vert_vbo);
glBindBuffer(GL_ARRAY_BUFFER, vert_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof( vertex ), vertex, GL_STATIC_DRAW);
GLuint vt_vbo;
glGenBuffers(1, &vt_vbo);
glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof( texcoords ), texcoords, GL_STATIC_DRAW);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vert_vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
最后,当纹理绑定到时,应将纹理单元的索引设置为纹理采样器均匀变量
basic_texture
:
int texture_unit_index = 0;
GLuint tex = 0;
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0 + texture_unit_index );
glBindTexture(GL_TEXTURE_2D, tex);
.....
// to do after glLinkProgram(shader_program);
int tex_sampler_loc = glGetUniformLocation( shader_program, "basic_texture" );
.....
// to do after glUseProgram(shader_program);
glUniform1i( tex_sampler_loc, texture_unit_index );