Jump to content

  • Log In with Google      Sign In   
  • Create Account

Rendering a texture


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 23 July 2013 - 08:20 AM

Hello!

 

I am very new to OpenGL and have a basic problem: I want to render 2 quads each with its own texture.

First I have an init function which loads the texture, generates the texture IDs and uploads the texture:

void initTex(TexObj& texObj, const char* imageFilename) // Images are .xpm files
{
   QImage image = QImage(imageFilename);
    texObj.w = image.width();
    texObj.h = image.height();

    QImage glImage;
    glImage = QGLWidget::convertToGLFormat(image);

    char* data = static_cast<char*>( calloc( texObj.w *  texObj.h, 4) ); 
    memcpy(data, glImage.bits(), texObj.w * texObj.h * 4);

    texObj.data = data
    glGenTextures(1, &texObj.texID);
    glBindTexture(GL_TEXTURE_2D, texObj.texID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texObj.w, texObj.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,  texObj.data);
}

Function initTex is called 2 times (for 2 different textures).

 

To render the 2 quads I use this function:

static void draw(TexObj& tex, float scale)
{
    glEnable(GL_CULL_FACE);
    glEnable( GL_TEXTURE_2D );
    glFrontFace( GL_CCW );

    glActiveTexture( GL_TEXTURE0 );
    glBindTexture(GL_TEXTURE_2D, tex.texID);

   // glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex->data );

    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ;
    glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ;
    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ; 

    glTranslated( 0.0, 0.0, 0.0 );
    glScalef( scale, scale, 1.0f );
   
      glPolygonMode(GL_FRONT, GL_FILL);
    glBegin(GL_POLYGON);
        glTexCoord2f( 0.0, 0.0 );
        glVertex2d(0.0, 1.0);
        glTexCoord2f( 0.0, -1.0 );
        glVertex2d(0.0, 0.0);
        glTexCoord2f( 1.0, -1.0 );
        glVertex2d(1.0, 0.0);
        glTexCoord2f( 1.0, 0.0 );
        glVertex2d(1.0, 1.0);
    glEnd();

    glDisable( GL_TEXTURE_2D );
    glDisable(GL_CULL_FACE);
}

The problem is: When I let this code run the quads are completely white!

The strange thing: When I comment in the outcommented line (glTexImage2D), the quads are textured! It seems like as if the texture I load into the VRAM in function init() is disappeared and I have to upload it every frame.

 

Does anyone have an idea what could cause this?

Thanks!

 

 



Sponsor:

#2 RobTheBloke   Crossbones+   -  Reputation: 2341

Like
0Likes
Like

Posted 23 July 2013 - 10:00 AM

1. Move the following lines to the end of initTexture (there's no point repeastedly doing this)

glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ;
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ;
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ;

2. Why are you doing this:  texObj.data = data ? Unless it's for a very specific reason (getting heightmap values on the CPU side, as well as the GPU), it's just wasting memory. You can skip everything involving copying the data from the image (the calloc + memcpy), and instead just pass glImage.bits() to glTexImage2D directly.

 

3. You might find that using glPushMatrix / glPopMatrix surrounding the scaling and drawing of the quad will be useful (stops the transforms leaking into other draw calls).

4. glTranslated( 0.0, 0.0, 0.0 );  << this is pointless.

5.
enabling / disabling texturing and face culling constantly is a bit silly. You'd be better off moving those outside so you can do:

 


glEnable(GL_TEXTURE_2D);

glEnable(GL_CULL_FACE);


// draw all textured quads.


glDisable(GL_CULL_FACE);

glDisable(GL_TEXTURE_2D);

6. glFrontFace( GL_CCW );  This is something you shouldn't need to be calling everytime you draw a single quad. Just once on start up will do fine (and then keep everything with the same winding order).
 

The problem is: When I let this code run the quads are completely white!

Check the values of tex.texID. Are they the same two values used when generating the texture?

The strange thing: When I comment in the outcommented line (glTexImage2D), the quads are textured! It seems like as if the texture I load into the VRAM in function init() is disappeared and I have to upload it every frame.

Which makes me think that you have either an invalid texture object, or that it's changing it's id somehow. You are initializing the textures AFTER you create the window right? (otherwise the gl context would be invalid, and the texture creation will fail).

 

So to recap, the rest of your app looks a little like this right?

<span>TexObj</span><span> g_tex</span>1;
<span>TexObj</span><span> g_tex</span>2;


int initGL()

{

   // initialize and create GL window


   // now textures are created.

   <span>initTex(g_tex1, "file1.bmp");</span>

   <span>initTex(g_tex2, "file2.bmp");</span>

}


void drawMethod()

{
<span>  draw</span><span>(g_</span><span>tex</span><span>1,</span><span> </span><span>1.0f</span><span>)</span>;
<span>  draw</span><span>(g_</span><span>tex</span><span>2, </span><span>1.0</span><span>f)</span>;

}



#3 schupf   Members   -  Reputation: 216

Like
0Likes
Like

Posted 25 July 2013 - 01:33 PM

Thanks RobTheBloke for your detailed help! You pushed me in the right direction:)

 

The problem was: When I uploaded the images with glTexImage2D I had no OpenGL context. I find it very strange that glError() did not tell any error though...

 

One last question: How is it possible NOT to have a valid context? I mean after I create a context and "activate" it by calling wglMakeCurrent (), isn't the context now active forever? In other words: I thought after calling wglMakeCurrent() I can use OpenGL calls in my code in every function I want. Did I miss something?



#4 Koehler   Members   -  Reputation: 228

Like
0Likes
Like

Posted 25 July 2013 - 04:15 PM

I think the main case where you'd be unable to use a context is due to multithreading. An OpenGL context cannot be active on multiple threads, so in the case where you wanted to call OpenGL functions from different threads, you'd need to either create more than one context and have them share data (with wglShareLists), or have each thread sync and make the context current / not current as needed. 






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS