OpenGL: Skybox magnified too much
我正在尝试在游戏中实现Skybox。 我正在使用的图像是:
不幸的是,它被极大地放大了,只显示了纹理的几个像素。 看起来像这样:
这是我创建天空盒的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | SkyBox::SkyBox() { programID = LoadShaders("Resources/Shaders/skybox.vert","Resources/Shaders/skybox.frag"); pID = glGetUniformLocation(programID,"P"); vID = glGetUniformLocation(programID,"V"); float points[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW); const char *pth ="/Users/uonibr/Documents/Programming/Space Shooter/Space Shooter/Space Shooter/Resources/space.jpg"; createCubeMap(pth, pth, pth, pth, pth, pth); } bool load_cube_map_side (GLuint texture, GLenum side_target, const char* file_name) { glBindTexture (GL_TEXTURE_CUBE_MAP, texture); int x, y; unsigned char* image_data = SOIL_load_image(file_name, &x, &y, 0, SOIL_LOAD_RGBA); if (!image_data) { fprintf (stderr,"ERROR: could not load %s\ ", file_name); return false; } // non-power-of-2 dimensions check if ((x & (x - 1)) != 0 || (y & (y - 1)) != 0) { fprintf ( stderr,"WARNING: image %s is not power-of-2 dimensions\ ", file_name ); } // copy image data into 'target' side of cube map glTexImage2D ( side_target, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data ); free (image_data); return true; } void SkyBox::createCubeMap ( const char* front, const char* back, const char* top, const char* bottom, const char* left,const char* right) { // generate a cube-map texture to hold all the sides glActiveTexture (GL_TEXTURE0); glGenTextures (1, &cubeMap); // load each image and copy into a side of the cube-map texture assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, front)); assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, back)); assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, top)); assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, bottom)); assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, left)); assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_X, right)); // format cube map texture glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } |
这是天空盒的渲染代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | void SkyBox::render(const Camera &camera) const { glDepthMask (GL_FALSE); glUseProgram (programID); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_CUBE_MAP, cubeMap); glUniformMatrix4fv(pID, 1, GL_FALSE, &camera.getProjectionMatrix()[0][0]); glm::mat4 view = camera.getRotationMatrix(); glUniformMatrix4fv(vID, 1, GL_FALSE, &view[0][0]); glEnableVertexAttribArray (0); // 1st attribute buffer : vertices glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer( 0, // attribute. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glBindBuffer(GL_ARRAY_BUFFER, vbo); glDrawArrays (GL_TRIANGLES, 0, 36); glDisableVertexAttribArray(0); glDepthMask (GL_TRUE); glCullFace(GL_BACK); } |
片段着色器很简单:
1 2 3 4 5 6 7 8 9 | #version 330 core in vec3 texcoords; uniform samplerCube cube_texture; out vec4 frag_color; void main () { frag_color = texture (cube_texture, texcoords); } |
顶点着色器也是如此:
1 2 3 4 5 6 7 8 9 10 11 | #version 330 core in vec3 vp; uniform mat4 P, V; out vec3 texcoords; void main () { texcoords = vp; gl_Position = P * V * vec4 (vp, 1.0); } |
编辑:
这是我生成投影矩阵的代码:
1 2 3 4 | glm::mat4 Camera::getProjectionMatrix() const { return glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f); } |
这是我的FoV:
1 | float FoV = 3.14159 * 65. / 180; |
我确定了问题:
当我应该通过度数时,我正在将弧度传递给glm :: perspective()函数。 因此,正如对该问题的评论所述,答案是一个小的FoV