OpenGL根本不渲染任何东西

OpenGL not rendering anything at all

本文关键字:任何东 OpenGL      更新时间:2023-10-16

我的程序在屏幕上不显示任何内容。我已经尝试了几件事,但没有任何效果。

这是我的源代码、顶点和片段着色器:

渲染器.cpp:

#include "Renderer.h"
Renderer::Renderer( Camera& camera, float w, float h )
    :
cam( camera ),
winW( w ),
winH( h )
{}
Renderer::~Renderer()
{
    glDeleteBuffers( 1, &quad );
    glDeleteBuffers( 1, &color );
    glDeleteBuffers( 1, &UV );
    glDeleteVertexArrays( 1, &vao );
}
void Renderer::load()
{
    projectionMatrix = glm::mat4( 1.0f );
    projectionMatrix = glm::perspective<float>( 45.0f, (float) winW / (float) winH, 0.01f, 100.0f );
    shader.loadAndCompile( "Res/Shaders/std.vs", "Res/Shaders/std.fs" );
    texture.loadTexture( "Res/Tex/sheet.png" );
    texture.bind();
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );
    Vertex quadArray[] = {
        { -0.5, -0.5, 0.0 },
        { -0.5, 0.5, 0.0 },
        { 0.5, -0.5, 0.0 },
        { 0.5, -0.5, 0.0 },
        { 0.5, 0.5, 0.0 },
        { -0.5, 0.5, 0.0 }
    };
    glUseProgram( shader.getProgram() );
    MVPLocation = glGetUniformLocation( shader.getProgram(), "MVP" );
    glGenBuffers( 1, &quad );
    glBindBuffer( GL_ARRAY_BUFFER, quad );
    glBufferData( GL_ARRAY_BUFFER, sizeof( quadArray ), quadArray, GL_STATIC_DRAW );
    glGenBuffers( 1, &color );
    glBindBuffer( GL_ARRAY_BUFFER, color );
    glBufferData( GL_ARRAY_BUFFER, 48, NULL, GL_STREAM_DRAW );
    glGenBuffers( 1, &UV );
    glBindBuffer( GL_ARRAY_BUFFER, UV );
    glBufferData( GL_ARRAY_BUFFER, 48, NULL, GL_STREAM_DRAW );
}
void Renderer::translate( glm::vec3 pos )
{
    this->transMatrix = glm::translate( glm::mat4( 1.0f ), pos );
}
void Renderer::translate( float x, float y, float z )
{
    translate( glm::vec3( x, y, z ) );
}
void Renderer::rotate( float angle, glm::vec3 axis )
{
    this->rotationMatrix = glm::rotate( glm::mat4( 1.0f ), angle, axis );
}
void Renderer::scale( glm::vec3 scale )
{
    this->scaleMatrix = glm::scale( glm::mat4( 1.0f ), scale );
}
void Renderer::scale( float x, float y, float z )
{
    scale( glm::vec3( x, y, z ) );
}
void Renderer::drawSpriteBillboarded( glm::vec3 pos, glm::vec3 lookAtPos, int w, int h, int uP, int vP, glm::vec4 col )
{
    int texW = texture.getWidth(), texH = texture.getHeight();
    float u = (float) uP / (float) texW, v = (float) vP / (float) texH, uEnd = (float) ( uP + w ) / (float) texW, vEnd = (float) ( vP + h ) / (float) texH;
    Color colArray[] = {
        { col.r, col.g, col.b, col.a },
        { col.r, col.g, col.b, col.a },
        { col.r, col.g, col.b, col.a },
        { col.r, col.g, col.b, col.a },
        { col.r, col.g, col.b, col.a },
        { col.r, col.g, col.b, col.a }
    };
    Vertex uvArray[] = {
        { u, v },
        { u, vEnd },
        { uEnd, v },
        { uEnd, v },
        { uEnd, vEnd },
        { u, vEnd }
    };
    translate( pos );
    
    glm::vec2 dist = glm::vec2( lookAtPos.x, lookAtPos.z ) - glm::vec2( pos.x, pos.z );
    rotate( atan2f( dist.y, dist.x ), glm::vec3( 0, 1, 0 ) );
    scale( w / 16 * 1.0, h / 16 * 1.0, 1.0 );
    modelMatrix = transMatrix * rotationMatrix * scaleMatrix;
    
    camTransMatrix = glm::translate( glm::mat4( 1.0f ), cam.getPos() );
    camRotationMatrix = glm::rotate( camRotationMatrix, cam.getRotX(), glm::vec3( 1, 0, 0 ) );
    camRotationMatrix = glm::rotate( camRotationMatrix, cam.getRotY(), glm::vec3( 0, 1, 0 ) );
    camRotationMatrix = glm::rotate( camRotationMatrix, cam.getRotZ(), glm::vec3( 0, 0, 1 ) );
    viewMatrix = camTransMatrix * camRotationMatrix;
    
    modelViewProjectionMatrix = projectionMatrix * viewMatrix * modelMatrix;
    glUniformMatrix4fv( MVPLocation, 1, GL_FALSE, &modelViewProjectionMatrix[ 0 ][ 0 ] );
    glBindBuffer( GL_ARRAY_BUFFER, quad );
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0 );
    glBindBuffer( GL_ARRAY_BUFFER, color );
    glBufferData( GL_ARRAY_BUFFER, sizeof( colArray ), colArray, GL_STREAM_DRAW );
    glEnableVertexAttribArray( 1 );
    glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0 );
    
    glBindBuffer( GL_ARRAY_BUFFER, UV );
    glBufferData( GL_ARRAY_BUFFER, sizeof( uvArray ), uvArray, GL_STREAM_DRAW );
    glEnableVertexAttribArray( 2 );
    glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
    glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0 );
}
void Renderer::drawSprite( glm::vec3 pos, int w, int h, int uP, int vP, glm::vec4 col )
{}

顶点着色器

#version 330 core
layout(location = 0) in vec3 vertPosition;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 in_UV;
uniform mat4 MVP;
out vec4 col;
out vec2 uv;
void main(void)
{
    gl_Position = MVP * vec4(vertPosition, 1.0);
    col = color;
    uv = in_UV;
}

片段着色器

#version 330 core
in vec4 col;
in vec2 uv;
out vec4 color;
uniform sampler2D tex;
void main(void)
{
    vec4 Color = texture2D( tex, uv ) * col;
    color = Color;
}

我从我的游戏类中调用drawSpriteBillboarded函数,如下所示:

drawSpriteBillboarded( glm::vec3( 0, 0, -5 ), cam.getPos(), 16, 16, 0, 0, glm::vec3( 255, 255, 255, 255 ) );

相机的位置为

0, 0, 0

我尝试将顶点着色器更改为不乘以 MVP 矩阵,并且还尝试将片段着色器更改为:

#version 330 core
in vec4 col;
in vec2 uv;
out vec4 color;
void main(void)
{
    color = vec4(1.0, 1.0, 1.0, 1.0);
}

但它也没有显示任何东西。我也尝试将GL_TRIANGLES更改为GL_POINTS,但什么都没有。

编辑

我还添加了 loadAndCompile() 函数:

void Shader::loadAndCompile( const char* vertPath, const char* fragPath )
{
    std::string vsCode = "";
    std::ifstream vsStream( vertPath, std::ios::in );
    fprintf( stdout, "loading vertex shader %sn", vertPath );
    if( vsStream.is_open() )
    {
        std::string line;
        while( std::getline( vsStream, line ) )
            vsCode += line + 'n';
        vsStream.close();
    }
    else
    {
        fprintf( stderr, "Error: could not find vertex shader %sn", vertPath );
        return;
    }
    std::string fsCode = "";
    std::ifstream fsStream( fragPath, std::ios::in );
    fprintf( stdout, "loading fragment shader %sn", fragPath );
    if( fsStream.is_open() )
    {
        std::string line;
        while( std::getline( fsStream, line ) )
            fsCode += line + 'n';
        fsStream.close();
    }
    else
    {
        fprintf( stderr, "Error: could not find fragment shader %sn", fragPath );
        return;
    }
    fprintf( stdout, "Compiling vertexShader %sn", vertPath );
    const char* vertCode = vsCode.c_str();
    GLuint vertShader = glCreateShader( GL_VERTEX_SHADER );
    
    glShaderSource( vertShader, 1, &vertCode, NULL );
    glCompileShader( vertShader );
    
    GLint result = GL_FALSE;
    int infoLogLength;
    glGetShaderiv( vertShader, GL_COMPILE_STATUS, &result );
    glGetShaderiv( vertShader, GL_INFO_LOG_LENGTH, &infoLogLength );
    if( infoLogLength > 0 )
    {
        std::vector< char > errorMsg( infoLogLength );
        glGetShaderInfoLog( vertShader, infoLogLength, NULL, &errorMsg[ 0 ] );
        fprintf( stderr, "%sn", &errorMsg[ 0 ] );
    }
    fprintf( stdout, "Compiling fragmentShader %sn", fragPath );
    const char* fragCode = fsCode.c_str();
    GLuint fragShader = glCreateShader( GL_FRAGMENT_SHADER );
    
    glShaderSource( fragShader, 1, &fragCode, NULL );
    glCompileShader( fragShader );
    
    glGetShaderiv( fragShader, GL_COMPILE_STATUS, &result );
    glGetShaderiv( fragShader, GL_INFO_LOG_LENGTH, &infoLogLength );
    if( infoLogLength > 0 )
    {
        std::vector< char > errorMsg( infoLogLength );
        glGetShaderInfoLog( fragShader, infoLogLength, NULL, &errorMsg[ 0 ] );
        fprintf( stderr, "%sn", &errorMsg[ 0 ] );
    }
    fprintf( stdout, "Linking program...n" );
    GLuint tmpProgID = glCreateProgram();
    glAttachShader( tmpProgID, vertShader );
    glAttachShader( tmpProgID, fragShader );
    glLinkProgram( tmpProgID );
    glGetProgramiv( tmpProgID, GL_LINK_STATUS, &result );
    glGetProgramiv( tmpProgID, GL_INFO_LOG_LENGTH, &infoLogLength );
    if( infoLogLength > 0 )
    {
        std::vector< char > errorMsg( infoLogLength );
        glGetProgramInfoLog( tmpProgID, infoLogLength, NULL, &errorMsg[ 0 ] );
        fprintf( stderr, "%sn", &errorMsg[ 0 ] );
    }
    glDeleteShader( vertShader );
    glDeleteShader( fragShader );
    this->programID = tmpProgID;
}

所以我基本上要求你检查我的代码,看看我是否犯了一个(愚蠢的)错误。

解决了! - 调用构造函数时未初始化 winW 和 winH 变量。我还必须将glDrawElements(...)更改为glDrawArrays(...)