I want to load an image on the background, I have written following code to load the texture as background by texturing the Rectangle. My image is in power of 2 (512x512). I am not getting why it is not showing anything on the screen,
please help me in this.
I am pasting my code to load the texture and to draw the rect.
Also, I have checked whether the image is loaded properly or not by using SOIL_last_result() and also checked whether there is any error in OpenGL by using glGetError()
Code to load the image as a texture using SOIL
void loadTexture(GLuint* texture, char* path){
*texture = SOIL_load_OGL_texture(path,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
);
cout<<*texture<<endl;
if(*texture == NULL){
printf("Failed to load %s", path);
}
}
Following code is to draw texture and rectangle,
void drawRect(int x, int y, int w, int h, GLuint texture){
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glColor3f(1.0,1.0,1.0);
glBegin(GL_POLYGON);
glTexCoord2i(0,0);
glVertex2i(x,y);
glTexCoord2i(1,0);
glVertex2i(x+w,y);
glTexCoord2i(0,1);
glVertex2i(x,y+h);
glTexCoord2i(1,1);
glVertex2i(x+w,y+h);
glEnd();
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
}
And I am calling it using init mehod,
void initGL(void)
{
glClearDepth(1.0);
glClearColor(0,0,0, 1.0f);
glColor3f(0.0, 0.0, 0.0);
glLineWidth(1);
glDepthFunc(GL_LESS);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
GLuint texture;
loadTexture(&texture, "image.png");
drawRect(0,0,screen_width-100,screen_height-100,texture);
glfwSwapBuffers(window);
}
Please help me and let me know if you need more information.
Thanks in advance!!
The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. It transforms from eye space to the clip space, and the coordinates in the clip space are transformed to the normalized device coordinates (NDC) by dividing with the w component of the clip coordinates. The NDC are in range (-1,-1,-1) to (1,1,1). Every geometry which is out of the clippspace is clipped.
Since you do not set up a projection matrix, you're projection matrix is the identity matrix. This means you will only "see" the geometry, whose coordinates are in the range -1 to 1.
I recommend to setup a orthographic projection matrix (glOrtho). At Orthographic Projection the coordinates in the eye space are linearly mapped to normalized device coordinates and the clip sapce coordinates are equal the normalized device coordiantes.
Set up the projection somehow like this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screen_width, 0, screen_height, -1, 1);
Related
I am trying to create a quick render to texture example using GLdc, a OpenGL implementation for the Sega Dreamcast. I have verified that both my Texture and Framebuffer Object are complete, yet the texture resulting from the framebuffer only has 1 white dot in it.
First, I generate an empty texture and prepare it to be written to.
func genTextures(){
glGenTextures(1, &renderedTexture[0]);
glBindTexture(GL_TEXTURE_2D, renderedTexture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smaller than texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
Next, I generate an FBO and bind the new texture we just created to it.
func genFBO() {
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, renderedTexture[0], 0);
}
At this point the FBO and the Texture should both be considered complete. The main loop is structured something like this:
int main(int argc, char **argv)
{
glKosInit();
InitGL(640, 480);
ReSizeGLScene(640, 480);
genTextures();
genFBO();
while(1) {
if(check_start())
break;
// I checked here for FBO and Texture completeness, both return True.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // bind to the FBO
DrawGLScene(); // Draw our cube to the FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // back to default
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
ReSizeGLScene(640,480);
DrawGLUI(); //Draw the quad with the framebuffers texture
}
return 0;
}
Here are the two functions that draw geometry:
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f); // move 5 units into the screen.
glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotate On The Y Axis
glRotatef(zrot,0.0f,0.0f,1.0f); // Rotate On The Z Axis
glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
glBegin(GL_QUADS); // begin drawing a cube
// Draw my textured cube, works fine.
glEnd(); // done with the polygon.
xrot+=1.5f; // X Axis Rotation
yrot+=1.5f; // Y Axis Rotation
zrot+=1.5f; // Z Axis Rotation
glKosSwapBuffers();
}
void DrawGLUI(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, renderedTexture[0]);
glBegin(GL_QUADS);
//glColor3f(1.0f, 0.0f, 0.0);
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1.0);
glEnd();
glEnable(GL_DEPTH_TEST);
ReSizeGLScene(640,480);
glFlush();
}
The result is
Where I would like to have the cube rendered to a texture then that texture applied to the quad in the upper right corner...
The size of the viewport must be adjusted to the size of the framebuffer with glViewport when the framebuffer is switched:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glViewport(0, 0, 128, 128);
// [...]
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glViewport(0, 0, 640, 480);
// [...]
I'm trying to write an OpenGL/GLSL app that will use GLSL for image processing. I've done some research and come to the conclusion that the right approach is to render to a framebuffer object and then retrieve the image from the gpu. Unfortunately I can't figure out how to set up the frustum and render the quadrilateral so that it fills it properly. Does anyone know how to do this?
You need to render with an orthogonal projection matrix.
glPushMatrix(GL_WORLDVIEW);
glLoadIdentity();
glPushMatrix(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(width, 0);
glVertex2i(width, height);
glVertex2i(0, height);
glEnd();
glPopMatrix();
glMatrixMode(GL_WORLDVIEW);
glPopMatrix();
Width and height are the dimensions of your FBO. Of course they could be both one if you don't need to address special parts of your FBO by drawing quads at pixel positions.
Is it possible to draw something in OpenGL on the drawing scene with giving window pixel coordinates?
For example, I'd like to draw a single point in a 400x400 window (e.g. in the middle of that window). Is there any quick way to set everything up so I could just type:
glVertex3f(200.0 , 200.0 , 1.0);?
You need to set up an orthogonal projection matrix for that first.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0.0f, WindowWidth, WindowHeight, 0.0f, 0.0f, 10.0f);
glMatrixMode(GL_MODELVIEW);
You can then render in window coordinates.
glPointSize(5.0f);
glBegin(GL_POINTS);
glVertex3f(100.0f, 100.0f, 1.0f);
glEnd();
Should render a point with a diameter of 5 pixels on window coordinates [100, 100]
Do note that this old way of rendering is deprecated and you should use VBOs and the like, but it is still good for testing.
I want to create a 3d cube with openGL. Also, I want to cover each side with an image that I transform in a texture.
I find cube coordinates in 2D, and I create a QUADS for each side.
My problem is that when I render textures corresponding cube sides, I see these textures overlap each other, as you can see in this image:
my code is:
Initialization:
glGenTextures(2, textures);
glClearColor (0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_ALWAYS);
Transform image in thexture:
up = imread("up.png");
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, up.cols, up.rows, GL_RGB, GL_UNSIGNED_BYTE, up.data);
Display cube:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// Set Projection Matrix
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, WIDTH, HEIGHT, 0);
// Switch to Model View Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
//sopra
glTexCoord2f(0.0f, 0.0f); glVertex2f((GLfloat)((coord[6].x)),(GLfloat)(coord[6].y));
glTexCoord2f(1.0f, 0.0f); glVertex2f((GLfloat)((coord[5].x)),(GLfloat)(coord[5].y));
glTexCoord2f(1.0f, 1.0f); glVertex2f((GLfloat)((coord[4].x)),(GLfloat)(coord[4].y));
glTexCoord2f(0.0f, 1.0f); glVertex2f((GLfloat)((coord[7].x)),(GLfloat)(coord[7].y));
glEnd();
I do the same for the other sides of the cube.
The order in which I render textures is:
bottom (ground) side
up side
behind side
front side
left side
right side
what is wrong or what am I missing? Or, Maybe cannot create a 3d cube with 2d coordinates (glVertex2f (...))?
Thanks for your help!
You can't create a cube with 2d coordinates. The sides are overlapping because they are all on the same plane in space. A cube is in 3d space so needs 3 coordinates, x, y, and z.
So try using:
glVertex3f(x, y, z);
and use some appropriate z values depending on where you want each face.
For the texture you can still use:
glTexCoord2f(x, y);
since the textures are in 2 dimensional space.
If you are still confused about what to use for your coordinates I suggest you read this to help you understand 3d space in openGL:
http://www.falloutsoftware.com/tutorials/gl/gl0.htm
I'm trying to draw a 2d character sprite on top of a 2d tilemap, but when I draw the character he's got odd stuff behind him. This isn't in the sprite, so I think its the blending.
This is how my openGL is set up:
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
{
glViewport(0, 0, Width, Height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glDisable(GL_DEPTH_TEST); // Enables Depth Testing
//glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
glShadeModel(GL_FLAT);
glMatrixMode(GL_PROJECTION);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glAlphaFunc(GL_GREATER, 0.5f);
glMatrixMode(GL_PROJECTION);//configuring projection matrix now
glLoadIdentity();//reset matrix
glOrtho(0, Width, 0, Height, 0.0f, 100.0f);//set a 2d projection matrix
}
How should I set this up to work properly (i.e. drawing the sprite without odd stuff behind him.
This is what I am talking about: http://i.stack.imgur.com/cmotJ.png
PS: I need to be able to put transparent/semi-transparent images on top of each other and have whats behind them visible too
Does your sprite have premultiplied alpha? Your glBlendFunc setup is a little unusual, if you don't have premultiplied alpha it could definitely be causing the issue.