Qt OpenGL texture is black - c++

I need to load a texture onto a square but whenever i start te program I can't see any texture, just a black square.
Here's the code:
GLuint texture;
interactiveScenes::interactiveScenes(QWidget *parent) :
QGLWidget(parent), ui(new Ui::interactiveScenes)
{
ui->setupUi(this);
timer = new QTimer();
connect( timer, SIGNAL(timeout()), this, SLOT(updateGL()) );
setFocusPolicy(Qt::StrongFocus);
lockMouse = true;
camPosx = 2.0, camPosy = 2.0, camPosz = 25.0;
camViewx = 2.0, camViewy = 2.0, camViewz = 0.0;
camUpx = 0.0, camUpy = 1.0, camUpz = 0.0;
mouseX = QCursor::pos().x();
mouseY = QCursor::pos().y();
setMouseTracking(true);
}
interactiveScenes::~interactiveScenes()
{
delete ui;
}
void interactiveScenes::initializeGL()
{
// Initialize QGLWidget (parent)
QGLWidget::initializeGL();
glShadeModel(GL_SMOOTH);
// White canvas
glClearColor(1.0f,1.0f,1.0f,0.0f);
// Place light
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable(GL_DEPTH_TEST);
GLfloat light0_position [] = {0.1f, 0.1f, 5.0f, 0.0f};
GLfloat light_diffuse []={ 1.0, 1.0, 1.0, 1.0 };
glLightfv ( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
glEnable(GL_TEXTURE_2D);
img = new QImage(":/images/images.jpg", "JPG");
if (img->isNull())
std::cout << "error" <<std::endl;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
QImage tex = QGLWidget::convertToGLFormat(*img);
if (tex.isNull())
std::cout << "error" <<std::endl;
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
tex.width(), tex.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
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_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDisable(GL_TEXTURE_2D);
timer->start(50);
}
void interactiveScenes::resizeGL(GLint width, GLint height)
{
if ((width<=0) || (height<=0))
return;
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
GLdouble aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(45.0f, aspect_ratio, 0.1, 40.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void interactiveScenes::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
glEnable( GL_LIGHTING );
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glColor3f( 1.0, 0.0, 0.0 );
glBegin(GL_POLYGON);
glTexCoord2d( 0.0, 5.0 );
glVertex3f( 0.0f, 3.0f, 0.0f );
glTexCoord2d( 0.0, 0.0);
glVertex3f( 0.0f, 0.0f, 0.0f );
glTexCoord2d( 5.0, 0.0);
glVertex3f( 3.0f, 0.0f, 0.0f );
glTexCoord2d( 5.0, 5.0);
glVertex3f( 3.0f, 3.0f, 0.0f );
glEnd();
glDisable(GL_TEXTURE_2D);
glPushMatrix();
glTranslated(2.0, 2.0 ,-4);
GLfloat shin[] = { 12.8f };
GLfloat amb[] = { 0.135f, 0.2225f, 0.1575f, 0.95f };
GLfloat diff2 [] = { 0.54f , 0.89f , 0.63f, 0.95f };
GLfloat specular[] = { 0.316228f, 0.316228f, 0.316228f, 0.95f };
glMaterialfv ( GL_FRONT, GL_SPECULAR, specular);
glMaterialfv ( GL_FRONT, GL_SHININESS, shin);
glMaterialfv ( GL_FRONT, GL_AMBIENT, amb);
glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff2 );
solidSphere(2, 25, 25);
glPopMatrix();
// restore current matrix
glMatrixMode( GL_MODELVIEW );
glPopMatrix( );
}
The image loads fine from my resource file, i thought it was something with convertToGLFormat but that also returns an image.

Thanks to agrum I found out the problem, I tested to see if the square would show any colors and it didn't.
I didn't disable the lighting before applying the textures/colors.
After disabling the lighting when applying the texture everything works fine!

Related

OpenGL texture mapping issue

I'm trying to do texture on my cube as the code below. However, the result that I got is that the image did not cover the entire cube surface while looks like it looped.
You can see the blue lining from the picture used:
I've checked the coordinates but doesn't seem to have any error. I check the image size (512x512), it's also the same as I declared when loading the texture. So, I had trouble figuring where is the problem.
void square(void) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]); //bind our texture to our shape
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glTexCoord3d(0.0, 0.0, 0.0); glVertex3d(500, -500, -500); //behind
glTexCoord3d(1.0, 0.0, 0.0); glVertex3d(500, 500, -500);
glTexCoord3d(1.0, 1.0, 0.0); glVertex3d(-500, 500, -500);
glTexCoord3d(0.0, 1.0, 0.0); glVertex3d(-500, -500, -500);
glEnd();
glBegin(GL_POLYGON);
glTexCoord3d(0.0, 0.0, 0.0); glVertex3f(500, -500, 500); //front
glTexCoord3d(1.0, 0.0, 0.0); glVertex3f(500, 500, 500);
glTexCoord3d(1.0, 1.0, 0.0); glVertex3f(-500, 500, 500);
glTexCoord3d(0.0, 1.0, 0.0); glVertex3f(-500, -500, 500);
glEnd();
glBegin(GL_POLYGON);
glTexCoord3d(0.0, 0.0, 0.0); glVertex3f(500, -500, -500); //right
glTexCoord3d(1.0, 0.0, 0.0); glVertex3f(500, 500, -500);
glTexCoord3d(1.0, 1.0, 0.0); glVertex3f(500, 500, 500);
glTexCoord3d(0.0, 1.0, 0.0); glVertex3f(500, -500, 500);
glEnd();
glBegin(GL_POLYGON);
glTexCoord3d(0.0, 0.0, 0.0); glVertex3f(-500, -500, 500); //left
glTexCoord3d(1.0, 0.0, 0.0); glVertex3f(-500, 500, 500);
glTexCoord3d(1.0, 1.0, 0.0); glVertex3f(-500, 500, -500);
glTexCoord3d(0.0, 1.0, 0.0); glVertex3f(-500, -500, -500);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_POLYGON);
glTexCoord3d(0.0, 0.0, 0.0); glVertex3f(500, 500, 500); //top
glTexCoord3d(1.0, 0.0, 0.0); glVertex3f(500, 500, -500);
glTexCoord3d(1.0, 1.0, 0.0); glVertex3f(-500, 500, -500);
glTexCoord3d(0.0, 1.0, 0.0); glVertex3f(-500, 500, 500);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_POLYGON);
glTexCoord3d(0.0, 0.0, 0.0); glVertex3f(500, -500, -500); //bottom
glTexCoord3d(1.0, 0.0, 0.0); glVertex3f(500, -500, 500);
glTexCoord3d(1.0, 1.0, 0.0); glVertex3f(-500, -500, 500);
glTexCoord3d(0.0, 1.0, 0.0); glVertex3f(-500, -500, -500);
glEnd();
glDisable(GL_TEXTURE_2D);
}
function to load the RAW file:
GLuint LoadTexture(const char * filename, int width, intbheight)
{
GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen(filename, "rb");
if (file == NULL) return 0;
data = (unsigned char *)malloc(width * height * 3);
fread(data, width * height * 3, 1, file);
fclose(file);
glGenTextures(1, &texture); //generate the texture with the loaded data
glBindTexture(GL_TEXTURE_2D, texture); //bind the textureto it’s array
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE); //set texture environment parameters
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);
//Generate the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, data);
free(data); //free the texture
return texture; //return whether it was successful
}

OpenGL Picking selects on wrong places

I'm trying to recognize a drawn object on a mousPressEvent in OpenGL in Qt with picking.
I did some research but wasn't able to find the problem.
Clearly it recognizes something (because the return value of glRenderMode(GL_RENDER) is often an integer > 0), but not necessarily when I click on an object.
I think gluPerspective is the problem right here, but i just don't know how to resolve it.
mousePressEvent:
void WorldView::mousePressEvent(QMouseEvent *e)
{
GLuint buff[256];
GLint hits;
GLint view[4];
//Buffer to store selection data
glSelectBuffer(256, buff);
//Viewport information
glGetIntegerv(GL_VIEWPORT, view);
//Switch to select mode
glRenderMode(GL_SELECT);
//Clear the name stack!
glInitNames();
//Restric viewing volume
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//Restrict draw area
gluPickMatrix(e->x(), e->y(), 1.0, 1.0, view);
gluPerspective(40.0f, (GLfloat)view[2]/(GLfloat)view[3], 1.0, 100.0);
//Draw the objects onto the screen
glMatrixMode(GL_MODELVIEW);
//Draw only the names in the stack
paintGL();
//Back into projection mode to push the matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
hits = glRenderMode(GL_RENDER);//number of recognized objects
printf("\n%d\n",hits);
//Back to modelview mode
glMatrixMode(GL_MODELVIEW);
}
Draw function:
void WorldView::paintGL ()
{
this->dayOfYear = (this->dayOfYear+1);
this->hourOfDay = (this->hourOfDay+1) % 24;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camViewx,camViewy,camViewz,
camUpx, camUpy, camUpz );
//Draw Axes
glDisable( GL_LIGHTING );
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 10.0);
glEnd();
//Draw objects we want to pick
glPushName(0);
glBegin(GL_TRIANGLES);
glVertex3d(1,1,1);
glVertex3d(2,3,2);
glVertex3d(5,2,2);
glEnd();
glPopName();
glPushName(1);
glBegin(GL_TRIANGLES);
glVertex3d(7,-5,1);
glVertex3d(10,3,2);
glVertex3d(10,2,2);
glEnd();
glPopName();
glPushName(2);
glBegin(GL_TRIANGLES);
glVertex3d(1,-5,7);
glVertex3d(2,3,9);
glVertex3d(5,2,9);
glEnd();
glPopName();
}
EDIT1: Maybe completing the code could help?
Initializer:
void WorldView::initializeGL ()
{
this->dayOfYear = 0;
this->hourOfDay = 0;
// Initialize QGLWidget (parent)
QGLWidget::initializeGL();
glShadeModel(GL_SMOOTH);
// Black canvas
glClearColor(0.0f,0.0f,0.0f,0.0f);
// Place light
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable(GL_DEPTH_TEST);
GLfloat light0_position [] = {0.1f, 0.1f, 0.1f, 0.1f};
GLfloat light_diffuse []={ 1.0, 1.0, 1.0, 1.0 };
glLightfv ( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
}
resizer:
void WorldView::resizeGL ( int width, int height )
{
if ((width<=0) || (height<=0))
return;
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
//change the next line order to have a different perspective
GLdouble aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(40.0f, aspect_ratio, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Use bullet raycast and not gl_Select which is way too slow and unwieldy. This will also make you get away from calling paintGL manually and other glCalls...in qt mousepressevent. Dont do this!

background texture. Switch to ortho and then switch back to 3d

I am working on a background texture. What I want to do is that I want to set a background image. For that in my code I used switch to ortho, draw a square full of window size, texture it. Then switch back to 3d and draw 3d images. It draw the background texture and snowman but they all disappear in a sec. I have no idea where the error code is. gotta have something to do with pushing and popping the matrix I think. Below is the code of my InitGl, draw() and drawsnowman(), main and reshape(). I think the problem is in draw() function during the swithc between 3D to 2d. Advice?
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
glutKeyboardFunc(key);
if( !initGL() ) { // NEW (16)
printf( "Unable to initialize graphics library!\n" );
return 1;
}
glutDisplayFunc (display);
// glutIdleFunc (display);
glutIdleFunc(idle);
glutReshapeFunc (reshape);
//Load our texture
texture = LoadTexture( "texture.bmp", 256, 256 );
glutMainLoop ();
//Free our texture
FreeTexture( texture );
return 0;
}
void drawSnowMan(void)
{
GLUquadricObj *pObj;
//glDisable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// save the world matrix
glPushMatrix();
glTranslatef(xpos, -0.5, -5.0);
glRotated(rotX,1,0,0); // ******** NEW (11)
glRotated(rotY,0,1,0);
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
//glRotated(rotZ,0,0,1);
glPushMatrix();
//setting up light effect for base, mid and head spheres. all red!
ambient[0] = 1.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glTranslatef(0.0 ,0.75f, 0.0f);
//bottom sphere. dont need to gltranslate again because it will use the previous gltranslate
//which is declared outside
glutSolidSphere(0.70f,20,20);
//mid sphere
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.45f,20,20);
//top sphere
glTranslatef(0.0f, 0.6f, 0.0f);
glutSolidSphere(0.30f,20,20);
//eyes
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
//drawing hat
glPushMatrix();
//black color. move it 1.85 in y position because thats where the head is
//rotate the cylinder and draw cylinder
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(0.0f, 1.85f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.17f, 0.17f, 0.4f, 26, 13);
//drawing brim. disable cull_face. draw disk, so front part. disabl
glDisable(GL_CULL_FACE);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glEnable(GL_CULL_FACE);
glTranslatef(0.0f, 0.0f, 0.40f);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glPopMatrix();
glPushMatrix();
glPushMatrix();
glColor3f(1.0,1.0,1.0);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(90.0,0.0, 0.0,-5.0);
glScalef (0.01, 0.2, 0.06); /* modeling transformation */
//glutSolidCone(0.1, 0.1, 10.0, 14.0);
glutSolidCube(1.5);
glPopMatrix();
glPushMatrix();
glTranslatef(2.0f, 0.8f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.04f, 0.04f, 0.2f, 26, 13);
glPopMatrix();
//blade
glPushMatrix();
ambient[0] = 0.0; ambient[1] = 1.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.03f, 0.03f, 1.1f, 26, 13);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
glPopMatrix();
//big push matrix for eyes, and nose
glPushMatrix();
//eyes color = black light. set defuse all 0, ambient = black. turns the eyes black
/*ambient[0] = 0.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 0.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);*/
glColor3f(0.0, 0.0, 0.0);
//left eye
glPushMatrix();
glTranslatef(-0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//right eye
glPushMatrix();
glTranslatef(0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//drawing nose
glPushMatrix();
glTranslatef(0.0, 1.6, 0.25 );
glutSolidCone(0.08f,0.5f,10,2);
glPopMatrix();
glPopMatrix(); // end big push matrix for eyes and nose
glPopMatrix();
} // end of drawsnowman()
void display (void) {
glClearColor(0.25f, 0.25f, 0.50f, 1.0f ); // blueish color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glLoadIdentity();
// MODEL VIEW is set up in IniitGL
//so save it
glPushMatrix();
//switch to projection matrix
//swithc to ortho.
//draw texture
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glPopMatrix();// pop the 3d model view
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
// You can ignore this. just a different of way drawing texture and still does not work
/* glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glDepthMask( false );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
/*glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, 800 / 600, 1.0, 100.0);;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0.0, 0.0, 0.0, // Where would the camera be?
0.0, 0.0,-1.0, // Where would it be looking?
0.0, 1.0, 0.0); // What would be the "up" vector?fa*/
/* glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//gluPerspective (45, SCREEN_WIDTH / SCREEN_HEIGHT, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();*/
drawSnowMan(); // draw snow man
glutSwapBuffers();
angle ++;
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
bool initGL (void) {
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Switch to the "camera" mode
glMatrixMode(GL_PROJECTION); // Camera
glLoadIdentity();
// Change the camera to a 3D view
glFrustum( -1 * (float) SCREEN_WIDTH / SCREEN_HEIGHT,
(float) SCREEN_WIDTH / SCREEN_HEIGHT,
-1.0,
1.0,
1.5,
1000.0);
glClearColor(0.25f, 0.25f, 0.50f, 1.0f );
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // NEW (5)
glEnable(GL_LINE_SMOOTH); // NEW (6)
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // NEW (7)
glEnable(GL_POLYGON_SMOOTH); // NEW (8)
// this is a specular light
GLfloat mat_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 }; // Color of a "shiny material
GLfloat mat_shininess[] = { 50.0 }; // How shiny is it?
// GLfloat mat_ambient_and_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; // Infinitely far away. Direction light
GLfloat light_position1[] = {2.0,1.5,0.0,1.0}; // saber light
// How to calculate the surface normal for pixels
glShadeModel(GL_SMOOTH); // Try this as well GL_FLAT
// Setup up some material reflective properties
// glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
// glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_and_diffuse);
//glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_ambient_and_diffuse);
// Finally actually make the light
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
//Check for error
GLenum error = glGetError(); // NEW (9)
if( error != GL_NO_ERROR ) {
printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
return false;
}
return true;
}
void idle(void) {
glutPostRedisplay();
}
Reoccuring newbie misconception: OpenGL "initialization".
OpenGL is not initialized! All the code you have in initGL and reshape belongs into display.
In the case of calls glLight… those must be placed in display, after setting the modelview matrix into the space you want the lights to be in. Also OpenGL is not a library; yes originally the 'L' in OpenGL did mean library, but I backronymed it to Layer, because that's what it is on most modern graphics systems: A layer between a end user program and the GPU and its drivers.
I think once you moved the code from initGL and reshape to display, the solution should become clear: You can change, reset and modify the projection and modelview matrix whenever you like. To have the window width and height available in display either store them in global variables in reshape, or, the preferred solution, use glutGet(GLUT_WINDOW_WIDTH) and glutGet(GLUT_WINDOW_HEIGHT) to query the window dimensions in the display function.
You want to draw things in a orthographic projection? Then setup projection and modelview appropriately. Switching to a perspective? Just do it.
I think I kinda figure out why my background texture keep disappearing. I had Cullface and depth something turned on. I turned it off befor popping the last matrix and it works.
However, there is one problem. The texture image is snowy background, but it turns into all red. So first I thought it was due to the reflection of the lighting from the snowgirl. I turned off all the light and still red. Can't figure out why. Could it be, the texture color blending in with the original color of the snowman?

How is Texture Splatting in OpenGL implemented?

I have been reading for a while the different techniques used to texture terrains and came across texture splatting. I have found a lot of articles that discuss how to do this in OpenGL, but most only discuss it theoretically and provide little to no code that I can study. Does anyone know/have some code that illustrates this in OpenGL?
Just to clarify, I want to be able to load four different textures, and based on the height of the quad/vertices, change the texture from one gradually to the next.
Edit: Below is a quick bit of code to help show what I want to know
#include <windows.h>
#include <SFML/Graphics.hpp>
#include <gl/gl.h>
#include <gl/glu.h>
#define GL_CLAMP_TO_EDGE 0x812F
class Scene {
public:
void resize( int w, int h ) {
// OpenGL Reshape
glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 120.0, (GLdouble)w/(GLdouble)h, 0.5, 500.0 );
glMatrixMode( GL_MODELVIEW );
}
};
int main() {
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Test");
///Setup the scene, materials, lighting
Scene scene;
scene.resize(800,600);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LIGHT0);
float XL = .5, YL = .1, ZL = 1;
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat lightpos[] = {XL, YL, ZL, 0.};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
///Test terrain texture splatting
///Load the textures
sf::Image tex1;
tex1.loadFromFile("texture1.png");
sf::Image tex2;
tex2.loadFromFile("texture2.png");
///Set the first texture
GLuint grass;
glGenTextures(1, &grass);
glBindTexture(GL_TEXTURE_2D, grass);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tex1.getSize().x, tex1.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)tex1.getPixelsPtr() );
///Set the second texture
GLuint dirt;
glGenTextures(1, &dirt);
glBindTexture(GL_TEXTURE_2D, dirt);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tex2.getSize().x, tex2.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)tex2.getPixelsPtr() );
///Start loop
while( window.isOpen() ) {
sf::Event event;
while( window.pollEvent( event ) ) {
if( event.type == sf::Event::Closed )
window.close();
}
///Clear buffer and set camera
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, 1.0, 1.0, 50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1, 0, 1, 0, 0, 0, 0, 1, 0);
///Begin rendering quad
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, grass);
///I know that around here I should enable blending in order to get my two textures to mix, but I am not certain
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-0.5, -0.5, 0.0);
glTexCoord2f(1, 0);
glVertex3f(-0.5, 0.5, 0.0);
glTexCoord2f(1, 1);
glVertex3f(0.5, 0.5, 0.0);
glTexCoord2f(0, 1);
glVertex3f(0.5, -0.5, 0.0);
glEnd();
///Reset env settings for SFML
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
window.display();
}
return 1;
}
As people mentioned above, use programmable pipeline, use shaders. In the fragment shader you can pass all the textures and interpolate between them based on vertex data you receive from the vertex shader.
Quick search gave me this result. I am sure that is what you need. Also take a look at this post. And this paper explains the technique very well.

openGL / GLSL: bloom/blur, rendering to FBO

I've reached another impasse I can't seem to resolve on my own. I really hope someone can help me out.
I've been trying to create a nice little bloom effect using GLSL, which worked quite well. When I tried including something moving into my scene I noticed that I forgot to clear my FBOs before rendering into them.
Without clearing it worked for never changing scenes because I was always using the same texture. With the glClear(); command it still works, but for the very first frame only, all I get after that is a black screen. So I guess my issue is that I can't get my FBOs to continuously be updated every frame.
I feel like I'm either missing something very obvious or doing something horribly wrong.
I'd be thankful for any suggestions you might have.
Here's what I get for the first frame:
Sources:
(using openFrameworks)
setup:
void testApp::setup(){
ofSetVerticalSync(true);
ofDisableSetupScreen();
width = ofGetWidth();
height = ofGetHeight();
//complie/link/generate ShaderObjects ....
horizontalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_horizontal.glsl", GL_FRAGMENT_SHADER);
verticalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_vertical.glsl", GL_FRAGMENT_SHADER);
BlurVertex.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/horizontal_blur.glsl", GL_VERTEX_SHADER);
blendTextures.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/blend_shader.glsl", GL_FRAGMENT_SHADER);
fboOriginal.initialize(width, height);
fboH800.initialize(width, height);
fboV800.initialize(width, height);
fboH400.initialize(width, height);
fboV400.initialize(width, height);}
draw:
void testApp::draw(){
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
//set orthographic projection
glOrtho( -1, 1, -1, 1, 1.0, 40.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height);
glDisable(GL_TEXTURE_2D);
fboOriginal.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glScalef(0.1f, 0.1f, 1.0f);
//generating values between 0 and 2
float x = 2 * (sin(time)+1.000001)/2;
//drawSOlidRect(xPos, yPos, width, height, red, green, blue);
drawSolidRect(-8.0f, 8.0f, x, x, 0.4f, 0.4f, 1.0f);
drawSolidRect(-5.0f, 8.0f, x, x, 0.4f, 1.0f, 0.4f);
drawSolidRect(-2.0f, 8.0f, x, x, 0.4f, 1.0f, 1.0f);
drawSolidRect( 1.0f, 8.0f, x, x, 1.0f, 0.4f, 0.4f);
drawSolidRect( 4.0f, 8.0f, x, x, 1.0f, 0.4f, 1.0f);
drawSolidRect( 7.0f, 8.0f, x, x, 1.0f, 1.0f, 0.4f);
glPopMatrix();
glPopAttrib();
fboOriginal.unbind();
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fboOriginal.fboTexture);
BlurVertex.enable();
horizontalBlurFrag.enable();
glUniform1i(glGetUniformLocation(horizontalBlurFrag.program, "RTScene"), 0);
glDisable(GL_TEXTURE_2D);
fboH800.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
fboH800.unbind();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fboH800.fboTexture);
BlurVertex.enable();
verticalBlurFrag.enable();
glUniform1i(glGetUniformLocation(verticalBlurFrag.program, "RTBlurH"), 0);
glDisable(GL_TEXTURE_2D);
fboV800.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
fboV800.unbind();
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fboV800.fboTexture);
BlurVertex.enable();
horizontalBlurFrag.enable();
glUniform1i(glGetUniformLocation(horizontalBlurFrag.program, "RTScene"), 1);
glDisable(GL_TEXTURE_2D);
fboH400.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glPushMatrix();
glViewport(0, 0, width/4, height/4); //crude downscale
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
fboH400.unbind();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fboH400.fboTexture);
BlurVertex.enable();
verticalBlurFrag.enable();
glUniform1i(glGetUniformLocation(verticalBlurFrag.program, "RTBlurH"), 1);
glDisable(GL_TEXTURE_2D);
fboV400.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glPushMatrix();
glViewport(0, 0, width*4, height*4); //crude downscale
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
fboV400.unbind();
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fboV800.fboTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fboV400.fboTexture);
BlurVertex.enable();
blendTextures.enable();
glUniform1i(glGetUniformLocation(blendTextures.program, "originalSizeTex"), 0);
glUniform1i(glGetUniformLocation(blendTextures.program, "downscaledTex"), 1);
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glDisable(GL_TEXTURE_2D);}
FBO:
class FrameBufferObject{
public:
//handles
GLuint fbo, fboTexture, fboDepthbuffer;
public:
void initialize(GLuint width, GLuint height){
// generate namespace for the frame buffer, colorbuffer and depthbuffer
glGenFramebuffersEXT(1, &fbo);
glGenTextures(1, &fboTexture);
glGenRenderbuffersEXT(1, &fboDepthbuffer);
//switch to our fbo so we can bind stuff to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
//create the colorbuffer texture and attach it to the frame buffer
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenerateMipmapEXT(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexture, 0);
// create a render buffer as our depthbuffer and attach it
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fboDepthbuffer);
// Go back to regular frame buffer rendering
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);
}
void bind(){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
}
void unbind(){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void clear(){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}};
UPDATE:
The alpha value one the glClearColor at least seems to be part of my issue.
I tried messing around with it and what i got is this:
(with up- and downscaling quads as you'd expect)
Somehow i seem to be losing all color somewhere along the way.
Oddly enough i got the best result having (0, 0, 0, 0) for 4 of my FBOs and (0, 0, 0, 1) for one of them. Setting (0, 0, 0, 0) for all FBOs just yields a greyish picture (which i assume is the default window without anything in it).
Here's my "blending-together-shader":
uniform sampler2D originalSizeTex;
uniform sampler2D downscaledTex;
varying vec2 vTexCoord;
void main(void){
vec4 colorOriginal = vec4(0.0, 0.0, 0.0, 0.0);
vec4 colorDownscale = vec4(0.0, 0.0, 0.0, 0.0);
colorOriginal = texture2D(originalSizeTex, vTexCoord.xy);
colorDownscale = texture2D(downscaledTex, vTexCoord.xy);
gl_FragColor = vec4(colorOriginal + colorDownscale);
}
Any guesses?
Depends on how you're doing your blending, but -- you might need to set the clear color to 0,0,0,0 instead of 0,0,0,1 when you clear your FBO.