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.
Related
I need to create a 3d cube, and so far I've created all the vertices but when I run the program I can only see the cube (or what I hope is a cube, I can't tell) from one face, so it looks like a square. I want to know how to view my cube from above, so I can check whether or not it actually looks the way I want it to.
I created the 24 vertices using glVertex3f but like I said I can't tell if it is a cube or not because I cannot look at it from an angle other than the default.
I tried downloading GLM but I am very confused on how, if at all, to use that to change the viewing perspective.
glEnable(GL_DEPTH_TEST);
// Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
// Render here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
... // Repeating drawing the vertices for each vertex of the cube
glEnd();
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
No error messages but I cant tell if its a cube or not.
// Render here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// need the window width & height to compute aspect ratio
int width, height;
glfwGetWindowSize(window, &width, &height);
// set up the camera projection (if you haven't done this in init)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, float(width) / height, 0.1f, 100.0f);
// set camera position & orientation
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1, 1, -3, //< eye position
0, 0, 0, //< aim position
0, 1, 0); //< up direction
// now draw stuff
glBegin(GL_QUADS);
glEnd();
I'm currently trying to color some rectangles to represent collision boxes for my game character. The issue is the color I'm trying to apply ONLY to the rectangles are being applied to my character and background textures as well. So if I draw a rect using the following code:
void DrawRect(v2f MinPoint, v2f MaxPoint)
{
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f); //Red color
glVertex2f(MaxPoint.x, MaxPoint.y);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(MinPoint.x, MaxPoint.y);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(MinPoint.x, MinPoint.y);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(MaxPoint.x, MinPoint.y);
glEnd();
glFlush();
}
Then right after draw my background texture:
void DrawBackground(ui32 TextureID, Drawable_Rect BackgroundImage, v2f MinUV, v2f MaxUV)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureID);
glBegin(GL_QUADS);
glTexCoord2f(MinUV.x, MinUV.y);
glVertex2f(BackgroundImage.BottomLeft.x, BackgroundImage.BottomLeft.y);
glTexCoord2f(MaxUV.x, MinUV.y);
glVertex2f(BackgroundImage.BottomRight.x, BackgroundImage.BottomRight.y);
glTexCoord2f(MaxUV.x, MaxUV.y);
glVertex2f(BackgroundImage.TopRight.x, BackgroundImage.TopRight.y);
glTexCoord2f(MinUV.x, MaxUV.y);
glVertex2f(BackgroundImage.TopLeft.x, BackgroundImage.TopLeft.y);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
Then both my rectangle AND my background are red instead of just my rectangle. Why is the color being applied to both my rectangle and my texture?
If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
This causes that the color of the texels of the texture is "mixed" by the last color which you have set by glColor3f:
Set a "white" color before you render the texture, to solve your issue:
glColor3f(1.0f, 1.0f, 1.0f);
Likewise you can change the environment mode to GL_REPLACE, instead:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Question:
I am trying to map a single 2D image to a 3D texture. When I visualize the output, OpenGL renders a white texture floating in black background. Why is this happening? Is it possible to map a 2D image to a 3D texture?
My goal is to place multiple 2D images along the z-dimension to resemble a volume. An example of such an approach is in this video: http://cvlab.epfl.ch/research/medical/em/synapses
Approaches attempted:
I took 2D images and mapped them to 2D textures. I have also used 2D texture arrays. Both of these approaches provide a good result. However, when I tried to paint the surface of a 3D texture with the same image, I get a white texture floating around in a black space.
Code
I have followed the texture mapping tutorial that is available on NeHe's website.
http://nehe.gamedev.net/tutorial/lesson_06_texturing_update/47002/
Except changes to these three functions, everything else in the program (present in the solution file in the website) is the same.
... // header file declarations
#include <glext.h>
PFNGLTEXIMAGE3DPROC glTexImage3D;
GLuint texture;
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
/* load an image file directly as a new OpenGL texture */
texture = SOIL_load_OGL_texture("Data/NeHe.bmp",SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,S OIL_FLAG_INVERT_Y);
// "Data/NeHe.bmp"
if(texture == 0) {return false;}
glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
if (glTexImage3D == NULL)
{
printf("Error in line %d: Couldn't load glTexImage3D function. Aborting.\n", __LINE__);
return -1;
}
glBindTexture(GL_TEXTURE_3D, texture);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4096, 4096, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
return true;
}
int InitGL(GLvoid)
{
if (!LoadGLTextures())
{ return FALSE; }
glEnable(GL_TEXTURE_3D);
// glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); //
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective calculations
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
// glBindTexture(GL_TEXTURE_2D, texture[0]);
glBindTexture(GL_TEXTURE_3D, texture);
glBegin(GL_QUADS);
glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
return TRUE;
}
...
It is better to use 3D textures instead of 2D ones as you will be able to apply rotations correctly using glRotate(). You will also need to do blending and/or alpha-testing to see different layers of your 2D image.
To create a 3D texture, you can create an array of dimension [width x height x number_of_slices] and then store the raw data slice by slice
Look at this tutorial: http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering?msg=4729498#xx4729498xx
It's very good and it worked for me to do the same thing
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 called this function once per frame and it took my FPS from >400 to 33. Why?
sw blt(const PtRect *dstRect, Texture *src, const PtRect *srcRect, RenderDevice::bltFlags flags=RenderDevice::bltDefault)
{
assert(src);
GL_Texture *glsrc = dynamic_cast<GL_Texture*>(src);
if (glsrc == 0)
return -1;
PtRect srcRect2(0, 0, src->width, src->height);
if (srcRect == 0)
srcRect = &srcRect2;
PtRect dstRect2(0, 0, srcRect->makeWidth(), srcRect->makeHeight());
if (dstRect == 0)
dstRect = &dstRect2;
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, *glsrc->getTex());
glBegin( GL_QUADS );
glNormal3f( 0.0f, 0.0f, 1.0f );
for (size_t i=0; i<350; i++)
{
glTexCoord2f( srcRect->left /src->width, srcRect->top/src->height); glVertex2f(dstRect->left, dstRect->top);
glTexCoord2f( srcRect->right/src->width, srcRect->top/src->height); glVertex2f(dstRect->right, dstRect->top);
glTexCoord2f( srcRect->right/src->width, srcRect->bottom/src->height); glVertex2f(dstRect->right, dstRect->bottom);
glTexCoord2f( srcRect->left /src->width, srcRect->bottom/src->height); glVertex2f(dstRect->left, dstRect->bottom);
}
glEnd();
return 0;
}
Hard to say without more details, potential problems could be using a too large texture, causing software fallbacks in your driver. Also you appear to loop 350 times for no obvious reason.
You may be able to improve performance by building an array of data and then calling glDrawArrays instead of issuing each glTexCoord/glVertex pair individually
For performance you should load your textures in an init function and use a list to display then later on the main render function, for example:
// Generate texture object ID
glGenTextures(1, img);
glBindTexture(GL_TEXTURE_2D, img);
// Set Texture mapping parameters
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
LoadBMP("texture.bmp");
Then on the main render function you have something like:
// Front face of Cube
glBindTexture(GL_TEXTURE_2D, img);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-fSize, fSize, fSize);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-fSize, -fSize, fSize);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(fSize,-fSize, fSize);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(fSize,fSize, fSize);
glEnd();
As you can see you can wrap the texture on the parameters instead of repeating it over and over in a loop.
Maybe you are not using Textures with of a power of 2 (e.g. 1024x768 instead of 1024x512)?
It looks like you draw the quad onto the screen 350 times for some reason. If this is full screen, then texturing every pixel on the screen 350 times a frame is bound to damage your performance.