OpenGL вообще ничего не рендерит

0

Моя программа ничего не отображает на экране. Я пробовал несколько вещей, но ничего не получилось.

Здесь мой исходный, вершинный и фрагментарный шейдер:

Renderer.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 из своего класса Game следующим образом:

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 %s\n", 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 %s\n", vertPath );
        return;
    }

    std::string fsCode = "";
    std::ifstream fsStream( fragPath, std::ios::in );

    fprintf( stdout, "loading fragment shader %s\n", 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 %s\n", fragPath );
        return;
    }

    fprintf( stdout, "Compiling vertexShader %s\n", 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, "%s\n", &errorMsg[ 0 ] );
    }

    fprintf( stdout, "Compiling fragmentShader %s\n", 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, "%s\n", &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, "%s\n", &errorMsg[ 0 ] );
    }

    glDeleteShader( vertShader );
    glDeleteShader( fragShader );

    this->programID = tmpProgID;
}

Поэтому я в основном прошу вас проверить мой код, чтобы увидеть, совершила ли я (глупую) ошибку.

  • 0
    По крайней мере, показывает белый экран? Какой выход вы получаете? Вы пытались проверить ваши логи шейдеров, чтобы убедиться, что они загружаются?
  • 0
    да, они загружаются так, как должны. Я получаю прозрачный фоновый экран
Показать ещё 5 комментариев
Теги:
opengl

1 ответ

0
Лучший ответ

Решено! - WinW и winH переменные не были инициализированы при вызове конструктора. Мне также пришлось сменить glDrawElements(...) на glDrawArrays(...)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню