1
$\begingroup$

I know there are tons of questions about it, but I found nothing useful so far so, here I am.

I'm trying to render a texture which is attached to a wavefront .obj mesh. I continued to fail (somehow, it was like textures were not correctly loaded), so I wrote a simple example code to see where I was wrong. The sample code follows, and the texture is "correctly" loaded and rendered. However, there are some problems in the render itself: the image is incomplete / blurry / repeated / distorted. I will also post the expected result and the actual result.

Working on Linux Ubuntu 14.04, OpenGL 3.0 Mesa 10.5.9. Any idea of what is happening?

Texture (copyright Angryfly @ Turbosquid) and result on the right: enter image description here

Sample code:

#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include<iostream>

int main(int argc, char* argv[]) {
    SDL_Init( SDL_INIT_VIDEO );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    // prepare the window
    SDL_Window *window = SDL_CreateWindow(argv[0], 0, 0,
            800, 600,
            SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    SDL_GLContext context = SDL_GL_CreateContext(window);
    // enable textures and bind a name (say 50)
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 50);

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                     GL_LINEAR_MIPMAP_NEAREST );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    // load image with SDL
    SDL_Surface *s = IMG_Load("texture.png");
    // the following doesn't work (white space)
    //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, s->w, s->h, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);

    glViewport(0, 0, 800, 600);
    glClearColor(1,1,1,1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(70, 0.75, 0.2, 1000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    gluLookAt(0, 10, 0, 0, 0, 0, 1, 0, 0);

    glActiveTexture(50);
    // display texture as 2 triangles.
    glBegin(GL_TRIANGLES);
    glTexCoord2d(0,0); glVertex3d(-5, 0, -5);
    glTexCoord2d(0,1); glVertex3d(-5, 0, 5);
    glTexCoord2d(1,0); glVertex3d(5, 0, -5);

    glTexCoord2d(0,1); glVertex3d(-5, 0, 5);
    glTexCoord2d(1,0); glVertex3d(5, 0, -5);
    glTexCoord2d(1,1); glVertex3d(5, 0, 5);

    glEnd();
    glFinish();
    SDL_GL_SwapWindow(window);
    // wait for quit procedure
    SDL_Quit();
    return 0;

}
$\endgroup$
9
  • $\begingroup$ Is there any reason why you use the old style openGL $\endgroup$
    – joojaa
    Commented Jun 10, 2016 at 14:06
  • $\begingroup$ It is a computer graphics project in OpenGL and SDL. $\endgroup$
    – phagio
    Commented Jun 11, 2016 at 14:58
  • $\begingroup$ that's not a reason its a circular definition. $\endgroup$
    – joojaa
    Commented Jun 11, 2016 at 15:07
  • 1
    $\begingroup$ Yes but why are you using obsolete and deprecated openGL calls? $\endgroup$
    – joojaa
    Commented Jun 12, 2016 at 21:57
  • 1
    $\begingroup$ Yes that's what deprecated means, any new code should not use this method if possible (here its possible). Read its not very performant why-do-vertex-buffer-objects-improve-performance. Nobody should be teaching you this stuff anymore. $\endgroup$
    – joojaa
    Commented Jun 14, 2016 at 8:03

1 Answer 1

7
$\begingroup$

This type of artifact is a tell-tale sign that you've messed up your texture image format at the byte level. It's hard to tell what exactly is wrong, but it's something along the lines of bad pitch or a component layout mismatch.

Have a read of this wiki page and try again. glTexImage2D should work, keep trying until it does.

$\endgroup$
4
  • $\begingroup$ Thank you! I might as well try to reimplement some basic reader - but in the sample code that was given as example the calls didn't mess up things like this. I'm going to look at it again! $\endgroup$
    – phagio
    Commented Jun 11, 2016 at 15:00
  • $\begingroup$ I see you're using the SDL surface's pixel buffer directly. You could get the debug version of the SDL library and the source, and inspect what's happening inside SDL. The core of the problem is that OpenGL expects the pixels to be laid out in memory differently than what is actually in the buffer. $\endgroup$
    – IneQuation
    Commented Jun 11, 2016 at 16:29
  • $\begingroup$ I "surprisingly" solved by letting the code load a jpg rather than a png. I guess SDL likes MPEG codecs more than PNG. $\endgroup$
    – phagio
    Commented Jun 17, 2016 at 11:55
  • 1
    $\begingroup$ PNG supports alpha, JPEG doesn't. Have you tried uploading your PNG texture as GL_RGBA, not GL_RGB? Because you haven't solved your problem, you just sidestepped it. $\endgroup$
    – IneQuation
    Commented Jun 20, 2016 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.