Sign in to follow this  
OpenGLAaron

OpenGL glCopyTexSubImage2D squishing images? [resolved]

Recommended Posts

OpenGLAaron    122
The Demo (Requires windows.h) I'm having this odd problem with glCopyTexSubImage2D where it seems as though the function is squishing the captured framebuffer image towards the bottom of the texture it is storing to. Here's an image to illustrate what I mean: This is a simply paint program. The cursor is a white diffuse sphere image and when you left click, the program copies everything from the framebuffer to a constantly updated texture, then renders the updated texture as a screen-aligned quad. That big line in the middle of the screen is the result of simply holding down "left click" while keeping the pointer stationary. As you can see, glCopyTexSubImage2D is grabbing the old image and stretching (or compressing, whichever you prefer) the image downward, resulting in the streak. Likewise, you can see near the bottome how a bunch of scribbles have been squished over time. Has anyone encountered anything similar to this before? I looked at parameters for glPixelStore and glPixelTransfer, but none of them seem like they would affect this at all. To create my initial texture, I call glCopyTexImage2D, and the width and height parameters are the same throughout the program, and are the same for both CopyTex calls, so it should be working, as far as I can tell. [Edited by - OpenGLAaron on November 25, 2004 1:26:34 AM]

Share this post


Link to post
Share on other sites
Hew T    206
Post code - specifically, your render segment and the part containing the glCopyTexImage2D. I suspect something like not glLoadIdentity'ing in the right place (or not at all), but it's really hard to give you any suggestions without code.

Regards,

Hew T.

Share this post


Link to post
Share on other sites
OpenGLAaron    122

///////////////////////////////////////////////////////////////////////////////
// draw the screen aligned quad and cursor brush to the backbuffer
///////////////////////////////////////////////////////////////////////////////
{
glClearColor(0.0,0.0,0.0,0.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1000,1000);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT, GL_FILL);

///////////////////////////////////////////////////////////////////////////////
// draw the screen-aligned quad
///////////////////////////////////////////////////////////////////////////////
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);

if (firstRun)
{
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
firstRun = false;
}
else
{
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, updateTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}

glColor3f(0.0,0.0,0.0);
drawQuad();

///////////////////////////////////////////////////////////////////////////////
// this draws the actual brush
///////////////////////////////////////////////////////////////////////////////
float texSize = 64.0/512.0;
glTranslatef(mousePos3D.m_x,mousePos3D.m_y,5);
glScalef(texSize,texSize,texSize);
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glColor3f(1.0,1.0,1.0);
glutSolidSphere(0.4,16,3);
glEnable(GL_LIGHTING);

///////////////////////////////////////////////////////////////////////////////
// on a left mouse click, copy the "paint texture" over the existing texture
///////////////////////////////////////////////////////////////////////////////
if (leftClick)
{
glReadBuffer(GL_BACK);
glBindTexture(GL_TEXTURE_2D, updateTex);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
}
}
///////////////////////////////////////////////////////////////////////////////
// draw the updated texture after the copytexsubimage call
///////////////////////////////////////////////////////////////////////////////
{
glClearColor(0.0,0.0,0.0,0.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1000,1000);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT, GL_FILL);

//draw the updated texture
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,updateTex);

drawQuad();

glEnable(GL_LIGHTING);
}



This is my drawing function. The two segments of curly braces are actually nested within an encompassing pair, I just include them to clarify code.
Thanks for taking a look.

Woops, forgot the glCopyTexImage2D part.


glReadBuffer(GL_BACK);

glGenTextures(1, &updateTex);
glBindTexture(GL_TEXTURE_2D, updateTex);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGB,0,0,WIDTH,HEIGHT,0);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);



And I just have that last segment in my initialization function.

[Edited by - OpenGLAaron on November 24, 2004 10:24:46 PM]

Share this post


Link to post
Share on other sites
Hew T    206
Firstly, using the "source" tags when posting code is good. The FAQ can tell you how.

First look - can't see anything obviously wrong. I'd like to know what happens in your "drawQuad" routine - if the routine is not drawing to the entire screen properly, it could result in the effect you're experiencing.

Regards,

Hew T.

Share this post


Link to post
Share on other sites
OpenGLAaron    122
I was using source tags... Sorta. I'm used to using [ code ] tags, and I assumed it was the same here. If you looked closely, you would have seen that the formatting was slightly different between my [ code ] tags. Nevertheless, I fixed it to what it should have been from the start. Sorry. :P

Here's my drawQuad function. Pretty straightforward, really:

void drawQuad()
{
glBegin(GL_QUADS);
{
glNormal3f(0,0,1);

glMultiTexCoord2fARB(GL_TEXTURE0, 0,0);
glMultiTexCoord2fARB(GL_TEXTURE1, 0,0);
glMultiTexCoord2fARB(GL_TEXTURE2, 0,0);
glVertex3f(-1,-1,0);

glMultiTexCoord2fARB(GL_TEXTURE0, 1,0);
glMultiTexCoord2fARB(GL_TEXTURE1, 1,0);
glMultiTexCoord2fARB(GL_TEXTURE2, 1,0);
glVertex3f(1,-1,0);

glMultiTexCoord2fARB(GL_TEXTURE0, 1,1);
glMultiTexCoord2fARB(GL_TEXTURE1, 1,1);
glMultiTexCoord2fARB(GL_TEXTURE2, 1,1);
glVertex3f(1,1,0);

glMultiTexCoord2fARB(GL_TEXTURE0, 0,1);
glMultiTexCoord2fARB(GL_TEXTURE1, 0,1);
glMultiTexCoord2fARB(GL_TEXTURE2, 0,1);
glVertex3f(-1,1,0);
}
glEnd();
}


[edit] man, I'm a typo monster.
[edit 2] Just updated the code a bit, removed some things I don't need anymore.

Share this post


Link to post
Share on other sites
Raduprv    997
I can't understand the exact problem from the screenshot, can you post a screenshot (or drawing) on how it is supposed to look?
Anyway, unless your screen size is a power of 2, then you might have some strange results. How big is the screen (x,y) and how big is the texture?

Share this post


Link to post
Share on other sites
OpenGLAaron    122
The screen size is 512 x 512 and the texture size is the same. Maybe I could send you the executable and then you could get a better idea of what's wrong. Actually, I could just post it on my website and anyone could try it out. Give me a few...

Okay, here it is:
http://members.shaw.ca/radrider/painter.zip

Share this post


Link to post
Share on other sites
Raduprv    997
What happens if you remove:

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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

Share this post


Link to post
Share on other sites
OpenGLAaron    122
When I remove those, the screen is just blank, but white.
I've had problems before where not defining the minification and magnification resulted in the texture not working at all.
Hmm. I tried leaving just the minification and magnification settings in, but it does the same thing.

Share this post


Link to post
Share on other sites
Raduprv    997
I tried to run your application, but it needs glut, and I don't have it (and I am too tired right now to go and find it). Anyway, try this: Remove (comment out) all the code in the program except for the code that copies the image to the texture and then make a simple code that displays that texture, but without any fancy things such as multitexxturing, polygon offset, etc. See where the problem is.

Share this post


Link to post
Share on other sites
OpenGLAaron    122
Alright, I updated the .zip file on my webpage. I simplified the project to about as bare as I can possibly make it, but it's still doing that weird thing.
For the project, I removed the explicit inclusion of glut.h, and as far as I can tell, glfw doesn't require the use of glut. So, maybe give it another shot. I can't promise that it will work, though.

Thanks for your help!

[edit] I get the same problem if I replace the glTexSubImage2D call with a glTexImage2D call.

[Edited by - OpenGLAaron on November 25, 2004 12:16:02 AM]

Share this post


Link to post
Share on other sites
Hew T    206
Not sure if you just uploaded a different version, or something... but it appears to work for me. It's currently 'painting' a white square over the black background. If I resize the window it makes, however, things start getting crazy. For example - if I reduce the vertical size of the window slightly (one or two pixels), it displays what I believe is the 'squishing' problem you have.

I suspect there is a mismatch between the 'height' and/or 'width' variables you're using to grab the image, and the actual client-space height/width of the window.

Regards,

Hew T.

Share this post


Link to post
Share on other sites
OpenGLAaron    122
Yeah, for the new version I "disabled" the resizing code. Improperly, mind you, since I simply don't do anything if you resize it.
But you say it works fine otherwise? I wonder if it's a driver issue for me? Mind telling me what hardware you are using, driver, etc?

[edit] when I resize the window, I'm getting all kinds of crazy stuff; all very similar to the "squishing" problem I have by default. Odd.

[edit 2] You are absolutely correct.
GLFW isn't actually setting my window size to 512,512 like I'm requesting; instead, it's setting it to 512,506.
Oh well, thanks for all the help, everyone! I was going to switch over to GLUT tomorrow so I could easily use GLUI anyway...

[Edited by - OpenGLAaron on November 25, 2004 1:09:13 AM]

Share this post


Link to post
Share on other sites
Hew T    206
I don't think it's a driver issue. For the hell of it, I decided to do a screengrab (good ol' PrintScreen!), and dump the grab into Photoshop.

Photoshop tells me the black 'interior' section of your GL window is actually 511 * 511 in size, not 512*512. Herein lies the problem, methinks. I'm not sure what method you're using to create your window, but if the window is smaller than you want, the framebuffer will also be so... and I think glCopyTexSubImage2D will subsequently get a smaller number of pixels... and so on.

Worth a look, anyways.

Regards,

Hew T.

Edit : Beat my reply. Best of luck with GLUT / GLUI.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Similar Content

    • By cebugdev
      hi all,

      i am trying to build an OpenGL 2D GUI system, (yeah yeah, i know i should not be re inventing the wheel, but this is for educational and some other purpose only),
      i have built GUI system before using 2D systems such as that of HTML/JS canvas, but in 2D system, i can directly match a mouse coordinates to the actual graphic coordinates with additional computation for screen size/ratio/scale ofcourse.
      now i want to port it to OpenGL, i know that to render a 2D object in OpenGL we specify coordiantes in Clip space or use the orthographic projection, now heres what i need help about.
      1. what is the right way of rendering the GUI? is it thru drawing in clip space or switching to ortho projection?
      2. from screen coordinates (top left is 0,0 nd bottom right is width height), how can i map the mouse coordinates to OpenGL 2D so that mouse events such as button click works? In consideration ofcourse to the current screen/size dimension.
      3. when let say if the screen size/dimension is different, how to handle this? in my previous javascript 2D engine using canvas, i just have my working coordinates and then just perform the bitblk or copying my working canvas to screen canvas and scale the mouse coordinates from there, in OpenGL how to work on a multiple screen sizes (more like an OpenGL ES question).
      lastly, if you guys know any books, resources, links or tutorials that handle or discuss this, i found one with marekknows opengl game engine website but its not free,
      Just let me know. Did not have any luck finding resource in google for writing our own OpenGL GUI framework.
      IF there are no any available online, just let me know, what things do i need to look into for OpenGL and i will study them one by one to make it work.
      thank you, and looking forward to positive replies.
    • By fllwr0491
      I have a few beginner questions about tesselation that I really have no clue.
      The opengl wiki doesn't seem to talk anything about the details.
       
      What is the relationship between TCS layout out and TES layout in?
      How does the tesselator know how control points are organized?
          e.g. If TES input requests triangles, but TCS can output N vertices.
             What happens in this case?
      In this article,
      http://www.informit.com/articles/article.aspx?p=2120983
      the isoline example TCS out=4, but TES in=isoline.
      And gl_TessCoord is only a single one.
      So which ones are the control points?
      How are tesselator building primitives?
    • By Orella
      I've been developing a 2D Engine using SFML + ImGui.
      Here you can see an image
      The editor is rendered using ImGui and the scene window is a sf::RenderTexture where I draw the GameObjects and then is converted to ImGui::Image to render it in the editor.
      Now I need to create a 3D Engine during this year in my Bachelor Degree but using SDL2 + ImGui and I want to recreate what I did with the 2D Engine. 
      I've managed to render the editor like I did in the 2D Engine using this example that comes with ImGui. 
      3D Editor preview
      But I don't know how to create an equivalent of sf::RenderTexture in SDL2, so I can draw the 3D scene there and convert it to ImGui::Image to show it in the editor.
      If you can provide code will be better. And if you want me to provide any specific code tell me.
      Thanks!
    • By Picpenguin
      Hi
      I'm new to learning OpenGL and still learning C. I'm using SDL2, glew, OpenGL 3.3, linmath and stb_image.
      I started following through learnopengl.com and got through it until I had to load models. The problem is, it uses Assimp for loading models. Assimp is C++ and uses things I don't want in my program (boost for example) and C support doesn't seem that good.
      Things like glVertexAttribPointer and shaders are still confusing to me, but I have to start somewhere right?
      I can't seem to find any good loading/rendering tutorials or source code that is simple to use and easy to understand.
      I have tried this for over a week by myself, searching for solutions but so far no luck. With tinyobjloader-c and project that uses it, FantasyGolfSimulator, I was able to actually load the model with plain color (always the same color no matter what I do) on screen and move it around, but cannot figure out how to use textures or use its multiple textures with it.
      I don't ask much: I just want to load models with textures in them, maybe have lights affect them (directional spotlight etc). Also, some models have multiple parts and multiple textures in them, how can I handle those?
      Are there solutions anywhere?
      Thank you for your time. Sorry if this is a bit confusing, English isn't my native language
    • By dpadam450
      FINALLY, upgrading my engine to openGL 4. I was having some trouble so I started with a stripped down application and was wondering if VAO's are required, because I have a sample working, but if I remove the VAO then it doesn't seem to like drawing my triangle.
  • Popular Now