簡體   English   中英

向OpenGL立方體添加紋理?

[英]Adding texture to OpenGL cube?

使用VAO和VBO,我想出了以下代碼,該代碼將一堆多維數據集渲染為一個巨大的塊,所有塊均具有相同的設置配色方案:

    #include <math.h>
    #include <time.h>

    #include <stdio.h>
    #include <stdlib.h>

    #include <GL/glew.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>

    #define WIDTH 0x320
    #define HEIGHT 0x258

    #define GLUT_KEY_LSHIFT 112
    #define QUIT 0x11
    #define ESC  0x1B

    typedef char* string;

    typedef struct vertex {

        float x;
        float y;
        float z;
    } Vertex;

    float angle = 0.0;
    float deltaX, deltaY;
    float deltaS, deltaSt;
    float deltaUp;

    float vx, vz, vy;
    float x = 0.0f, y = 0.0f, z = 0.0f;

    float defaultSpeed = 1.0f;
    float speed = 1.0f;

    float lastMousePosY = HEIGHT / 2;
    float lastMousePosX = WIDTH / 2;

    int nFrames;
    double lastTime;

    GLint up, down;
    GLuint vbo0, vbo1, ibo, vao;
    GLint indexAmnt, vertexAmnt, colorAmnt;
    GLint menuId;
    GLenum mode;

    int release;

    int xBlocks = 30;
    int yBlocks = 4;
    int zBlocks = 16;

    void direction(float delta_h, float delta_v)
    {
        angle += delta_h;
        vx = sin(angle);
        vz = -cos(angle);
        vy += sin(delta_v) * cos(delta_v);
    }

    void position(float delta_x, float delta_z)
    {
        x += delta_z * vx * speed;
        z += delta_z * vz * speed;

        x += delta_x * -vz * speed;
        z += delta_x * vx * speed;
    }

    int toRGBA(int r, int g, int b, int a)
    {
        return ((a << 24) | (b << 16) | (g << 8) | r);
    }

    Vertex initVector(float x, float y, float z)
    {
        Vertex v = {.x=x, .y=y, .z=z};
        return v;
    }

    unsigned int initVertexBuffer(Vertex* v)
    {
        unsigned int vbo_v;

        glGenBuffers(1, &vbo_v);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_v);
        glBufferData(GL_ARRAY_BUFFER, vertexAmnt * sizeof(Vertex), v, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        return vbo_v;
    }

    unsigned int initColorBuffer(int* c)
    {
        unsigned int vbo_c;

        glGenBuffers(1, &vbo_c);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_c);
        glBufferData(GL_ARRAY_BUFFER, colorAmnt * sizeof(int), c, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        return vbo_c;
    }

    unsigned int initIndexBuffer(int *i)
    {
        unsigned int ibo_i;

        glGenBuffers(1, &ibo_i);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_i);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexAmnt * sizeof(int), i, GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        return ibo_i;
    }

    void menuActions(int value)
    {
        switch(value)
        {
        case 1:
            mode = GL_LINES;
            break;
        case 0:
            mode = GL_TRIANGLES;
            break;
        default:
            break;
        }
    }

    int createMenu()
    {
        int menu;

        menu = glutCreateMenu(menuActions);
        glutAddMenuEntry("On", 1);
        glutAddMenuEntry("Off", 0);

        return menu;
    }

    unsigned int initVertexArray()
    {
        GLuint vao_a;

        glGenVertexArrays(1, &vao_a);
        glBindVertexArray(vao_a);

        glBindBuffer(GL_ARRAY_BUFFER, vbo1);
        glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(int), 0);
        glEnableClientState(GL_COLOR_ARRAY);

        glBindBuffer(GL_ARRAY_BUFFER, vbo0);
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
        glEnableClientState(GL_VERTEX_ARRAY);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

        glBindVertexArray(0);

        return vao_a;
    }

    void loadgame()
    {
        Vertex vertices[] = {

            initVector(-0.5f, -0.5f, 0.5f),
            initVector(0.5f, -0.5f, 0.5f),
            initVector(0.5f, 0.5f, 0.5f),
            initVector(-0.5f, 0.5f, 0.5f), 
            initVector(-0.5f, -0.5f, -0.5f), 
            initVector(0.5f, -0.5f, -0.5f),
            initVector(0.5f, 0.5f, -0.5f),
            initVector(-0.5f, 0.5f, -0.5f)
        };

        int colors[] = {

            toRGBA(0xff, 0x00, 0x00, 0xff),
            toRGBA(0xff, 0xa5, 0x00, 0xff),
            toRGBA(0xa5, 0x2a, 0x2a, 0xff),
            toRGBA(0x80, 0x00, 0x00, 0xff),
            toRGBA(0x00, 0x00, 0xff, 0xff),
            toRGBA(0x00, 0xff, 0xff, 0xff),
            toRGBA(0x00, 0x80, 0x00, 0xff),
            toRGBA(0xad, 0xff, 0x2f, 0xff)
        };

        int indices[] = {

            0, 1, 2, 2, 3, 0, 
            3, 2, 6, 6, 7, 3, 
            7, 6, 5, 5, 4, 7, 
            4, 0, 3, 3, 7, 4, 
            0, 1, 5, 5, 4, 0,
            1, 5, 6, 6, 2, 1
        };

        vertexAmnt = sizeof(vertices) / sizeof(Vertex);
        colorAmnt = sizeof(colors) / sizeof(int);
        indexAmnt = sizeof(indices) / sizeof(int);

        vbo0 = initVertexBuffer(vertices);
        vbo1 = initColorBuffer(colors);
        ibo = initIndexBuffer(indices);
        vao = initVertexArray();

        mode = GL_TRIANGLES;

        menuId = createMenu();
        glutAttachMenu(GLUT_RIGHT_BUTTON);
        glClearColor(0.6f, 0.6f, 1.0f, 1.0f);

        lastTime = time(NULL);
    }

    void input(int key, int ix, int iy)
    {
        if(key == GLUT_KEY_LSHIFT){ deltaUp = -0.3f; down = 1; }
    }

    void input_r(int key, int ix, int iy)
    {
        if(key == GLUT_KEY_LSHIFT) down = 0;
    }

    void keyboard(unsigned char key, int kx, int ky)
    {
        if(key == QUIT) exit(0);
        if(key == ESC) release = 1;
        if(key == 'w') deltaS = 0.5f;
        if(key == 's') deltaS = -0.5f;
        if(key == 'a') deltaSt = -0.5f;
        if(key == 'd') deltaSt = 0.5f;
        if(key == 'r') speed = defaultSpeed * 5.0;
        if(key == ' '){ deltaUp = 0.3f; up = 1; }
    }

    void keyboard_r(unsigned char key, int kx, int ky)
    {
        if(key == ESC) release = 0;
        if(key == 'w' || key == 's') deltaS = 0.0f;
        if(key == 'a' || key == 'd') deltaSt = 0.0f;
        if(key == ' ') up = 0;
        if(key == 'r') speed = defaultSpeed;
    }

    void resetPointer()
    {
        glutWarpPointer(WIDTH / 2.0, HEIGHT / 2.0);

        lastMousePosY = HEIGHT / 2.0;
        lastMousePosX = WIDTH / 2.0;
    }

    void mouse(int mx, int my)
    {
        if(!release)
        {
            if(fabs(WIDTH / 2 - mx) > 15 ||
                    fabs(HEIGHT / 2 - my) > 15)
                        resetPointer();
            else
            {
                int vMotion = lastMousePosY - my;
                int hMotion = lastMousePosX - mx;

                deltaX = -hMotion / 25.0;
                deltaY = vMotion / 25.0;

                lastMousePosY = my;
                lastMousePosX = mx;
            }
        }
    }

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

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        const double w = glutGet(GLUT_WINDOW_WIDTH);
        const double h = glutGet(GLUT_WINDOW_HEIGHT);

        gluPerspective(45.0, w / h, 0.1, 1000.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        gluLookAt(x, y, z, x + vx, y + vy,  z + vz, 0.0f, 1.0f,  0.0f);
        glRotatef(angle, 0.0, 1.0, 0.0);

        int i = 0, j = 0, k = 0;
        for(; i < yBlocks; i ++)
            for(j = -xBlocks / 2; j < xBlocks / 2; j ++)
                for(k = -zBlocks / 2; k < zBlocks / 2; k ++)
                {
                    glPushMatrix();
                    glTranslatef((float)j, -(float)i - 1.7f, (float)k);

                    glBindVertexArray(vao);
                    glDrawElements(mode, indexAmnt, GL_UNSIGNED_INT, NULL);
                    glBindVertexArray(0);

                    glPopMatrix();
                }
        glutSwapBuffers();
    }

    void update()
    {
        if(deltaX || deltaY)
            direction(deltaX, deltaY);
        if(deltaS || deltaSt)
            position(deltaSt, deltaS);

        deltaX *= 0.9f;
        deltaY *= 0.9f;

        if(up == 0 && down == 0)
            deltaUp *= 0.9;

        if(fabs(deltaUp) >= 0.001f)
            y += deltaUp;

        double currentTime = time(NULL);
        nFrames ++;

        if(currentTime - lastTime >= 1.0)
        {
            //printf("%f ms/frame\n", 1000.0 / (double)nFrames);
            printf("%d fps\n", nFrames);
            defaultSpeed = (float)nFrames / 60.0f;
            nFrames = 0;
            lastTime += 1.0;
        }
        glutPostRedisplay();
    }

    int main(int argc, string argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);

        glutInitWindowSize(WIDTH, HEIGHT);
        glutCreateWindow("First Person World");

        glutDisplayFunc(render);
        glutIdleFunc(update);
        glutPassiveMotionFunc(mouse);
        glutKeyboardFunc(keyboard);
        glutKeyboardUpFunc(keyboard_r);
        glutSpecialFunc(input);
        glutSpecialUpFunc(input_r);
        glutSetCursor(GLUT_CURSOR_NONE);

        GLenum error = glewInit();

        if(error != GLEW_OK)
        {
            fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
            return -1;
        }
        glewGetString(GLEW_VERSION);

        loadgame();

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        glEnable(GL_CULL_FACE);
        glutMainLoop();

        return 0;
    }

這段代碼可以正常工作,但是馬上我注意到它缺乏加載紋理的能力。 因此,我研究了如何加載和渲染紋理,但遺憾的是我一直無法使它正常工作。 到目前為止,關於加載和渲染紋理的內容是這樣的:

    #include <math.h>
    #include <time.h>

    #include <stdio.h>
    #include <stdlib.h>

    #include <GL/glew.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>
    #include <SOIL/SOIL.h>

    #define WIDTH 0x320
    #define HEIGHT 0x258

    #define GLUT_KEY_LSHIFT 112
    #define QUIT 0x11
    #define ESC  0x1B

    typedef char* string;

    typedef struct vertex {

        float x;
        float y;
        float z;
        float u;
        float v;
    } Vertex;

    float angle = 0.0;
    float deltaX, deltaY;
    float deltaS, deltaSt;
    float deltaUp;

    float vx, vz, vy;
    float x = 0.0f, y = 0.0f, z = 0.0f;

    float defaultSpeed = 1.0f;
    float speed = 1.0f;

    float lastMousePosY = HEIGHT / 2;
    float lastMousePosX = WIDTH / 2;

    int nFrames;
    double lastTime;

    GLint up, down;
    GLuint vbo0, vbo1, ibo, vao, texId, progId;
    GLint indexAmnt, vertexAmnt, colorAmnt;
    GLint menuId;
    GLenum mode;

    int release;

    int xBlocks = 30;
    int yBlocks = 4;
    int zBlocks = 16;

    void direction(float delta_h, float delta_v)
    {
        angle += delta_h;
        vx = sin(angle);
        vz = -cos(angle);
        vy += sin(delta_v) * cos(delta_v);
    }

    void position(float delta_x, float delta_z)
    {
        x += delta_z * vx * speed;
        z += delta_z * vz * speed;

        x += delta_x * -vz * speed;
        z += delta_x * vx * speed;
    }

    Vertex initVertex(float x, float y, float z, float u, float v)
    {
        Vertex v0 = {.x=x, .y=y, .z=z, .u=u, .v=v};
        return v0;
    }

    unsigned int initShaderProgram()
    {
        unsigned int id_p, vs, fs;

        const char* vertShader =
        "#version 300 es\n"
        "in vec2 texcoord;"
        "out vec2 TexCoord;"
        "void main() {"
        "   TexCoord = texcoord;"
        "}";

        const char* fragShader =
        "#version 300 es\n"
        "uniform sampler2D cubeTex;"
        "in vec2 TexCoord;"
        "void main() {"
        "   gl_FragColor = texture(cubeTex, TexCoord);"
        "}";

        int compile_ok = 0;

        vs = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vs, 1, &vertShader, NULL);
        glCompileShader(vs);
        glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);

        if(compile_ok == 0)
        {
            GLsizei slen = 0;
            GLint blen = 0;
            glGetShaderiv(vs, GL_INFO_LOG_LENGTH , &blen);
            fprintf(stderr, "Error in vertex shader:\n");
            GLchar* compiler_log = (GLchar*)malloc(blen);
            glGetShaderInfoLog(vs, blen, &slen, compiler_log);
            fprintf(stderr, "%s\n", compiler_log);
            free (compiler_log);
        }

        fs = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fs, 1, &fragShader, NULL);
        glCompileShader(fs);
        glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);

        if(compile_ok == 0)
        {
            GLsizei slen = 0;
            GLint blen = 0;
            glGetShaderiv(fs, GL_INFO_LOG_LENGTH , &blen);
            fprintf(stderr, "Error in fragment shader:\n");
            GLchar* compiler_log = (GLchar*)malloc(blen);
            glGetShaderInfoLog(fs, blen, &slen, compiler_log);
            fprintf(stderr, "%s\n", compiler_log);
            free (compiler_log);
        }

        id_p = glCreateProgram();
        glAttachShader(id_p, vs);
        glAttachShader(id_p, fs);
        glLinkProgram(id_p);

        return id_p;
    }

    unsigned int initVertexBuffer(Vertex* v)
    {
        unsigned int vbo_v;

        glGenBuffers(1, &vbo_v);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_v);
        glBufferData(GL_ARRAY_BUFFER, vertexAmnt * sizeof(Vertex), v, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        return vbo_v;
    }

    unsigned int initColorBuffer(int* c)
    {
        unsigned int vbo_c;

        glGenBuffers(1, &vbo_c);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_c);
        glBufferData(GL_ARRAY_BUFFER, colorAmnt * sizeof(int), c, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        return vbo_c;
    }

    unsigned int initIndexBuffer(int *i)
    {
        unsigned int ibo_i;

        glGenBuffers(1, &ibo_i);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_i);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexAmnt * sizeof(int), i, GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        return ibo_i;
    }

    unsigned int initTexture(const char* filename)
    {
        unsigned int id_t;

        glGenTextures(1, &id_t);

        int w, h;
        unsigned char* image = SOIL_load_image(filename, &w, &h, 0, SOIL_LOAD_RGB);

        glBindTexture(GL_TEXTURE_2D, id_t);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
        glGenerateMipmap(GL_TEXTURE_2D);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glBindTexture(GL_TEXTURE_2D, 0);
        SOIL_free_image_data(image);

        return id_t;
    }

    void menuActions(int value)
    {
        switch(value)
        {
        case 1:
            mode = GL_LINES;
            break;
        case 0:
            mode = GL_TRIANGLES;
            break;
        default:
            break;
        }
    }

    int createMenu()
    {
        int menu;

        menu = glutCreateMenu(menuActions);
        glutAddMenuEntry("On", 1);
        glutAddMenuEntry("Off", 0);

        return menu;
    }

    unsigned int initVertexArray()
    {
        GLuint vao_a;

        glGenVertexArrays(1, &vao_a);
        glBindVertexArray(vao_a);

        glBindBuffer(GL_ARRAY_BUFFER, vbo0);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)offsetof(Vertex, x));
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)offsetof(Vertex, u));
        glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, x));
        glEnableClientState(GL_VERTEX_ARRAY);

        glActiveTexture(GL_TEXTURE0);
        glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
        glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, u));
        glBindTexture(GL_TEXTURE_2D, texId);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBindVertexArray(0);

        return vao_a;
    }

    void loadgame()
    {
        Vertex vertices[] = {

                initVertex(-0.5f, -0.5f, 0.5f, 0.0f, 0.0f),
                initVertex(0.5f, -0.5f, 0.5f, 1.0f, 0.0f),
                initVertex(0.5f, 0.5f, 0.5f, 1.0f, 1.0f),
                initVertex(-0.5f, 0.5f, 0.5f, 0.0f, 1.0f),
                initVertex(-0.5f, -0.5f, -0.5f, 0.0f, 0.0f),
                initVertex(0.5f, -0.5f, -0.5f, 1.0f, 0.0f),
                initVertex(0.5f, 0.5f, -0.5f, 1.0f, 1.0f),
                initVertex(-0.5f, 0.5f, -0.5f, 0.0f, 1.0f)
        };

        int indices[] = {

            0, 1, 2, 2, 3, 0,
            3, 2, 6, 6, 7, 3,
            7, 6, 5, 5, 4, 7,
            4, 0, 3, 3, 7, 4,
            0, 1, 5, 5, 4, 0,
            1, 5, 6, 6, 2, 1
        };

        vertexAmnt = sizeof(vertices) / sizeof(Vertex);
        indexAmnt = sizeof(indices) / sizeof(int);

        vbo0 = initVertexBuffer(vertices);
        ibo = initIndexBuffer(indices);
        texId = initTexture("stone.png");
        progId = initShaderProgram();
        vao = initVertexArray();

        mode = GL_TRIANGLES;

        menuId = createMenu();
        glutAttachMenu(GLUT_RIGHT_BUTTON);
        glClearColor(0.6f, 0.6f, 1.0f, 1.0f);

        lastTime = time(NULL);
    }

    void input(int key, int ix, int iy)
    {
        if(key == GLUT_KEY_LSHIFT){ deltaUp = -0.3f; down = 1; }
    }

    void input_r(int key, int ix, int iy)
    {
        if(key == GLUT_KEY_LSHIFT) down = 0;
    }

    void keyboard(unsigned char key, int kx, int ky)
    {
        if(key == QUIT) exit(0);
        if(key == ESC) release = 1;
        if(key == 'w') deltaS = 0.5f;
        if(key == 's') deltaS = -0.5f;
        if(key == 'a') deltaSt = -0.5f;
        if(key == 'd') deltaSt = 0.5f;
        if(key == 'r') speed = defaultSpeed * 5.0;
        if(key == ' '){ deltaUp = 0.3f; up = 1; }
    }

    void keyboard_r(unsigned char key, int kx, int ky)
    {
        if(key == ESC) release = 0;
        if(key == 'w' || key == 's') deltaS = 0.0f;
        if(key == 'a' || key == 'd') deltaSt = 0.0f;
        if(key == ' ') up = 0;
        if(key == 'r') speed = defaultSpeed;
    }

    void resetPointer()
    {
        glutWarpPointer(WIDTH / 2.0, HEIGHT / 2.0);

        lastMousePosY = HEIGHT / 2.0;
        lastMousePosX = WIDTH / 2.0;
    }

    void mouse(int mx, int my)
    {
        if(!release)
        {
            if(fabs(WIDTH / 2 - mx) > 15 ||
                    fabs(HEIGHT / 2 - my) > 15)
                        resetPointer();
            else
            {
                int vMotion = lastMousePosY - my;
                int hMotion = lastMousePosX - mx;

                deltaX = -hMotion / 25.0;
                deltaY = vMotion / 25.0;

                lastMousePosY = my;
                lastMousePosX = mx;
            }
        }
    }

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

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        const double w = glutGet(GLUT_WINDOW_WIDTH);
        const double h = glutGet(GLUT_WINDOW_HEIGHT);

        gluPerspective(45.0, w / h, 0.1, 1000.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        gluLookAt(x, y, z, x + vx, y + vy,  z + vz, 0.0f, 1.0f,  0.0f);
        glRotatef(angle, 0.0, 1.0, 0.0);

        glUseProgram(progId);

        int i = 0, j = 0, k = 0;
        for(; i < yBlocks; i ++)
            for(j = -xBlocks / 2; j < xBlocks / 2; j ++)
                for(k = -zBlocks / 2; k < zBlocks / 2; k ++)
                {
                    glPushMatrix();
                    glTranslatef((float)j, -(float)i - 1.7f, (float)k);

                    glBindVertexArray(vao);
                    //glActiveTexture(GL_TEXTURE0);
                    //glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
                    //glBindTexture(GL_TEXTURE_2D, texId);
                    glDrawElements(mode, indexAmnt, GL_UNSIGNED_INT, NULL);
                    glBindVertexArray(0);

                    glPopMatrix();
                }
        glutSwapBuffers();
    }

    void update()
    {
        if(deltaX || deltaY)
            direction(deltaX, deltaY);
        if(deltaS || deltaSt)
            position(deltaSt, deltaS);

        deltaX *= 0.9f;
        deltaY *= 0.9f;

        if(up == 0 && down == 0)
            deltaUp *= 0.9;

        if(fabs(deltaUp) >= 0.001f)
            y += deltaUp;

        double currentTime = time(NULL);
        nFrames ++;

        if(currentTime - lastTime >= 1.0)
        {
            printf("%d fps\n", nFrames);
            defaultSpeed = (float)nFrames / 60.0f;
            nFrames = 0;
            lastTime += 1.0;
        }
        glutPostRedisplay();
    }

    int main(int argc, string argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);

        glutInitWindowSize(WIDTH, HEIGHT);
        glutCreateWindow("First Person World");

        glutDisplayFunc(render);
        glutIdleFunc(update);
        glutPassiveMotionFunc(mouse);
        glutKeyboardFunc(keyboard);
        glutKeyboardUpFunc(keyboard_r);
        glutSpecialFunc(input);
        glutSpecialUpFunc(input_r);
        glutSetCursor(GLUT_CURSOR_NONE);

        GLenum error = glewInit();

        if(error != GLEW_OK)
        {
            fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
            return -1;
        }
        glewGetString(GLEW_VERSION);

        loadgame();

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        glEnable(GL_CULL_FACE);
        glutMainLoop();

        return 0;
    }

我意識到,即使在我的工作代碼中,很可能還有很多其他事情需要修復,這是我仍在學習中所期望的。 因此,我想知道是否仍然有一種方法可以使此代碼與紋理一起使用(也許我只是缺少一些東西?)或者我是否打算在此代碼中完全實現紋理(在其中情況下,我將如何處理?)。

尚未測試您的代碼,因此這可能有幫助也無濟於事。

1。

我看到您的頂點緩沖區設置為

{vertex0 [x,y,z,u,v],vertex1 [x,y,z,u,v] ...}

也就是說,您的glVertexAttripPointer調用必須為:

// Okay. vbo0 will be used for later operations.
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
// Okay. We will use attribute at 0.
glEnableVertexAttribArray(0);
// Okay. Vertex position attribute will be sent to attribute at 0.
glVertexAttribPointer( 0 // attribute at 0
                     , 3 , GL_FLOAT // 3 floating numbers for each vertex
                     , GL_FALSE // shell not normalize.
                     , 5 * sizeof(GLfloat) // jump 5 floating numbers to reach next vertex position
                     , (GLvoid*)0); // start from beginning
glEnableVertexAttribArray(1);
glVertexAttribPointer(1
                     , 2, GL_FLOAT
                     , GL_FALSE
                     , 5 * sizeof(GLfloat)
                     , (GLvoid*)offsetof(Vertex, u)); // start from fourth floating point number in buffer.

2。

//glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, x));

此功能對您不再有用。 它將與您的glVertexAttribPointer調用混淆。 帶他們出去。

3。

並且您的頂點着色器源外殼為:

#version 300 es
layout(location=0) in vec3 a_vertexPosition; // attribute at 0 is vertex position
layout(location=1) in vec2 a_TexCoord; // attribute at 1 is uv

out vec2 v_TexCoord;
void main() {
   gl_Position = vec4(a_vertexPosition, 1);
   v_TexCoord = a_TexCoord;
}

和您的片段着色器:

#version 300 es
in vec2 v_TexCoord;
uniform sampler2D u_cubeTexture;

void main()
{
    gl_FragColor = texture(u_cubeTexture, v_TexCoord);
}

4。

如果您認為uv不能正確發送,則可以始終通過將uv渲染為紅色/綠色來進行測試。 你會得到像這樣

void main()
{
    gl_FragColor = vec4(v_TexCoord.x, v_TexCoord.y, 0, 1);
}

5,

unsigned int initVertexArray()
    {
        GLuint vao_a;

        ...

        glActiveTexture(GL_TEXTURE0); // can be moved to different place
        glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0); // Meaningless. You don't know what program is currently used.
        glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, u)); // Bad. Messes up your glVertexAttribPoionter call
        glBindTexture(GL_TEXTURE_2D, texId); // can be moved to different place

        ...

        return vao_a;
    }

沒有理由將紋理和着色器程序綁定作為vao初始化的一部分。 紋理綁定和程序都不是vao的一部分。 在這里

6。

如果不確定是否正確創建了Texture,請記住SOIL具有易於使用的功能,可以為您完成所有工作。

/**
    Loads an image from disk into an OpenGL texture.
    \param filename the name of the file to upload as a texture
    \param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
    \param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
    \param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
    \return 0-failed, otherwise returns the OpenGL texture handle
**/
unsigned int
    SOIL_load_OGL_texture
    (
        const char *filename,
        int force_channels,
        unsigned int reuse_texture_ID,
        unsigned int flags
    );

7。

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

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    const double w = glutGet(GLUT_WINDOW_WIDTH);
    const double h = glutGet(GLUT_WINDOW_HEIGHT);

    gluPerspective(45.0, w / h, 0.1, 1000.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(x, y, z, x + vx, y + vy,  z + vz, 0.0f, 1.0f,  0.0f);
    glRotatef(angle, 0.0, 1.0, 0.0);

    glUseProgram(progId);

    int i = 0, j = 0, k = 0;
    for(; i < yBlocks; i ++)
        for(j = -xBlocks / 2; j < xBlocks / 2; j ++)
            for(k = -zBlocks / 2; k < zBlocks / 2; k ++)
            {
                glPushMatrix();
                glTranslatef((float)j, -(float)i - 1.7f, (float)k);

                glBindVertexArray(vao);
                //glActiveTexture(GL_TEXTURE0);
                //glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
                //glBindTexture(GL_TEXTURE_2D, texId);
                glDrawElements(mode, indexAmnt, GL_UNSIGNED_INT, NULL);
                glBindVertexArray(0);

                glPopMatrix();
            }
    glutSwapBuffers();
}

您在此處調用的每個Matrix函數都是沒有意義的。

您從未使用過的頂點着色器甚至不會使用任何推入的矩陣。 您使用的是ES版本。 您不能按照以下存根描述從頂點着色器訪問那些矩陣:

(從這里存檔)

一些框架(特別是OpenGL兼容性配置文件,但OpenGL核心配置文件和OpenGL ES 2.x都不提供)提供了一些內置的統一體,以訪問GLSL着色器中的某些頂點轉換。 不應聲明它們,但以下是聲明其類型的聲明:

uniform mat4 gl_ModelViewMatrix;
uniform mat4 gl_ProjectionMatrix;
uniform mat4 gl_ModelViewProjectionMatrix;
uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
uniform mat3 gl_NormalMatrix; // transpose of the inverse of the
   // upper left 3x3 matrix of gl_ModelViewMatrix
uniform mat4 gl_ModelViewMatrixInverse;
uniform mat4 gl_ProjectionMatrixInverse;
uniform mat4 gl_ModelViewProjectionMatrixInverse;
uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixTranspose;
uniform mat4 gl_ProjectionMatrixTranspose;
uniform mat4 gl_ModelViewProjectionMatrixTranspose;
uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixInverseTranspose;
uniform mat4 gl_ProjectionMatrixInverseTranspose;
uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];

如果您正在使用OpenGL的現代去,你會做正是因為這個文章告訴你。

8。

//glActiveTexture(GL_TEXTURE0);
//glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
//glBindTexture(GL_TEXTURE_2D, texId);

這部分是正確的。 為什么將其注釋掉?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM