2016-05-21 2 views
6

J'essaye de rendre un sprite en utilisant la bibliothèque opengl glsl et glm. quand je rends sprite pipeline existant en utilisant glBegin, glEnd tout va bien, mais quand je l'utilise shaders, après sprite tourner ses tirages de qualité vraiment médiocre que vous pouvez voir sur la photo:Le sprite OpenGL dessine en faible qualité

http://sm.uploads.im/t/I3lpf.png

Mon code de rendu :

GLuint p; 
GLuint vertex_shader, fragment_shader; 
GLuint VBO, VAO; 
glm::mat4 projection_matrix = glm::ortho(0.0F, 640.0F, 480.0F, 0.0F, -1.0F, 1.0F); 

void sprite_init() 
{ 
    p = glCreateProgram(); 

    // LOAD VERTEX SHADER // 
    std::ifstream vf("E:\\vertex.sh"); 
    std::stringstream vs; 
    vs << vf.rdbuf(); 

    std::ifstream ff("E:\\fraqment.sh"); 
    std::stringstream fs; 
    fs << ff.rdbuf(); 

    vertex_shader = glCreateShader(GL_VERTEX_SHADER); 
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 

    char* buffer = new char[vs.str().size() + 1]; 
    memcpy(buffer, vs.str().c_str(), vs.str().size() + 1); 
    glShaderSource(vertex_shader, 1, &buffer, NULL); 
    free(buffer); 

    buffer = new char[fs.str().size() + 1]; 
    memcpy(buffer, fs.str().c_str(), fs.str().size() + 1); 
    glShaderSource(fragment_shader, 1, &buffer, NULL); 
    free(buffer); 

    glCompileShader(vertex_shader); 
    glCompileShader(fragment_shader); 

    glAttachShader(p, vertex_shader); 
    glAttachShader(p, fragment_shader); 
    glLinkProgram(p); 

    GLfloat vertices[] = 
    { 
     // POS // // TEX // 
     0.0F, 1.0F, 0.0F, 1.0F, 
     1.0F, 0.0F, 1.0F, 0.0F, 
     0.0F, 0.0F, 0.0F, 0.0F, 

     0.0F, 1.0F, 0.0F, 1.0F, 
     1.0F, 1.0F, 1.0F, 1.0F, 
     1.0F, 0.0F, 1.0F, 0.0F 
    }; 

    glGenVertexArrays(1, &VAO); 
    glGenBuffers(1, &VBO); 

    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    glBindVertexArray(VAO); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 
} 

void sprite_draw() 
{ 
    glUseProgram(p); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glUniform1i(glGetUniformLocation(p, "image"), 0); 

    // SET MATRIX // 
    glm::vec2 size = glm::vec2(width, height); 
    glm::vec2 position = glm::vec2(pos.x - 0.5F * size.x, pos.y - 0.5F * size.y); 
    glm::vec3 col = glm::vec3(1.0F, 1.0F, 1.0F); 

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

    model_matrix = glm::translate(model_matrix, glm::vec3(0.5F * size.x, 0.5F * size.y, 0.0f)); 
    model_matrix = glm::rotate(model_matrix, glm::radians(rotate), glm::vec3(0.0f, 0.0f, 1.0f)); 
    model_matrix = glm::translate(model_matrix, glm::vec3(-0.5F * size.x, -0.5F * size.y, 0.0f)); 

    model_matrix = glm::scale(model_matrix, glm::vec3(size, 1.0F)); 

    glUniformMatrix4fv(glGetUniformLocation(p, "projection"), 1, GL_FALSE, glm::value_ptr(projection_matrix)); 
    glUniformMatrix4fv(glGetUniformLocation(p, "model"), 1, GL_FALSE, glm::value_ptr(model_matrix)); 
    glUniform3f(glGetUniformLocation(p, "spriteColor"), col.x, col.y, col.z); 

    glBindVertexArray(VAO); 
    glDrawArrays(GL_TRIANGLES, 0, 6); 
    glBindVertexArray(0); 

    glUseProgram(0); 
} 

Vertex Shader:

#version 330 core 
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords> 

out vec2 TexCoords; 

uniform mat4 model; 
uniform mat4 projection; 

void main() 
{ 
    TexCoords = vertex.zw; 
    gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0); 
} 

Fragment Shader:

#version 330 core 
in vec2 TexCoords; 
out vec4 color; 

uniform sampler2D image; 
uniform vec3 spriteColor; 

void main() 
{  
    color = vec4(spriteColor, 1.0) * texture(image, TexCoords); 
} 

configuration Texture:

unsigned int texture; 
glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
this->textures.push_back(texture); 

Merci

+3

Configurez-vous le filtrage de texture, par exemple, LINEAR_MIPMAP_LINEAR et le filtrage anisotrope (omniprésent)? Sinon, vous pourriez bénéficier d'un contexte multi-échantillonnage. –

+2

Forcer alpha à 1.0 dans fs est une mauvaise idée, mais probablement pas votre problème principal – Andreas

+0

@ brett-hale Oui, j'utilise le filtrage de texture GL_NEAREST – Ash

Répondre

2
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

Vous devez utiliser le filtrage GL_LINEAR, pas GL_NEAREST.