I'm trying to display the texture on the window using openGL. However, the texture is only mapping to the bottom left of my window and it cuts off! output
Here is my code:
Texture:
GLuint textureID[1];
GLubyte Image[1024*768*4];
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1,textureID);
glBindTexture(GL_TEXTURE_2D, textureID[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 1024, 768, 0, GL_RGBA, GL_UNSIGNED_BYTE, Image);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
Quad:
glPushMatrix ();
glTranslatef(0, 0.0, -1.1);
glMaterialf(GL_FRONT, GL_SHININESS, 30.0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureID[0]);
glViewport(-511,-383,1025,768);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2d(1.0, 0.0); glVertex2f(1024.0, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2f(1024.0, 768.0);
glTexCoord2d(0.0, 1.0); glVertex2f(0.0, 768.0);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix ();
glFlush ();
I'm trying to map the texture into my window. Both of my window and texture have the size of 1024x768. What did I do wrong? If I comment out glViewport, the texture will be mapped to top right.
The reason why your image gets cut off are the values supplied to glViewport. This function specifies to which area of the screen the rendering should go. So if you set the x-value to -511 and the width to 1025, then the drawing will happen from pixel -511 to 514, which is exactly what you see.
What you actually want to get the image to your desired position is a projection (most probably an orthographic one), that maps you input coordinates to the appropriate normalized device coordinates (NDC). When not using projections OpenGL works in this NDC coordinates ranging from -1 to 1 on each axis and not, as you assumed, in pixel coordinates.
Your viewport parameters are invalid for your particular desires (negative values for x,y). Also likely you didn't specify a projection / modelview matrix pair that maps local coordinates to pixels (at least not in the code shown), yet the coordinates you pass to glVertex look like you want to address pixels.
Related
I'm using opengl to draw the graphics for simple game like space invaders. So far I have it rendering moving meteorites and a gif file quite nicely. I get the basics. But I just cant get the framebuffer working properly which I indent to render bitmap font to.
The first function will be called inside the render function only when the score changes, This will produce a texture containing the score characters. The second function will draw the texture containing the bitmap font characters to the screen every time the render function is called. I thought this would be a more efficient way to draw the score. Right now I'm just trying to get it drawing a square using the frameBuffer, but it seems that the coordinates range from -1 to 0. I thought the coordinates for a texture went from 0 to 1? I commented which vertex effects which corner of the square and it seems to be wrong.
void Score::UpdateScoreTexture(int* success)
{
int length = 8;
char* chars = LongToNumberDigits(count, &length, 0);
glDeleteTextures(1, &textureScore);//last texture containing previous score deleted to make room for new score
glGenTextures(1, &textureScore);
GLuint frameBufferScore;
glGenTextures(1, &textureScore);
glBindTexture(GL_TEXTURE_2D, textureScore);
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffers(1, &frameBufferScore);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferScore);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureScore, 0);
GLenum status;
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
std::cout << "status is: ";
std::cout << "\n";
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE:
std::cout << "good";
break;
default:
PrintGLStatus(status);
while (1 == 1);
}
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferScore);
glBegin(GL_POLYGON);
glVertex3f(-1, -1, 0.0);//appears to be the bottom left,
glVertex3f(0, -1, 0.0);//appears to be the bottom right
glVertex3f(0, 0, 0.0);//appears to be the top right
glVertex3f(-1, 0, 0.0);//appears to be the top left
glEnd();
glDisable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D,0);
glDeleteFramebuffers(1, &frameBufferScore);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, chars2);
}
void Score::DrawScore(void)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, textureScore);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.7, 0.925, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.7, 0.975, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.975, 0.975, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.975, 0.925, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
Any ideas where I'm going wrong?
You have not set the glViewport, this may give you problems.
Another possibility is that you have the matrix set to something other than identity.
Ensure that you have reset the model-view and projection matrices to identity (or what you want them to be) before glBegin(GL_POLYGON) in UpdateScoreTexture() (You may wish to push the matrices to the stack before you make changes):
glViewport(0,0, framebufferWidth, framebufferHeight)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
Then put them back at the end of the function:
glViewport(0,0, width, height)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
I'm trying to display a 128x128 array of floats (0.0 -> 1.0) as a texture of green on black within a legacy FLTK application. The rest of the application uses immediate mode for all it's drawing, so I don't want to change the way it works. From reading tutorials, I've come up with the following calls that should be sufficient to load the texture into graphics memory, and draw it to the current context (managed by FLTK). However, all I can get it to do is draw a black square where the texture should be, drawing over anything else that has been drawn there (GL_LINES).
Is there anything basic that I'm missing here? some initialization step that I've neglected? Thanks in advance. Here the code that I'm trying to get running:
// Part of class init
glGenTextures(1, &tex);
// As far as I can tell, this is optional with FLTK having already
// set these parameters. Omitting them does not change output.
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODEL);
glLoadIdentity();
// This is the meat of the problem. reports no GL errors.
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_FLAT);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_GREEN, GL_FLOAT, &image);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2f(-0.9,-0.9);
glTexCoord2d(0,1); glVertex2f(-0.9, 0.9);
glTexCoord2d(1,0); glVertex2f( 0.9,-0.9);
glTexCoord2d(1,1); glVertex2f( 0.9, 0.9);
glEnd();
glDisable(GL_TEXTURE_2D);
// Again, busywork.
glPopMatrix();
I'm trying to understand how to load a texture in OpenGL and I wrote this very simple code:
GLuint texture;
void loadTexture() {
GLubyte data[] = { 255,0,0,
0,255,0,
0,255,0,
255,0,0 };
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
int chk = gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, 2, 2, GL_RGB, GL_UNSIGNED_BYTE, data );
if (chk!=0)
printf("error code = %d\n",chk);
else
printf("success\n");
}
I use loadTexture() to load the texture in memory. The texture, in this sample, is extremely simple, but at the moment it doesn't matter.
void drawTexturedSquare() {
glEnable( GL_TEXTURE_2D );
glBegin (GL_QUADS);
glTexCoord2f (0.0, 0.0);
glNormal3f(0, 0, 1);
glVertex3f (0.0, 0.0, 0.0);
glTexCoord2f (1.0, 0.0);
glNormal3f(0, 0, 1);
glVertex3f (10.0, 0.0, 0.0);
glTexCoord2f (1.0, 1.0);
glNormal3f(0, 0, 1);
glVertex3f (10, 10, 0.0);
glTexCoord2f (0.0, 1.0);
glNormal3f(0, 0, 1);
glVertex3f (0.0, 10, 0.0);
glEnd ();
glDisable( GL_TEXTURE_2D);
}
I would like to apply this simple texture to a square. I call function drawTexturedSquare() from inside a draw() function where I already called
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
The problem is that this is the result I get
while I expected the square to be green in main diagonal (upper-left to lower-right) and red is secondary diagonal (upper-right to lower-left). May someone explain me why?
Besides, every time I run the program I get a different result:
I do not understand where this blue comes out...May someone help me?
Each row of your data needs to be 4-byte aligned. Either pad each row with 0 0, or use a RGBA texture.
If you don't want to do the aforementioned, you can use:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
The reason your color is changing is that since you don't pad your rows correctly, OpenGL reads past the end of the array.
You may want to try GL_NEAREST for GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER
As it is right now, OpenGL is interpolating between the colors, creating a gradient (since your texture is being stretched from 2x2 to however big your screen is)
This doesn't explain why you're getting different results for your texture each time though.
I am trying to draw a partly-transparent texture above a coloured quad, so that the colour shines through the transparent part, making an outline. This is the code:
// Setup
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// (...)
// Get image bits in object 't'
glBindTexture(GL_TEXTURE_2D, textureIDs[idx]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits());
// (...)
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Underlying coloured quad
glColor4d(0.0, 1.0, 0.0, 1.0);
glBindTexture(GL_TEXTURE_2D, 0);
glBegin(GL_QUADS);
glVertex3d(coords11.first, coords11.second, -0.001);
glVertex3d(coords12.first, coords12.second, -0.001);
glVertex3d(coords21.first, coords21.second, -0.001);
glVertex3d(coords22.first, coords22.second, -0.001);
glEnd();
// Textured quad
glColor4d(1.0, 1.0, 1.0, 0.5);
glBindTexture(GL_TEXTURE_2D, textureIDs[castleTextureIndices[0]]);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex3d(coords11.first, coords11.second, 0);
glTexCoord2d(1.0, 0.0); glVertex3d(coords12.first, coords12.second, 0);
glTexCoord2d(1.0, 1.0); glVertex3d(coords21.first, coords21.second, 0);
glTexCoord2d(0.0, 1.0); glVertex3d(coords22.first, coords22.second, 0);
glEnd();
The texture is black except where it has the outline of a castle; that part is transparent (and white). The expected behaviour, therefore, is a black rectangle with a green outline. What I get instead is a greenish rectangle with a white outline:
Screenshot
That's with alpha on the textured quad set to 0.5. If instead I set it to 1.0, I get back the texture with no transparency, as in (oh well, can't post the second screenshot as a link; it's at s330.photobucket.com/albums/l412/TWBWar/?action=view¤t=replace10.png). With alpha of 0, I get a green rectangle. It therefore seems to me that the textured quad is being blended using the alpha value set by glColor4d, instead of the value from the texture, which is what I expected from GL_REPLACE. (I experimented with GL_DECAL and GL_MODULATE as well, but I wasn't able to get the behaviour I wanted.) Can anyone tell me how to make OpenGL use the texture, not the quad, alpha for blending?
Get ready for a trip down memory lane.
glTexImage2D(GL_TEXTURE_2D, 0, 3, ..., ..., 0, GL_RGBA, GL_UNSIGNED_BYTE, ...);
That 3 in there is your problem. The right part of the arguments (RGBA+UNSIGNED_BYTE) mentions what your source data type is. the destination data type is the third argument (i.e. what GL will store your texture as).
As it happens, when GL 1.0 was created, texturing was somewhat simpler. So the parameter only was required to specify the number of channels you wanted for your final texture, with the mapping
1=GL_LUMINANCE
2=GL_LUMINANCE_ALPHA
3=GL_RGB
4=GL_RGBA
I believe this use is discouraged, but as you can see, still works.
So... Your texture is stored as GL_RGB, without alpha.
The rest is simple application of the spec. A replace on a texture with internal format RGB does final_color=texture_color and final_alpha=fragment_alpha (aka the source from glColor in your case). See this man page for the full tables of texture environment based on internal formats.
I'm new to opengl and have been able to learn a lot on my own, but i am stuck on this one.
I have a room rendered, but I need a sphere that hovers in the center reflecting everything else perfectly. So far, I've been able to cube map to it with pretty good results, but the 6 textures are all the same: namely, the view I have of the room. I am calling gluLookAt to reposition the camera to where the sphere is going to be, and look at its surroundings, then I make a call to glCopyTexImage2D to get that loaded into the appropriate texture, but I can't get 6 different perspectives loaded... just the one, six times.
here's the relevant code if you can look through it and help me out, i will love you forever :)
void drawReflectiveSphere(){
glEnable(GL_TEXTURE_CUBE_MAP);
float pos[] = {10.0, 1.0, -40.0};
float x_pos [] = {pos[0] + 1, pos[1], pos[2]};
float x_neg [] = {pos[0] - 1, pos[1], pos[2]};
float y_pos [] = {pos[0], pos[1] + 1, pos[2]};
float y_neg [] = {pos[0], pos[1] - 1, pos[2]};
float z_pos [] = {pos[0], pos[1], pos[2] + 1};
float z_neg [] = {pos[0], pos[1], pos[2] - 1};
float view_pos[][3] = {x_pos[0], x_neg[0], y_pos[0], y_neg[0], z_pos[0], z_neg[0]};
glGenTextures(1, &cubemap);
glReadBuffer(GL_BACK);
//Use different frustum
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glFrustum(-5.0, 5.0, -5.0, 5.0, 0.0, width + 10.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, 128, 128);
//Generate cube map textures
for(int i = 0; i < 6; i++){
glPushMatrix();
gluLookAt(pos[0], pos[1], pos[2],
view_pos[i][0], view_pos[i][1], view_pos[i][2],
0.0, -1.0, 0.0);
glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 0, 0, 128, 128, 0);
glPopMatrix();
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
//Restore viewport
glViewport(0, 0, W, H);
//Draw cube-mapped sphere
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]);
gluSphere(quadratic, 5.0f, 128, 128);
glPopMatrix();
//Restore projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_CUBE_MAP);
}
(It's been a while since I've done any graphics programming, so I may be totally off base.)
glCopyTexImage2D copies from the current GL_READ_BUFFER, which is not getting modified by your gluLookAt calls. I don't think this approach is going to work; you're sending a bunch of drawing commands, copying the pixels to a texture, using gluLookAt to change the view and expecting all of the previous drawing commands to still be hanging around. You're going to need to repeat all of the drawing for each perspective and copy into a single texture after each one. Then to actually use your cube map, you'll need to redraw the entire scene again, and then draw the sphere with the cube map.
You're also drawing to the screen, or whatever it's called (the default color buffer?), and then copying it into a texture. That's fine for a simple program, but you'd really want to render directly to your textures, and only draw the final result. (Especially when they're wildly different sizes.)