Domanda

Sto avendo difficoltà a raggiungere una consistenza da mappare con la geometria correttamente con OpenGL. In realtà mi sembra di aver anche rotto l'interpolazione del colore che ha usato per funzionare bene. Ho creato un banco di prova in C99 che utilizza SDL, Glee e TERRENO.

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <SDL/SDL.h>
#include <GL/GLee.h>
#include <SOIL/SOIL.h>

static const char *vertex_source = " \
uniform mat4 projection; \
uniform mat4 view_model; \
 \
attribute vec2 vertex; \
attribute vec2 texcoord; \
attribute vec4 colour; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 0, 1); \
    _texcoord = texcoord; \
    gl_FrontColor = colour; \
} ";

static const char *fragment_source = " \
uniform sampler2D sampler0; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_FragColor = texture2D(sampler0, _texcoord) * 0.01 + gl_Color; \
} ";

typedef struct
{
    GLfloat position[2];
    GLfloat texcoord[2];
    GLubyte colour[4];
} Vertex;

static Vertex verts[] = {
        {
            .position = { 1, 1 },
            .texcoord = { 1, 1 },
            .colour = { 255, 0, 0, 255 },
        },
        {
            .position = { -1, 1 },
            .texcoord = { 0, 1 },
            .colour = { 0, 255, 0, 255 },
        },
        {
            .position = { -1, -1 },
            .texcoord = { 0, 0 },
            .colour = { 0, 0, 255, 255 },
        },
        {
            .position = { 1, -1 },
            .texcoord = { 1, 0 },
            .colour = { 255, 255, 0, 255 },
        },
    };

static GLuint vertex, fragment, program, vbo, texture;
static GLint sampler_loc, vertex_loc, texcoord_loc, colour_loc;

static void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_SetVideoMode(800, 800, 0, SDL_OPENGL);

    glClearColor(1, 0, 0, 0);

    glMatrixMode(GL_PROJECTION);
    glOrtho(-1, 1, -1, 1, -1, 1);

    /* Shaders */
    vertex = glCreateShader(GL_VERTEX_SHADER);
    assert(vertex != 0);
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    assert(fragment != 0);

    GLint length = strlen(vertex_source);
    glShaderSource(vertex, 1, &vertex_source, &length);
    length = strlen(fragment_source);
    glShaderSource(fragment, 1, &fragment_source, &length);

    glCompileShader(vertex);
    glCompileShader(fragment);

    program = glCreateProgram();

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);

    sampler_loc = glGetUniformLocation(program, "sampler0");
    vertex_loc = glGetAttribLocation(program, "vertex");
    texcoord_loc = glGetAttribLocation(program, "texcoord");
    colour_loc = glGetAttribLocation(program, "colour");

    /* VBO */
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    /* Texture */
    texture = SOIL_load_OGL_texture("test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
    assert(texture != 0);
}

static void draw()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(program);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(sampler_loc, 0);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glScalef(.5, .5, .5);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, position));
    glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texcoord));
    glVertexAttribPointer(colour_loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), offsetof(Vertex, colour));

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindTexture(GL_TEXTURE_2D, 0);
    glPopMatrix();

    glUseProgram(0);
}

static void shutdown()
{
    SDL_Quit();
}

int main()
{
    init();
    atexit(shutdown);

    while(true)
    {
        static SDL_Event event;
        while(SDL_PollEvent(&event)) 
        {
            switch(event.type) 
            {
                case SDL_QUIT:
                    exit(0);
                    break;

                default:
                    break;
            }
        }

        draw();

        SDL_GL_SwapBuffers();

        if(glGetError() != GL_NO_ERROR)
        {
            printf("Error\n");
            exit(1);
        }
    }

    return 0;
}

L'unica cosa che rende è un quadrato blu chiaro sulla parte superiore del glClearColor.

Qualsiasi aiuto molto apprezzato.

Grazie per le risposte, ho allegato il codice fissato per completezza.

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <SDL/SDL.h>
#include <GL/GLee.h>
#include <SOIL/SOIL.h>

static const char *vertex_source = " \
uniform mat4 projection; \
uniform mat4 view_model; \
 \
attribute vec2 vertex; \
attribute vec2 texcoord; \
attribute vec4 colour; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 0, 1); \
    _texcoord = texcoord; \
    gl_FrontColor = colour; \
} ";

static const char *fragment_source = " \
uniform sampler2D sampler0; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_FragColor = texture2D(sampler0, _texcoord) + gl_Color; \
} ";

typedef struct
{
    GLfloat position[2];
    GLfloat texcoord[2];
    GLubyte colour[4];
} Vertex;

static Vertex verts[] = {
        {
            .position = { 1, 1 },
            .texcoord = { 1, 1 },
            .colour = { 255, 0, 0, 255 },
        },
        {
            .position = { -1, 1 },
            .texcoord = { 0, 1 },
            .colour = { 0, 255, 0, 255 },
        },
        {
            .position = { -1, -1 },
            .texcoord = { 0, 0 },
            .colour = { 0, 0, 255, 255 },
        },
        {
            .position = { 1, -1 },
            .texcoord = { 1, 0 },
            .colour = { 255, 255, 0, 255 },
        },
    };

static GLuint vertex, fragment, program, vbo, texture;
static GLint sampler_loc, vertex_loc, texcoord_loc, colour_loc;

static void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_SetVideoMode(800, 800, 0, SDL_OPENGL);

    glClearColor(1, 0, 0, 0);

    glMatrixMode(GL_PROJECTION);
    glOrtho(-1, 1, -1, 1, -1, 1);

    /* Shaders */
    vertex = glCreateShader(GL_VERTEX_SHADER);
    assert(vertex != 0);
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    assert(fragment != 0);

    GLint length = strlen(vertex_source);
    glShaderSource(vertex, 1, &vertex_source, &length);
    length = strlen(fragment_source);
    glShaderSource(fragment, 1, &fragment_source, &length);

    glCompileShader(vertex);
    glCompileShader(fragment);

    program = glCreateProgram();

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);

    sampler_loc = glGetUniformLocation(program, "sampler0");
    vertex_loc = glGetAttribLocation(program, "vertex");
    texcoord_loc = glGetAttribLocation(program, "texcoord");
    colour_loc = glGetAttribLocation(program, "colour");

    glUseProgram(program);
    glUniform1i(sampler_loc, 0);
    glUseProgram(0);

    /* VBO */
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts[0], GL_STATIC_DRAW);
    glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, position));
    glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texcoord));
    glVertexAttribPointer(colour_loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), offsetof(Vertex, colour));

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    /* Texture */
    texture = SOIL_load_OGL_texture("test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
    assert(texture != 0);
}

static void draw()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(program);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glScalef(.5, .5, .5);

    glEnableVertexAttribArray(vertex_loc);
    glEnableVertexAttribArray(texcoord_loc);
    glEnableVertexAttribArray(colour_loc);

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableVertexAttribArray(vertex_loc);
    glDisableVertexAttribArray(texcoord_loc);
    glDisableVertexAttribArray(colour_loc);

    glBindTexture(GL_TEXTURE_2D, 0);
    glPopMatrix();

    glUseProgram(0);
}

static void shutdown()
{
    SDL_Quit();
}

int main()
{
    init();
    atexit(shutdown);

    while(true)
    {
        static SDL_Event event;
        while(SDL_PollEvent(&event)) 
        {
            switch(event.type) 
            {
                case SDL_QUIT:
                    exit(0);
                    break;

                default:
                    break;
            }
        }

        draw();

        SDL_GL_SwapBuffers();

        if(glGetError() != GL_NO_ERROR)
        {
            printf("Error\n");
            exit(1);
        }
    }

    return 0;
}
È stato utile?

Soluzione

Non stai permettendo correttamente le matrici vertice Attrib.

  • si attiva 0, che non può essere anche qualcosa che si usa (o meglio, in pratica, è probabilmente vertex_loc, ma non si dovrebbe fare affidamento su di esso)
  • si ignora gli altri 2 array

Provare quanto segue:

glEnableVertexAttribArray(vertex_loc);
glEnableVertexAttribArray(texcoord_loc);
glEnableVertexAttribArray(colour_loc);

Modifica per aggiungere: tanto vale precisare altri dettagli:

  • mi piacerebbe impostare la posizione campionatore solo una volta. impostazione tende a forzare lavoro supplementare nel driver, e dato che verrà imposta solo alla stessa unità di consistenza ogni volta, si potrebbe anche farlo a initilization.

  • Il luogo si chiama glBindBuffer(GL_ARRAY_BUFFER, 0) non è sbagliato, ma mi piacerebbe metterlo subito dopo il VertexAttribPointer chiama. Il buffer attualmente legato è in realtà solo un argomento in più per quelle chiamate ... E non influenza i glDrawArrays definirsi.

Altri suggerimenti

Il tuo Shader comprende la sottoespressione

texture2D(sampler0, _texcoord) * 0.01

Il che renderebbe la vostra struttura essenzialmente invisibile sulla maggior parte dei display, non è vero?

AFAIK è necessario utilizzare glClientActiveTexture () prima vincolante una texture per un VBO.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top