I'm doing an SDL/OpenGL project on MinGW Windows Code::Blocks 12.11, using GLEW. I'm trying to implement 2D off-screen rendering, so that I can eventually try some fragment shader effects.
Here is the scene rendered to the default framebuffer:
However, if I render the scene to a Framebuffer Object's texture (called fbo_texture) and then try and render that to a full-screen quad, I get this:
The image appears flipped, mirrored and green. I'm pretty sure that the rendering to the Framebuffer is working correctly, but for the life of me I can't figure out why the texture is appearing so skewed.
Here is how I tried to render fbo_texture to a textured quad, after calling glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0). I am using glMatrixMode(GL_MODELVIEW) and glOrtho(0, screen_width, screen_height, 0, 0, 1) when the program initializes. Screen_width is 400 and screen_height is 400.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glBegin(GL_QUADS);
x1= 0.5;
x2= 400.5;
y1= 0.5;
y2 = 400.5;
glTexCoord2f(0.0f, 0.0f); glVertex2f(x1, y1);
glTexCoord2f(1.0f, 0.0f); glVertex2f(x2, y1);
glTexCoord2f(0.0f, 1.0f); glVertex2f(x2, y2);
glTexCoord2f(1.0f, 1.0f); glVertex2f(x1, y2);
glEnd();
glDisable(GL_TEXTURE_2D);
I really appreciate any help, please let me know if I should provide any more information.
This might not be your only problem, but from the part you show, two vertices are swapped in your texture coordinates. The 3rd of the 4 vertices is the top-right corner, with coordinates (x2, y2), so it should have texture coordinates (1.0f, 1.0f):
glTexCoord2f(0.0f, 0.0f); glVertex2f(x1, y1);
glTexCoord2f(1.0f, 0.0f); glVertex2f(x2, y1);
glTexCoord2f(1.0f, 1.0f); glVertex2f(x2, y2);
glTexCoord2f(0.0f, 1.0f); glVertex2f(x1, y2);
You're also saying that you call glOrtho() after glMatrixMode(GL_MODELVIEW). glOrtho() sets a projection matrix, so it should normally be called after glMatrixMode(GL_PROJECTION).
Related
I am facing the problem of rendering the correct image with some portion of the edges cropped out. I can observe this only for non-standard aspect ratio.
In my case width is 1228 and height is 972 which is yielding an aspect ratio of 1.26.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glClearColor(0.0, 0.0, 0.0, 1.0);
float vx = float(m_uiImageWidth) / float(m_uiImageWidth);
float vy = float(m_uiImageHeight) / float(m_uiImageWidth);
glEnable(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, 3, m_uiImageWidth, m_uiImageHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, m_arrayBufferVS1);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, m_texture);
//glTranslatef(0.0f, 0.0f, -1.36f);
glTranslatef(0.0f, 0.0f, -1.358f);
//Normal
if(m_bContextMenuNormal)
glRotatef(180, 1, 0, 0);
else if (m_bContextMenuRotate180 && m_bContextMenuMirror)
{
//do nothing
}
else if(m_bContextMenuMirror)
glRotatef(180, 0, 0, 0);
else if(m_bContextMenuRotate180)
glRotatef(180, 0, 1, 0);
glScalef(1, -1, 1);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); //top right
glVertex3f(vx, vy, 0.0f);
glTexCoord2f(0.0f, 1.0f); // left top
glVertex3f(-vx, vy, 0.0f);
glTexCoord2f(0.0f, 0.0f); //left bottom
glVertex3f(-vx, -vy, 0.0f);
glTexCoord2f(1.0f, 0.0f); //right bottom
glVertex3f(vx, -vy, 0.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
This is my code snippet. It would be a great help if anyone points out the mistake I have made and suggestions to fix.
modify your calls to glTexCoord2f, the decimal values are interpolated between the four vertexes and then multiplied by the width and height of the image to calculate the coordinates of each pixel from the texture to draw to the screen. if you want to crop the left and right of your image with an aspect ratio of 1.26 into a square you would use the following texture coordinates:
glTexCoord2f(1.0f - 0.13f, 1.0f); //top right
glTexCoord2f(0.0f + 0.13f, 1.0f); // left top
glTexCoord2f(0.0f + 0.13f, 0.0f); //left bottom
glTexCoord2f(1.0f - 0.13f, 0.0f); //right bottom
0.13 * 1228 is 159.64 pixels, and when you remove 159.64 pixels from either side of your 1228 pixel wide texture the remaining portion of the image is 972 pixels wide, meaning the aspect ratio of the pixels drawn will be 1:1 because your texture is 972 pixels tall
If i comment out DrawGLScene(), i see a large shaded triangle, if I comment out drawtri() i see a square texture drawn. But I am not able to combine both - when both func's are called, I see only triangle outline and the texture is rendered with a strong red filter applied.
What could be the problem?
void DrawGLScene()
{
int x, y;
float float_x, float_y, float_xb, float_yb;
float x0=0,y0=0,x1=10,y1=10,z=-3;
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glEnable(GL_TEXTURE_2D);
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-12.0f); // move 12 units into the screen.
glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
glPolygonMode(GL_BACK, GL_FILL);
glPolygonMode(GL_FRONT, GL_LINE);
glBegin(GL_QUADS);
glTexCoord2f( 0,0);
glVertex3f( x0, y0, z );
glTexCoord2f( 0, 1 );
glVertex3f( x0, y1, z );
glTexCoord2f( 1, 1);
glVertex3f( x1, y1, z );
glTexCoord2f( 1, 0 );
glVertex3f( x1, y0,z );
glEnd();
glDisable(GL_TEXTURE_2D);
// since this is double buffered, swap the buffers to display what just got drawn.
// glutSwapBuffers();
}
void drawtri() {
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
}
void zdisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
glLoadIdentity();
glTranslatef(0.0f,0.0f,-3.0f);
//drawtri();
DrawGLScene();
glutSwapBuffers();
}
The red filter is caused by the applied color:
glColor3f(0.0f,0.0f,1.0f);
Reset the color to white before drawing the quad:
glColor3f(1.0f,1.0f,1.0f);
The outline is caused by the following specification:
glPolygonMode(GL_FRONT, GL_LINE);
Specify fill mode:
glPolygonMode(GL_FRONT, GL_FILL);
When calling both functions, did you actually call the methods in the order in which the code shows them? Because I suspect that the order was reversed. If I'm right, I think you must reset the glPolygonMode when drawing the triangle. Try adding glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) before the call to glBegin(GL_TRIANGLES).
I am new to GLFW and made a simple texture mapping program. Problem is while running the program the memory resource increases non stop which I can see clearly in taskmanager.
After running the program for a few minutes, my computer's fan speeds up and a heating problem occurs. How can I fix this problem?
Here is code for texture loading function
GLuint LoadTexture(const char* TextureName)
{
GLuint Texture; //variable for texture
glGenTextures(1,&Texture); //allocate the memory for texture
glBindTexture(GL_TEXTURE_2D,Texture); //Binding the texture
if(glfwLoadTexture2D(TextureName, GLFW_BUILD_MIPMAPS_BIT)){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
return Texture;
}else return -1;
}
Here is code for draw function
void display()
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); //clear background screen to black
//Clear information from last draw
glClear( GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0f,0.0f,-35.0f); //Translate whole scene to -ve z-axis by -35 unit
GLuint text2D;
text2D = LoadTexture("cicb.tga"); //loading image for texture
glEnable(GL_TEXTURE_2D); //Enable texture
glBindTexture(GL_TEXTURE_2D,text2D);//Binding texture
glPushMatrix();
glBegin(GL_POLYGON); //Begin quadrilateral coordinates
glNormal3f(0.0f, 0.0f, 1.0f);//normal vector
glTexCoord2f(0.0f, 0.0f); //Texture co-ordinate origin or lower left corner
glVertex3f(-10.0f,-11.0f,5.0f);
glTexCoord2f(1.0f, 0.0f); //Texture co-ordinate lower right corner
glVertex3f(10.0f,-11.0f,5.0f);
glTexCoord2f(1.0f, 1.0f);//Texture co-ordinate top right corner
glVertex3f(10.0f,-1.0f,-15.0f);
glTexCoord2f(0.0f, 1.0f);//Texture co-ordinate top left corner
glVertex3f(-10.0f,-1.0f,-15.0f);
glEnd(); //End quadrilateral coordinates
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,text2D);
glPushMatrix();
glBegin(GL_POLYGON);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);//Texture co-ordinate origin or lower left corner
glVertex3f(-10.0f,-1.0f,-15.0f);
glTexCoord2f(10.0f, 0.0f); //Texture co-ordinate for repeating image ten times form
//origin to lower right corner
glVertex3f(10.0f,-1.0f,-15.0f);
glTexCoord2f(10.0f, 10.0f);//repeat texture ten times form lower to top right corner.
glVertex3f(10.0f,15.0f,-15.0f);
glTexCoord2f(0.0f, 10.0f);//repeat texture ten time form top right to top left corner.
glVertex3f(-10.0f,15.0f,-15.0f);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D); //Disable the texture
glfwSwapBuffers();
}
If anyone want to see the problem by running exe then I can provide download link.
You seem to be loading your texture each time you call display(). (Once per frame in essence) I assume that is what is taking all your memory at some point. You just want to do this once outside of your display function.
I'm rendering textures on the two surfaces which actually have the same location and position.
In these kind of cases I want to display only one of the textures, while I get following
I.e. I want only the texture of first material to be displayed.
So I would like to know where I've to search for solution, should I play with the blending of the materials ?
This is a pretty old issue (z-fighting) as the card isn't sure which object to draw in front. The linked Wikipedia article has more examples of this.
To fix this, increase the depth buffer's accuracy (bit depth), reduce the depth of your view (distance far/near clip plane) or add a tiny offset so the coordinates are no longer exactly (or almost) the same. You could as well simply disable the depth buffer (or clear it) for rendering this (in which case whatever is rendered last will overlap everything else).
You mean you want to display few textures at one time? Use multi texturing then. Attach both textures to one Quad using:
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
And play with glTexEnvi to combine them as you want. If you want to show only one of your textures then draw two quads with separate textures on each of them. And quad witch will be drawn later will be visible. Then if you want to turn from one to another, make separate -(void)'s for each of quad, with glClearColor before each quad drawing and then make button to call for example -(void)quad1 and button to call -(void)quad2.
Or just use depth buffer.
At your situation i would use multi texturing, because all buffers looked too hard for me all time.
I will show how would my code look like.
Code using multi texture:
glClear(GL_COLOR_BUFFER_BIT);
//Turn on blending and set glBlendFunc for your needs
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Describing multitexturing
glClientActiveTexture(GL_TEXTURE0_ARB); //Activating texture on unit 0
glActiveTexture(GL_TEXTURE0_ARB); //Activating texture on unit 0
glBindTexture(GL_TEXTURE_2D, Texture1); //Bind texture on unit 0
glEnable(GL_TEXTURE_2D); //Enable GL_TEXTURE_2D to set it's glTexEnvi for your needs
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); //Edit glTexEnvi for your needs (link bellow code)
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE );
glClientActiveTexture(GL_TEXTURE1_ARB); //Activating texture on unit 1
glActiveTexture(GL_TEXTURE1_ARB); //Activating texture on unit 1
glBindTexture(GL_TEXTURE_2D, Texture2); //Bind texture on unit 0
glEnable(GL_TEXTURE_2D); //Enable GL_TEXTURE_2D to set it's glTexEnvi for your needs
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); //Edit glTexEnvi for your needs (link bellow code)
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE );
//Drawing quad with multi texture
glBegin(GL_QUADS);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f); //Texture on unit 1 coords
glVertex2f(0.0, 500);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f); //Texture on unit 1 coords
glVertex2f(0.0, 0.0);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f); //Texture on unit 1 coords
glVertex2f(800, 0.0);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f); //Texture on unit 0 coords
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f); //Texture on unit 1 coords
glVertex2f(800, 500);
glEnd();
//Disable GL_TEXTURE_2D. We don't need it anymore
glDisable(GL_TEXTURE_2D);
//Disable blending
glDisable(GL_BLEND);
//Flush everything
glFlush();
Code for using one quad for each texture
-(void) drawQuad1
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture1);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 500);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(800, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(800, 500);
glEnd();
glDisable(GL_TEXTURE_2D)
glFlush();
}
-(void) drawQuad2
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture2);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 500);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(800, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(800, 500);
glEnd();
glDisable(GL_TEXTURE_2D)
glFlush();
}
//and now when you want to draw `drawQuad1` you need to do `[self drawQuad1];`
//and where you want to draw `drawQuad2` you need to do `[self drawQuad2];`
Info about glTexEnvi here. Its just sample code. Fast written so could have mistakes. Sorry if i forgot something. Just i haven't been doing it for long time. Written it on Mac OS X, so if you are using other platform maby you will have to change few things (not opengl). And about depth buffer? I don't know how to use it. So I can't explain it for you. Sorry. Never used them.
I am creating a texture from a pango layout and mapping the texture to the screen using OpenGL and GLUT. I want to scroll the texture in the window. I'm not concerned with the controls to scroll, but how do I cause map the portion of the texture I want to see onto the screen? I assume I use glTranslate, but where do I apply it?
Thanks in advance.
Here is what I currently do:
glEnable(GL_TEXTURE_2D);
{
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f( 0.0f+x, 0.0f+y);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_width+x, 0.0f+y);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_width+x, _height+y);
glTexCoord2f(0.0f, 1.0f); glVertex2f( 0.0f+x, _height+y);
}
glEnd();
}
glFlush();
glDisable(GL_TEXTURE_2D);
Another way would be to use a texture matrix (matrix mode GL_TEXTURE) or do it in a shader.
Depends on how many vertices would have to be modified. If just a few it could be more performant but for many vertices a texture matrix/shader approach could be better. Note that built in matrix operations are deprecated, i.e. it now is recommended to use textures.
Scrolling in a shader would be easy: out.tex = in.tex + offset where offset could be a uniform which is set per frame or be calculated from other input.
Since your example uses immediate mode, I'll expand it with the texture matrix mode.
But please be aware that this is deprecated methodology.
glEnable(GL_TEXTURE_2D);
{
glMatrixMode(GL_TEXTURE);
glLoadIndentity();
glTranslatef(x,y,0);
glMatrixMode(GL_MODELVIEW);
glBegin(GL_QUADS);
{
glTexCoord2f(0.0f, 0.0f); glVertex2f( 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_width, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_width, _height);
glTexCoord2f(0.0f, 1.0f); glVertex2f( 0.0f, _height);
}
glEnd();
}
glFlush();
glDisable(GL_TEXTURE_2D);
Unless you also want to tile I would just modify the UV coordinates of the vertices you are outputting. Then you just change the coordinates you feed to glTexCoord2f to specify a crop.
There is also a nice example of texture transformations here http://potatoland.org/glart/week5/GLART_5_texture_samples.java (it's java but you can easily translate it to C)