I am trying to make a background using SOIL_load_OGL_texture
but when I added my 3D models the texture disappeared. The code for 3D models were separated from the texture code but when I combine it, the background becomes black and my 3D models is facing back. Is the problem here because of the coordination?
I expect the output would be the 3D models facing front and it is in front of the texture.
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include "SOIL2.h"
GLuint myTexture;
const GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
static int head = 0, rear = -90, lear = -90, body = 0, lleg = -90, rleg = -90, ball = 0, stage = 0;
GLfloat ballRadius = 0.1f;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(0.5, 0.85, 0.9); // head
glPushMatrix();
glTranslated(0, 0.25, 0.15);
glRotated((GLfloat)head, 0, 1, 0);
glutSolidSphere(0.2, 40, 50);
glPopMatrix();
glPushMatrix(); //ear
glTranslated(0.11, 0.3, 0.18);
glRotated((GLfloat)rear, 1, 0, 0);
glutSolidCone(0.08, 0.2, 16, 16);
glPopMatrix();
glPushMatrix(); //ear
glTranslated(-0.11, 0.3, 0.18);
glRotated((GLfloat)lear, 1, 0, 0);
glutSolidCone(0.08, 0.2, 16, 16);
glPopMatrix();
glColor3d(0.0, 0.0, 0.0); //eyes
glPushMatrix();
glTranslated(0.07, 0.3, 0.33);
glRotated(-5, 0, 0, 1);
glScalef(0.5, 0.1, 0.1);
glutSolidCube(0.1);
glPopMatrix();
glPushMatrix(); //eyes
glTranslated(-0.07, 0.3, 0.33);
glRotated(-5, 0, 0, -1);
glScalef(0.5, 0.1, 0.1);
glutSolidCube(0.1);
glPopMatrix();
glPushMatrix(); //mouth
glTranslated(0.0, 0.25, 0.35);
glRotated(0, 0, 0, 0);
glScalef(1, 0.1, 0.1);
glutSolidCube(0.1);
glPopMatrix();
glColor3d(1.0, 1.0, 1.0);
glPushMatrix(); // teeth
glTranslated(-0.045, 0.255, 0.34);
glRotated(-90, 1, 0, 0);
glutSolidCone(0.01, 0.02, 16, 16);
glPopMatrix();
glPushMatrix(); // teeth
glTranslated(0.045, 0.255, 0.34);
glRotated(-90, 1, 0, 0);
glutSolidCone(0.01, 0.02, 16, 16);
glPopMatrix();
glColor3d(0.5, 0.85, 0.88); // body
glTranslatef(0, 0, 0.1);
glPushMatrix();
glRotated((GLfloat)body, 1, 0, 0);
glutSolidSphere(0.3, 40, 50);
glPopMatrix();
glPushMatrix();
glTranslatef(0, 0.7, 0.0);
glRotatef((GLfloat)stage, 0.0, 1.0, 0.0);
glTranslatef(1.0, 0.0, 0.0);
glPushMatrix();
glScalef(2.0, 0.4, 1.0);
glutWireCube(1.0);
glPopMatrix();
//glFlush();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, myTexture);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
/*glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); */
glNormal3f(0.0, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-2.5f, -2.5f, 2.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(2.5f, -2.5f, 2.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(2.5f, -2.5f, -2.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-2.5f, -2.5f, -2.5f);
glEnd();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glutSwapBuffers();
}
void reshape(int width, int height)
{
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustum(-ar + 1, ar - 1, -1.0, 1.0, 2.0, 90.0);
//gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("SOIL test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
myTexture = SOIL_load_OGL_texture("background.png", 0, 1, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_INVERT_Y);
if (!myTexture)
{
printf("soil failed to load texture\n");
}
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glutMainLoop();
return EXIT_SUCCESS;
}
If you want that the background image is draw in the back, then you've to draw the background first, but disable the Depth Test (The depth buffer has to be cleared before).
This causes that the other geometry covers the background.
When the background is drawn no projection matrix is set, the projection matrix is the identity matrix. So the z-coordinate of the background has to be in [-1, 1], else it wold be clipped by the near or far plane.
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 glColor3d
.
Set a "white" color before you render the texture:
glColor3d(1.0, 1.0, 1.0);
Note, OpenGL is a state engine. If a color was set, the color is kept until it is changed again, even beyond frames. So this might not be an issue in the first frame, but it would be in the further frames.
The fixed function light model is applied on the background, too. This will cause a bad look with fixed function gouraud light model. I recommend to disable lighting before you draw the background.
glDisable(GL_LIGHTING);
and to enable lighting before you draw the geometry
glEnable(GL_LIGHTING);
The function display
may look like this:
void display(void)
{
// clear color buffer and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// prepare for drawing the back ground
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glColor3d(1.0, 1.0, 1.0);
// projection and model view for the background
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// draw the background
glBindTexture(GL_TEXTURE_2D, myTexture);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
// prepare for drawing the geometry
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
// projection and model view for the geoemtry
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustum(-ar + 1, ar - 1, -1.0, 1.0, 2.0, 90.0);
//gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// draw geometry
glColor3d(0.5, 0.85, 0.9); // head
// ...
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}