How to draw background in openGL
I have a program to animate the solar system. The program draws the sun and a few orbiting planets. I like to put a nebula pixmap in the background, but I don't know how to do it. What I have tried does not seem to work. Here is what I have tried.
1) Use glDrawPixels to draw pixmap. With this approach I was able to draw the pixmap, but it covered the solar objects. I tried to translate the pixmap but that did not work either.
2) Draw a GL_QUADS as a plane behind the solar objects. The plane was up as a tiny parallelogram.
For all I know this might be just totally wrong approach. I would appreciate if someone can point me to the right direction. Here is the code for method #1.
void universe::createObj() { QPixmap map ("hst_orion_nebula.jpg"); glTexImage2D (GL_TEXTURE_2D,0, GL_LUMINANCE, map.width(), map.height(), 0, GL_BGRA,GL_UNSIGNED_BYTE, map.convertToImage().bits()); callId = glGenLists(itemId::next()); glNewList(callId, GL_COMPILE); glDrawPixels (map.width(), map.height(), GL_RGBA, GL_UNSIGNED_BYTE, map.convertToImage().bits()); glEnable (GL_TEXTURE_2D); glEndList(); } void universe::draw() { glPushMatrix(); glPushAttrib (GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT); glCallList (callId); glPopMatrix(); glPopAttrib(); } ///////////////////////////////// void sun::createObj() { QPixmap map ("sunmap.jpg"); glGenTextures (10, canvas::_instance->_texture); glBindTexture(GL_TEXTURE_2D, canvas::_instance->_texture[0]); glTexImage2D(GL_TEXTURE_2D,0, GL_LUMINANCE, map.width(), map.height(), 0, GL_BGRA,GL_UNSIGNED_BYTE, map.convertToImage().bits()); 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); callId = glGenLists(itemId::next()); glNewList(callId, GL_COMPILE); GLUquadricObj *sphere_quadric = gluNewQuadric(); gluQuadricTexture( sphere_quadric, GL_TRUE ); gluQuadricDrawStyle(sphere_quadric, (GLenum)GLU_SMOOTH); gluSphere(sphere_quadric, 25, 36, 36); glEnable (GL_TEXTURE_2D); glEndList(); } void sun::draw() { glEnable( GL_LIGHTING ); glPushMatrix(); glPushAttrib (GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT); GLfloat color1[4] = {1, 0.50, .0, 1 }; glRotated (_xangle, 1, 0, 0); glRotated (_yangle, 0, 1, 0); glRotated (_zangle, 0, 0, 1)开发者_运维问答; glBindTexture(GL_TEXTURE_2D, canvas::_instance->_texture[0]); GLfloat shine[1] = {128}; glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, color1 ); glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shine ); glCallList (callId); glPopMatrix(); glPopAttrib(); }
to draw a fullscreen quad:
glBegin(GL_QUADS);
glVertex2f(1,1);
glVertex2f(1,0);
glVertex2f(0,0);
glVertex2f(0,1);
glEnd();
Call those first, and then whole your scene. and use shader program like this:
void main(void){
gl_Position = gl_Vertex * 2.0 - 1.0;
gl_TexCoord[0] = gl_Vertex;
}
also beware, because gl_Vertex is officially deprecated. If you have to use the fixed pipeline, that is the way:
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBegin( GL_QUADS );
glTexCoord2f(0,0);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1,0);
glVertex2f(1.0f, -1.0f);
glTexCoord2f(1,1);
glVertex2f(1.0f, 1.0f);
glTexCoord2f(0,1);
glVertex2f(-1.0f, 1.0f);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
I would advise you to add a skybox to your scene, this way you will have a quite satisfying effect that will follow your camera movement.
You can find a number of skybox textures over the internet, and here is a really neat tutorial on how to render your scene inside a skybox : https://learnopengl.com/Advanced-OpenGL/Cubemaps
If you still want to go with your idea of drawing a static nebula picture, rendering the quad on which you apply the nebula texture first while disabling the rendering on the zbuffer should solve your issue. This way your scene will be rendered on top of your background.
精彩评论