Michael Bell
Michael Bell

Reputation: 189

OpenGL Texturing with SOIL

I'm working on building a basketball game in openGL, however i'm taking baby steps and dividing my work into sections. I'm currently focusing on texturing, attempting to build a house using the SOIL library.

I'm extremely new to all of this so i've probably set things up wrong but my main problem is that textures are acting as if they are clamped to edge from what i can see.

Currently the project is a singular wall meant to be textured by bricks, here's an image of the output i'm getting: Texture Fail

Here is the source code:

#include <stdlib.h>
#include <GL/glut.h>
#include <SOIL.h>
#include <stdio.h>

float _angle = 0.0;
GLuint _textureBrick;

static void resize(int width, int height)
{
    const float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void renderScene(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);

    // Front side brick wall
    glPushMatrix();
        glBindTexture(GL_TEXTURE_2D, _textureBrick);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTranslatef(0,0,-6);
        glRotatef(_angle, 0.0, 1.0, 0.0);
        glBegin(GL_QUADS);  // Wall
            glTexCoord3f(-50.0,2.0,0.1);  glVertex3f(-50,0,1);
            glTexCoord3f(50.0,2.0,0.1);  glVertex3f(50,0,1);
            glTexCoord3f(50.0,0.0,0.1);  glVertex3f(50,-1.5,1);
            glTexCoord3f(-50.0,0.0,0.1);  glVertex3f(-50,-1.5,1);
        glEnd();
    glPopMatrix();

    glutSwapBuffers();
}

void mySpecialFunc(int key, int x, int y){
    switch (key) {
    case GLUT_KEY_RIGHT:
        _angle += 1;
        if (_angle > 360) _angle = 0.0;
        break;
    case GLUT_KEY_LEFT:
        _angle -= 1;
        if (_angle > 360) _angle = 0.0;
        break;
    }
    glutPostRedisplay();
}

GLuint loadTex(const char* texname)
{
    GLuint texture = SOIL_load_OGL_texture
                    (
                        texname,
                        SOIL_LOAD_AUTO,
                        SOIL_CREATE_NEW_ID,
                        SOIL_FLAG_INVERT_Y

                    );

    if( 0 == texture )
    {
        printf( "SOIL loading error: '%s'\n", SOIL_last_result() );
    }

    //glBindTexture(GL_TEXTURE_2D, texture);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    return texture;
}

void Initialize() {
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);

    //_textureFloor = loadTex("C:\\Users\\Mikle\\OneDrive\\Uni work\\Second Year\\Projects\\3D-House-using-OpenGL-and-C--master\\court.png");

    _textureBrick = loadTex("C:\\Users\\Mikle\\OneDrive\\Uni work\\Second Year\\Projects\\3D-House-using-OpenGL-and-C--master\\bricks.bmp");
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(600,600);
    glutCreateWindow("Textured House");
    glEnable(GL_DEPTH_TEST);

    glutReshapeFunc(resize);
    glutSpecialFunc(mySpecialFunc);
    glutDisplayFunc(renderScene);
    Initialize();

    glutMainLoop();

    return 0;
}

Any help would be appreciated, thankyou!

Upvotes: 1

Views: 997

Answers (1)

Kato Katsu
Kato Katsu

Reputation: 26

Michael. In order to generate mipmaps and possibly fix the texture, you should change the parameters of the soil loading function to

GLuint texture = SOIL_load_OGL_texture
                (
                    texname,
                    SOIL_LOAD_AUTO,
                    SOIL_CREATE_NEW_ID,
                    SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT

                );

This will automatically generate mipmaps from the OpenGL library, as you did not call afterwards to glGenerateMipmaps(). It also saves on the memory needed to store the textures. Another suggestion for the texture clamping and wrapping is to use

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

after you use the load function. Good luck with your OpenGL learning experience. I hope this helped you in some way.

EDIT:

You also shouldn't repeat the glTexParameteri every single frame. This puts excess and unnecessary strain on your (or the user's) CPU.

Upvotes: 1

Related Questions