I am working with openGL GLUT C++. I am trying to load a BMP image and fill a rectangle with it creating a billboard on top of a building. However I cannot not get it to work. I cannot use any third party libraries so I have to make my own BMP loader. How do I do this:
Here is my code:
#include <iostream> // include iostream library
#include <cmath> // include cmath library
#include <GL/glut.h> // include GLUT library
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
//***********************************************************************************
void myInit()
{
glClearColor(1, 1, 1, 0); // specify a background clor: white
glOrtho(-600, 600, -600, 600, -600, 600); // specify a viewing area
glutInitDisplayMode(GLUT_DEPTH);
gluLookAt(1.0, 1.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void drawCylinder() {
glPushMatrix();
GLUquadricObj* qobj = gluNewQuadric();
glTranslated(0.0, 0.4, 0.0);
glRotatef(270, 1.0f, 0.0f, 0.0f);
gluCylinder(qobj, 10, 10, 250, 20, 16);
gluDeleteQuadric(qobj);
glPopMatrix();
}
GLuint LoadTexture(const char* FinalProject)
{
GLuint texture;
texture = LoadTexture("img.bmp");
int width, height;
unsigned char* data;
FILE* file;
file = fopen(FinalProject, "rb");
if (file == NULL) return 0;
width = 1024;
height = 512;
data = (unsigned char*)malloc(width * height * 3);
//int size = fseek(file,);
fread(data, width * height * 3, 1, file);
fclose(file);
for (int i = 0; i < width * height; ++i)
{
int index = i * 3;
unsigned char B, R;
B = data[index];
R = data[index + 2];
data[index] = R;
data[index + 2] = B;
}
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_MIPMAP_NEAREST);
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);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
free(data);
return texture;
}
void drawBillboard() {
GLuint texture;
texture = LoadTexture("img.bmp");
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_POLYGON);
glVertex3i(-300, 500, 0);
glVertex3i(300, 500, 0);
glVertex3i(300, 250, 0);
glVertex3i(-300, 250, 0);
glEnd();
}
void drawPolygon()
{
glMatrixMode(GL_MODELVIEW);
glPointSize(1); // change point size back to 1
glEnable(GL_POLYGON);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// back
glColor3ub(128, 128, 128);
glBegin(GL_POLYGON);
glVertex3i(-100, 100, -100);
glVertex3i(100, 100, -100);
glVertex3i(100, -100, -100);
glVertex3i(-100, -100, -100);
glEnd();
// front
glColor3ub(211, 211, 211);
glBegin(GL_POLYGON);
glVertex3i(-100, 100, 100);
glVertex3i(100, 100, 100);
glVertex3i(100, -100, 100);
glVertex3i(-100, -100, 100);
glEnd();
// window left
glColor3ub(240, 240, 0);
glBegin(GL_POLYGON);
glVertex3i(-30, 50, 105);
glVertex3i(-30, 0, 105);
glVertex3i(-70, 0, 105);
glVertex3i(-70, 50, 105);
glEnd();
// window right
glColor3ub(240, 240, 0);
glBegin(GL_POLYGON);
glVertex3i(30, 50, 105);
glVertex3i(30, 0, 105);
glVertex3i(70, 0, 105);
glVertex3i(70, 50, 105);
glEnd();
// door
glColor3ub(100, 100, 100);
glBegin(GL_POLYGON);
glVertex3i(20, -40, 105);
glVertex3i(20, -100, 105);
glVertex3i(-20, -100, 105);
glVertex3i(-20, -40, 105);
glEnd();
// left
glColor3ub(150, 150, 150);
glBegin(GL_POLYGON);
glVertex3i(-100, 100, -100);
glVertex3i(-100, 100, 100);
glVertex3i(-100, -100, 100);
glVertex3i(-100, -100, -100);
glEnd();
// right
glColor3ub(169, 169, 169);
glBegin(GL_POLYGON);
glVertex3i(100, 100, -100);
glVertex3i(100, 100, 100);
glVertex3i(100, -100, 100);
glVertex3i(100, -100, -100);
glEnd();
// top
glColor3ub(220, 220, 220);
glBegin(GL_POLYGON);
glVertex3i(100, 100, -100);
glVertex3i(100, 100, 100);
glVertex3i(-100, 100, 100);
glVertex3i(-100, 100, -100);
glEnd();
// bottom
glColor3ub(0, 0, 0);
glBegin(GL_POLYGON);
glVertex3i(100, -100, -100);
glVertex3i(100, -100, 100);
glVertex3i(-100, -100, 100);
glVertex3i(-100, -100, -100);
glEnd();
glDisable(GL_POLYGON_STIPPLE);
}
//***********************************************************************************
void myDisplayCallback()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // draw the background
glEnable(GL_DEPTH_TEST);
drawPolygon();
drawCylinder();
drawBillboard();
glFlush(); // flush out the buffer contents
}
void mainMenuCallback(int entryId) {
switch (entryId) {
case 30: // x-45
glRotatef(-45.0, 1.0, 0.0, 0.0);
break;
case 40: // x+45
glRotatef(45.0, 1.0, 0.0, 0.0);
break;
case 50: // y-45
glRotatef(-45.0, 0.0, 1.0, 0.0);
break;
case 60: // y+45
glRotatef(45.0, 0.0, 1.0, 0.0);
break;
case 70: // z-45
glRotatef(-45.0, 0.0, 0.0, 1.0);
break;
case 80: // z+45
glRotatef(45.0, 0.0, 0.0, 1.0);
break;
case 90: // reset
glLoadIdentity();
myInit();
break;
case 100:
exit(1);
break;
}
myDisplayCallback();
}
bool mouseDown = false;
int lastX = 0;
int lastY = 0;
void OnMouseMove(int x, int y) {
int deltaX = x - lastX;
int deltaY = y - lastY;
if (lastX == 0) {
deltaX = 0;
}
lastX = x;
lastY = y;
std::cout << deltaY << std::endl;
glRotatef(deltaX, 0.0, 1.0, 0.0);
//glRotatef(-deltaY, 1.0, 0.0, 0.0);
glutPostRedisplay();
}
void OnMouseClick(int button, int state, int x, int y)
{
if ((button == GLUT_LEFT_BUTTON || button == GLUT_RIGHT_BUTTON))
{
mouseDown = (state == GLUT_DOWN);
}
else if ((button == 3) || (button == 4)) // It's a wheel event
{
// Each wheel event reports like a button click, GLUT_DOWN then GLUT_UP
if (state == GLUT_DOWN) return; // Disregard redundant GLUT_UP events
float scale = (button == 3 ? 2 : 0.5);
printf("Scroll %s At %f\n", (button == 3) ? "Up" : "Down", scale);
glScalef(scale, scale, scale);
glutPostRedisplay();
}
}
//***********************************************************************************
int main(int argc, char** argv)
{glutInit(& argc, argv); // optional in our environment
glutInitWindowSize(600, 600); // specify a window size
glutInitWindowPosition(100, 0); // specify a window position
glutInitDisplayMode(GLUT_DEPTH);
glutCreateWindow("Simple Text Drawing"); // create a titled window
myInit(); // setting up
glutCreateMenu(mainMenuCallback);
glutAddMenuEntry("Rotate X-Axis -45 degrees", 30);
glutAddMenuEntry("Rotate X-Axis 45 degrees", 40);
glutAddMenuEntry("Rotate Y-Axis -45 degrees", 50);
glutAddMenuEntry("Rotate Y-Axis 45 degrees", 60);
glutAddMenuEntry("Rotate Z-Axis -45 degrees", 70);
glutAddMenuEntry("Rotate Z-Axis 45 degrees", 80);
glutAddMenuEntry("Reset Polygon", 90);
glutAddMenuEntry("Terminate Program", 100);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMouseFunc(OnMouseClick);
glutMotionFunc(OnMouseMove);
glutDisplayFunc(myDisplayCallback); // register a callback
glutMainLoop(); // get into an infinite loop
return 0;
}