问题描述
我正在使用跨平台库(glfw,glew,glm)制作简单的纹理映射OpenGl示例程序.它只是从我的计算机上获取一个512 x 512 PNG的图像,并且应该将其映射到我要显示的正方形.没有纹理映射的程序效果很好,并且正方形可见.使用纹理映射看不到东西",您能帮我找到错误的地方吗?
I'm using cross-platform libraries (glfw, glew, glm) to make a simple texture mapping OpenGl Sample Program. It just takes an image from my computer, which is a 512 x 512 PNG, and is supposed to map it to a square I have displaying. The Program without the texture mapping works great and the square is visible. With the texture mapping Nothing is Visible, could you help me find where the mistake is?
也许我在做"到画框"循环中缺少绑定或某些东西?
Perhaps I'm missing a binding or something within my "do" drawing-to-the-frame loop?
主程序(LoadShaders和stbi_Image在外部正确定义)
Main Program (LoadShaders and stbi_Image are externally defined correctly)
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
// Open a window and create its OpenGL context
GLFWwindow* window = glfwCreateWindow (640, 480, "Hello Triangle", NULL, NULL);
if(!window)
{
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are
not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = GL_TRUE; // Needed for core profile
GLenum err = glewInit();
if (err != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return -1;
}
const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string
const GLubyte* version = glGetString (GL_VERSION); // version as a string
printf ("Renderer: %s\n", renderer);
printf ("OpenGL version supported %s\n", version);
// tell GL to only draw onto a pixel if the shape is closer to the viewer
glEnable (GL_DEPTH_TEST); // enable depth-testing
glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer"
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window,GLFW_STICKY_KEYS,GL_TRUE );
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader",
"SimpleFragmentShader.fragmentshader" );
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <->
// 100 units
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Camera matrix
glm::mat4 View = glm::lookAt(
glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up
);
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model;
unsigned char* image_data;
int x, y, n;
char* file_name;
file_name = "/home/syk435/Pictures/texture_sample.png";
int force_channels = 4;
image_data = stbi_load(file_name, &x, &y, &n, force_channels);
if (!image_data)
{
fprintf (stderr, "ERROR: could not load %s\n", file_name);
}
//check if not normal dims
if (x & (x - 1) != 0 || y & (y - 1) != 0)
{
fprintf (stderr, "WARNING: texture %s is not power-of-2 dimensions\n",
file_name);
}
//invert to norm
int width_in_bytes = x * 4;
unsigned char *top = NULL;
unsigned char *bottom = NULL;
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++;
}
}
static const GLfloat g_vertex_buffer_data[] = {
-0.75f,-0.75f,0.0f,
-0.75f, 0.75f,0.0f,
0.75f,-0.75f,0.0f,
0.75f, 0.75f,0.0f,
-0.75f, 0.75f,0.0f,
0.75f,-0.75f,0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data,
GL_STATIC_DRAW);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//texture stuff
unsigned int tex = 0;
glGenTextures (1, &tex);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, tex);
GLuint TextureID = glGetUniformLocation(programID, "basic_texture");
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);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
float texcoords[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
1.0, 0.0
};
unsigned int vt_vbo;
glGenBuffers (1, &vt_vbo);
glBindBuffer (GL_ARRAY_BUFFER, vt_vbo);
int dimensions = 2; // 2d data for texture coords
int length = 6; // 6 vertices
glBufferData (
GL_ARRAY_BUFFER,
dimensions * length * sizeof (float),
texcoords,
GL_STATIC_DRAW
);
do{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );
// Use our shader
glUseProgram(programID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// note: this is your existing VAO
glEnableVertexAttribArray(1);
glBindBuffer (GL_ARRAY_BUFFER, vt_vbo);
// note: I assume that vertex positions are location 0
dimensions = 2; // 2d data for texture coords
glVertexAttribPointer (1, dimensions, GL_FLOAT, GL_FALSE, 0, NULL);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 6); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// Swap buffers
glfwSwapBuffers(window);
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey( window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && window!=NULL );
// Close OpenGL window and terminate GLFW
glfwTerminate();
// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &vt_vbo);
glDeleteProgram(programID);
glDeleteTextures(1, &TextureID);
glDeleteVertexArrays(1, &vao);
return 0;
VertexShader:
VertexShader:
#version 420
// Input vertex data, different for all executions of this shader.
layout (location = 0) in vec3 vertexPosition_modelspace;
layout (location = 1) in vec2 vt; // per-vertex texture co-ords
out vec2 texture_coordinates;
uniform mat4 MVP;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
texture_coordinates = vt;
}
FragmentShader:
FragmentShader:
#version 420
// Ouput data
//texture stuff
in vec2 texture_coordinates;
uniform sampler2D basic_texture;
out vec3 frag_colour;
void main()
{
frag_colour = texture2D(basic_texture, texture_coordinates).rgb;
}
推荐答案
对于那些不想搜索注释的人...
For those who don't want to search the comments...
要么删除这两行(即不启用深度测试).
Either remove these 2 lines (i.e. do not enable depth test).
glEnable (GL_DEPTH_TEST); // enable depth-testing
glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer"
或者启用深度缓冲,在do while循环开始时清除深度缓冲
Or with depth buffer enabled, clear the depth buffer at the start of the do while loop
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
(答案是在安东·科尔曼(Andon Coleman)的问题下方的评论中.我在阅读安东的OpenGL 4教程我想我会进行一些练习,看看是否可以使代码正常工作.执行以上任一操作都可以显示纹理.)
(The answer is in the comment below the question from Andon Coleman. As I'm reading Anton's OpenGL 4 Tutorials I thought I'll practice a bit and see if I could get the code working. Doing either of the above displayed the texture.)
这篇关于OpengGl 4.2纹理映射不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!