OpenGL纹理不呈现
OpenGL Texture not rendering
我目前正在尝试学习OpenGL。我已经成功地将Rainbow Triangles渲染到了屏幕上,并且成功地将它们移到了屏幕上。但是,我似乎无法正确地呈现两个三角形的纹理。
每当我运行此程序时,我都会遇到一个黑屏,没有任何渲染。我已经检查了,并且图像文件一定在正确的目录中(否则不会运行!)
define STB_IMAGE_IMPLEMENTATION
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <stb/stb_image.h>
int main()
{
//Initialize glfw
if (!glfwInit())
{
fprintf(stderr, "ERROR: Could not start GLFW3.n");
return 1;
}
//Create the rendering context
GLFWwindow* window = glfwCreateWindow(480, 600, "Hello Rendering",
nullptr, nullptr);
if(!window)
{
fprintf(stderr, "ERROR: Could not create a rendering context with "
"GLFW3.n");
return 1;
}
glfwMakeContextCurrent(window);
//Start GLEW
glewExperimental=GL_TRUE;
GLenum err=glewInit();
if(err!=GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
std::cout<<"glewInit failed, aborting."<<std::endl;
}
////////////////////////
//Loading PNG
////////////////////////
int x = 0;
int y = 0;
int n = 0;
int force_channels = 4;
unsigned char* image_data = stbi_load("spooky.png", &x, &y, &n,
force_channels);
if(!image_data)
{
fprintf(stderr, "ERROR: Could not load spooky.pngn.");
return 1;
}
//NPOT Check
if((x & (x - 1)) != 0 || (y & (y - 1)) != 0)
{
fprintf(stderr, "ERROR: Image is not a power of 2.n");
fprintf(stderr, "h: %d w: %d", y, x);
return 1;
}
//Flip the image
int width_in_bytes = x * 4;
unsigned char* top = nullptr;
unsigned char* bottom = nullptr;
unsigned char temp = 0;
int half_height = y / 2;
for(int row = 0; row < half_height; row++)
{
top = image_data + row * width_in_bytes;
bottom = image_data + (y - row - 1) * width_in_bytes;
for(int col = 0; col < width_in_bytes; col++)
{
temp = *top;
*top = *bottom;
*bottom = temp;
top++;
bottom++;
}
}
GLuint tex = 0;
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//////////////////////////////////
//Vertex shader
//////////////////////////////////
const char* vertShader =
"#version 330 core"
"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;"
"}";
///////////////////////////////////
//Frag shader
///////////////////////////////////
const char* fragShader =
"#version 330 core"
"uniform sampler2D basic_texture;"
"out vec4 frag_color;"
"void main() {"
" vec4 texel = texture(basic_texture, texture_coordinates);"
" frag_color = texel;"
"}";
////////////////////////////////////
//Create shader program
///////////////////////////////////
GLuint vsp = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vsp, 1, &vertShader, nullptr);
glCompileShader(vsp);
GLuint fsp = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fsp, 1, &fragShader, nullptr);
glCompileShader(fsp);
GLuint shader_program = glCreateProgram();
glAttachShader(shader_program, fsp);
glAttachShader(shader_program, vsp);
glLinkProgram(shader_program);
glUseProgram(shader_program);
////////////////////////////////////
//Texture coordinates
////////////////////////////////////
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
};
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, vt_vbo);
int dimensions = 2;
glVertexAttribPointer(1, dimensions, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Use the shader
glUseProgram(shader_program);
//Draw the two triangles (6 points)
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwPollEvents();
glfwSwapBuffers(window);
if(GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE))
{
glfwSetWindowShouldClose(window, 1);
}
}
std::cout << "Hello, World!" << std::endl;
return 0;
}
首先,您在编译和链接着色器时应该检索错误消息:
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:无效令牌"版本行
这是因为您没有在着色器代码的第一行("#version 330 core"
)之后编写结局"n"
。
修复此操作时,您将获得下一个错误消息:
0(2):错误c1008:未定义的变量" texture_coordinates"
您必须将in
变量texture_coordinates
的声明添加到片段着色器中。
in vec2 texture_coordinates;
最终代码看起来像这样:
const char* vertShader =
"#version 330 coren"
"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 coren"
"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 );
相关文章:
- OpenGL大的3D纹理(>2GB)非常慢
- OpenGL将纹理四边形渲染为(0,0)
- OpenGL 4.3 错误地将第 4 个纹理坐标映射到与第 3 个纹理坐标相同的位置
- Qt OpenGL 渲染到纹理性能问题
- 使用 C++在 OpenGL 中对 3D 多边形进行纹理处理
- 无法获取要在 OpenGL ES2 中显示的 RGB 纹理
- 在 OpenGL 中加载纹理C++
- 添加新纹理OpenGL时,模型消失了
- 初始化多个纹理 OpenGL、SDL C++ 时出现问题
- 将多个纹理 OpenGL 绑定到不同的四边形
- 如何加载纹理Opengl
- 读写一个纹理(OpenGL)
- 渲染时加载纹理 (OpenGL)
- 如何绑定纹理openGL的一部分
- 将两个图像堆栈的非电源加载到 3D 纹理 OpenGL C++
- 我的精灵在纹理opengl之间切换
- 使用深度纹理OpenGL/GLSL的深度遮挡(3.3/330)
- 加载多纹理opengl 2.0
- 将位置写入纹理OpenGL/GLSL
- 为纹理OpenGL C++加载多个.bmp文件时出现问题