gpt4 book ai didi

c++ - Open_GL 中的透视问题

转载 作者:行者123 更新时间:2023-11-28 04:47:23 27 4
gpt4 key购买 nike

有人可以解释一下我的代码有什么问题吗?当我尝试运行它时,我得到一个黑色窗口,但如果我没有像在第 31 行中那样设置透视矩阵,我会在窗口上绘制正确的实体(金字塔)。这是代码的主要部分。在顶点着色器中,我只是将模型、 View 和投影定义为统一的 4x4 矩阵,并将它们乘以顶点的位置,并将顶点的颜色传递给片段着色器。我认为问题不在这些文件中,但如果您需要它们,我会发布它们。

#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <string>
#include <fstream>
#include <sstream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;

GLuint IBO, VBO, gModelLocation, gViewLocation, gProjectionLocation;

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

const char* VSfileName = "vertex.vs";
const char* FSfileName = "fragment.fs";

void RenderSceneCB()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glm::mat4 model;
model = glm::rotate( model, 0.0f, glm::normalize( glm::vec3( 1.0, 0.0, 0.0 ) ) );

glm::mat4 view;
view = glm::translate( view, glm::vec3( 0.0f, 0.0f, 0.0f ) );

glm::mat4 projection;
projection = glm::perspective( 90.0f, float( WINDOW_WIDTH ) / float( WINDOW_HEIGHT ), 0.1f, 100.0f );

glUniformMatrix4fv( gModelLocation, 1, GL_FALSE, &model[ 0 ][ 0 ] );
glUniformMatrix4fv( gViewLocation, 1, GL_FALSE, &view[ 0 ][ 0 ] );
glUniformMatrix4fv( gProjectionLocation, 1, GL_FALSE, glm::value_ptr( projection ) );

glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IBO );

glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 0 );

glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)( 15 * sizeof( GLfloat ) ) );
glEnableVertexAttribArray( 1 );

glDrawElements( GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0 );
//glDrawArrays(GL_TRIANGLES, 0, 3);

glDisableVertexAttribArray( 1 );
glDisableVertexAttribArray( 0 );

glutSwapBuffers();
}

void InizializeGlutCallBacks()
{
glutDisplayFunc( RenderSceneCB );
glutIdleFunc( RenderSceneCB );
}

void InizializeVertices()
{
GLfloat Vertices[ 9 ][ 3 ]
{
{ -0.5f, 0.5f, 0.0f},
{ 0.5f, -0.5f, 0.0f },
{ 0.5f, 0.5f, 0.0f},
{ -0.5f, -0.5f, 0.0f },
{ 0.0f, 0.0f, 1.0f},
{ 1.0f, 0.0f, 0.0f},
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f}
};
GLint Indices[ 12 ]
{
0,2,4,0,3,4,1,2,4,1,3,4
};

glGenBuffers( 1, &VBO );
glGenBuffers( 1, &IBO );

glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IBO );

glBufferData( GL_ARRAY_BUFFER, sizeof( Vertices ), Vertices, GL_STATIC_DRAW );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( Indices ), Indices, GL_STATIC_DRAW );

}

void AddShader( GLuint ShaderProgram, const char* ShaderSource, GLenum ShaderType )
{

GLuint ShaderObj = glCreateShader( ShaderType );
if( ShaderObj == 0 )
{
fprintf( stderr, "Error creating Shader Object %d \n", ShaderType );
}

const GLchar* p[ 1 ];
p[ 0 ] = ShaderSource;

GLint Lengths[ 1 ];
Lengths[ 0 ] = strlen( p[ 0 ] );

glShaderSource( ShaderObj, 1, p, Lengths );

glCompileShader( ShaderObj );
GLint success;
glGetShaderiv( ShaderObj, GL_COMPILE_STATUS, &success );
if( !success )
{
GLchar InfoLog[ 1024 ];
glGetShaderInfoLog( ShaderObj, 1024, NULL, InfoLog );
fprintf( stderr, "Error Compiling Shader %d: '%s' \n", ShaderType, InfoLog );
}

glAttachShader( ShaderProgram, ShaderObj );
}

void CompileShaders()
{
GLuint ShaderProgram = glCreateProgram();
if( ShaderProgram == 0 )
{
fprintf( stderr, "Error creating Shader Program \n" );
}

string vs, fs;

ifstream VertexFile;
ifstream FragmentFile;

VertexFile.open( VSfileName );
if( !VertexFile )
{
std::cout << "Error in opening vertex.vs \n";
exit( 1 );
}
FragmentFile.open( FSfileName );
if( !FragmentFile )
{
std::cout << "Error in opening fragment.fs \n";
exit( 1 );
}

stringstream VertexStream;
stringstream FragmentStream;

VertexStream << VertexFile.rdbuf();
FragmentStream << FragmentFile.rdbuf();

vs = VertexStream.str();
fs = FragmentStream.str();

AddShader( ShaderProgram, vs.c_str(), GL_VERTEX_SHADER );
AddShader( ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER );

glLinkProgram( ShaderProgram );
GLint success;
glGetProgramiv( ShaderProgram, GL_LINK_STATUS, &success );
if( !success )
{
GLchar InfoLog[ 1024 ];
glGetProgramInfoLog( ShaderProgram, 1024, NULL, InfoLog );
fprintf( stderr, "Error in linking Shader '%s' \n", InfoLog );
}

glValidateProgram( ShaderProgram );
glGetProgramiv( ShaderProgram, GL_VALIDATE_STATUS, &success );
if( !success )
{
GLchar InfoLog[ 1024 ];
glGetProgramInfoLog( ShaderProgram, 1024, NULL, InfoLog );
fprintf( stderr, "Error in linking Shader '%s' \n", InfoLog );
}

//gScaleLocation = glGetUniformLocation(ShaderProgram, "gScale");
gModelLocation = glGetUniformLocation( ShaderProgram, "gModel" );
gViewLocation = glGetUniformLocation( ShaderProgram, "gView" );
gProjectionLocation = glGetUniformLocation( ShaderProgram, "gProjection" );
glUseProgram( ShaderProgram );
}

int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );
glutInitWindowSize( WINDOW_WIDTH, WINDOW_HEIGHT );
glutInitWindowPosition( 100, 100 );
glutCreateWindow( "Hello World" );

InizializeGlutCallBacks();

glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );

GLenum res = glewInit();
if( res != GLEW_OK )
{
std::cout << "Error, check please \n";
}

glViewport( 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT );

glEnable( GL_DEPTH_TEST );

// enable alpha support
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

InizializeVertices();

CompileShaders();

glutMainLoop();

system( "pause" );

return 0;
}

最佳答案

首先你应该初始化所有的矩阵(见 glm returning nan on simple translate ):

glm::mat4 model(1.0f);
glm::mat4 view(1.0f);
glm::mat4 projection(1.0f);

几何体必须在裁剪空间中。当您设置投影时,您可以定义 0.1 的近平面和 100.0 的远平面。这两个值定义近和远裁剪平面。
这意味着您只能“看到”Z 分量在 [0.1, 100.0] 范围内的几何图形。

设置 View 矩阵,解决您的问题。

glm::mat4 view(1.0f);
view = glm::translate( view, glm::vec3( 0.0f, 0.0f, -1.0f ) );


更远:查看GLM glm::perspective , version 0.9.8 的文档:

LM_FUNC_DECL tmat4x4<T, defaultp> glm::perspective(T fovy, T aspect, T near, T far)

Creates a matrix for a symetric perspective-view frustum based on the default handedness.

Parameters
fovy Specifies the field of view angle in the y direction. Expressed in radians.

版本 0.9.4 ( glm::perspective , version 0.9.4 ) 在同一位置注明:

fovy Expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.


这是因为一般的 GLM 在不久前从度数更改为弧度。

像这样设置透视投影矩阵:

projection = glm::perspective(
90.0f * (float)M_PI / 180.0,
float( WINDOW_WIDTH ) / float( WINDOW_HEIGHT ),
0.1f, 100.0f );



解释:

View 矩阵描述了观察场景的方向和位置。 View 矩阵从世界空间转换到 View (眼睛)空间。

投影矩阵描述了从场景的 3D 点到视口(viewport)的 2D 点的映射。它从眼睛空间转换到剪辑空间,剪辑空间中的坐标通过除以w转换为归一化设备坐标(NDC)。剪辑坐标的组成部分。 NDC 的范围为 (-1,-1,-1) 到 (1,1,1)。
裁剪空间之外的每个几何图形。

在透视投影中,投影矩阵描述了从针孔相机看到的世界中的 3D 点到视口(viewport)的 2D 点的映射。
相机平截头体(截棱锥)中的眼空间坐标映射到立方体(归一化设备坐标)。

enter image description here

关于c++ - Open_GL 中的透视问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48998335/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com