PDA

View Full Version : Problem with texturing and Xlib



03-28-2001, 12:43 PM
I'm having a hard time getting a simple program to work right. I'm just trying to draw a rectangle and then apply a texture map to it. The rectangle comes out fine, but it's not textured; also strange is that it's colored a sort of brownish-orange color for no good reason that I can tell. The color of the rectangle seems to depend on which bitmap I use to try to texture the surface with. Anyway, here's the code...I'd be VERY grateful for any help you could give me. Oh - before anyone asks - yes, my bitmap's dimensions are powers of 2 (256 x 256, to be exact). http://www.opengl.org/discussion_boards/ubb/smile.gif

#include <iostream.h>
#include <string>

#include <GL/glx.h>
#include <GL/glu.h>

#include "bitmap.h"

int main() {

Display* dpy;
string dpyName;
XVisualInfo* vi;
int viAttribList[] = {
GLX_RGBA, GLX_DEPTH_SIZE, 16, None
};
GLXContext cx;
Colormap cmap;
XSetWindowAttributes swa;
Bitmap* bmp;
Window win;
XEvent event;
GLuint texName;


/**
* Open the connection to the appropriate X server.
*/
dpyName = getenv("DISPLAY");
dpy = XOpenDisplay(dpyName.c_str());
if (dpy == NULL) {
cerr << "Error: couldn't connect to X server " << dpyName << endl;
exit(1);
}

/**
* Make sure this X server has an OpenGL GLX extension.
*/
if (!glXQueryExtension(dpy, NULL, NULL)) {
cerr << "Error: X server "
<< dpyName
<< "has no OpenGL GLX extension" << endl;
exit(1);
}

/**
* Set up the visual for a double-buffered, RGBA format, 16-bit depth
* display.
*/
vi = glXChooseVisual(dpy, DefaultScreen(dpy), viAttribList);
if (vi == NULL) {
cerr << "Error: no appropriate visual" << endl;
exit(1);
}

/**
* Create the GLX rendering context that renders directly to the graphics
* system if it can.
*/
cx = glXCreateContext(dpy, vi, NULL, GL_TRUE);
if (cx == NULL) {
cerr << "Error: couldn't create rendering context" << endl;
exit(1);
}

/**
* Create the color map.
*/
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
vi->visual, AllocNone);

/**
* Set up the window attributes.
*/
swa.colormap = cmap;
swa.border_pixel = 0;
swa.event_mask = (ExposureMask |
StructureNotifyMask);

bmp = new Bitmap("bmp.bmp");

/**
* Create the window.
*/
win = XCreateWindow(dpy,
RootWindow(dpy, vi->screen),
0, 0,
640, 480,
0,
vi->depth,
InputOutput,
vi->visual,
CWBorderPixel | CWColormap | CWEventMask,
&swa);

/**
* Display the window, and bind the rendering context to it.
*/
XMapWindow(dpy, win);
glXMakeCurrent(dpy, win, cx);


/**
* Set up OpenGL.
*/
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);

// Set up shading
glShadeModel(GL_SMOOTH);

// Set up lights
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);


// Define the texture
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glEnable(GL_TEXTURE_2D);
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);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bmp->GetWidth(), bmp->GetHeight(),
0, GL_RGB, GL_UNSIGNED_BYTE, (GLubyte*)(bmp->GetData()));

GLenum e = glGetError();
if (e != GL_NO_ERROR)
cout << "Error result: " << gluErrorString(e) << endl;

glMatrixMode(GL_PROJECTION);
gluPerspective(60.0, float(640)/float(480), 1.0, 4000.0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(320.0, 240.0, 2.0,
320.0, 240.0, -1.0,
0.0, 1.0, 0.0);

while (true) {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
if (event.xexpose.count > 0) break;
// Draw the textured image
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_QUADS);
glColor3f(0.0, 1.0, 0.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(640.0, 0.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(640.0, 320.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0, 320.0, 0.0);
glEnd();

glFlush();
glWaitGL();

break;

}
}

delete bmp;

return 0;
}

rts
03-28-2001, 01:05 PM
All the GL stuff looks correct.

How certain are you that your Bitmap class is doing the right thing?

03-28-2001, 01:22 PM
Originally posted by rts:
All the GL stuff looks correct.

How certain are you that your Bitmap class is doing the right thing?

Fairly certain - here's the code for that, too, if you're interested. I'd really appreciate it! (I've omitted the typedefs.h file - I guarantee that those are correct. http://www.opengl.org/discussion_boards/ubb/smile.gif)

// ----------

/**
* File: bitmap.h
* Author: Will Grzanich
* Mail: grzanich@mailroom.com
* Date: 03/25/01
*
*
*/

#ifndef BITMAP_H
#define BITMAP_H

#include <string>
#include "typedefs.h"

const WORD BM = 0x4D42;

#pragma pack(1)
struct BITMAPFILEHEADER {
WORD bfType; // type of file (must be BM)
DWORD bfSize; // size of bitmap file, in bytes
WORD bfReserved1; // reserved; must be 0
WORD bfReserved2; // reserved; must be 0
DWORD bfOffBits; // offset, in bytes, from this structure to the data
};

struct BITMAPINFOHEADER {
DWORD biSize; // size of structure, in bytes
LONG biWidth; // bitmap width, in pixels
LONG biHeight; // bitmap height, in pixels
WORD biPlanes; // number of planes for target device (must be 1)
WORD biBitCount; // number of bits per pixel (must be 1, 4, 8, or 24)
DWORD biCompression; // type of compression (BI_RGB, BI_RLE8, BI_RLE4, or
// BI_BITFIELDS)
DWORD biSizeImage; // size, in bytes, of the image
LONG biXPelsPerMeter; // horizontal resolution in pixels per meter
LONG biYPelsPerMeter; // vertical resolution in pixels per meter
DWORD biClrUsed; // number of indices in color table used
DWORD biClrImportant; // number of "critical" indices in color table
};

struct RGBQUAD {
BYTE rgbBlue; // intensity of blue color
BYTE rgbGreen; // intensity of green color
BYTE rgbRed; // intensity of red color
BYTE rgbReserved; // reserved; must be 0
};

struct BITMAPINFO {
BITMAPINFOHEADER bmiHeader; // info about dimensions & color format
RGBQUAD bmiColors[1]; // color table
};

#pragma pack()

using namespace std;

class Bitmap {
public:
Bitmap();
Bitmap(const string& fileName);
Bitmap(const Bitmap& origBitmap);
~Bitmap();
Bitmap& operator=(const Bitmap& origBitmap);

bool OpenFile(const string& fileName);

int GetSize() const;
int GetWidth() const;
int GetHeight() const;
int GetBitCount() const;
const BYTE* const GetData() const;

private:
BITMAPFILEHEADER _bmpFileHeader;
BITMAPINFO _bmpInfo;
BYTE* _bmpData;
};


#endif

// --------------

/**
* File: bitmap.C
* Author: Will Grzanich
* Mail: grzanich@mailroom.com
* Date: 03/25/01
*
*/

#include <fstream>
#include <iostream>
#include "bitmap.h"

Bitmap::Bitmap() {
_bmpData = NULL;
}

Bitmap::Bitmap(const string& fileName) {
_bmpData = NULL;
OpenFile(fileName);
}

Bitmap::Bitmap(const Bitmap& origBitmap) {
int size;

_bmpFileHeader = origBitmap._bmpFileHeader;
_bmpInfo = origBitmap._bmpInfo;
size = origBitmap.GetSize();
if (size == 0)
_bmpData = NULL;
else
memcpy(_bmpData, origBitmap._bmpData, size);
}

Bitmap::~Bitmap() {
if (_bmpData != NULL)
delete _bmpData;
}

Bitmap& Bitmap: http://www.opengl.org/discussion_boards/ubb/redface.gifperator=(const Bitmap& origBitmap) {
int size;

if (&origBitmap != this) {
_bmpFileHeader = origBitmap._bmpFileHeader;
_bmpInfo = origBitmap._bmpInfo;
size = origBitmap.GetSize();
if (size == 0)
_bmpData = NULL;
else
memcpy(_bmpData, origBitmap._bmpData, size);
}

return (*this);
}

bool Bitmap::OpenFile(const string& fileName) {
ifstream fin;

fin.open(fileName.c_str());
if (!fin) {
cerr << "Error: Bitmap::OpenFile() - cannot open file "
<< fileName
<< endl;
return (false);
}

// read the BITMAPFILEHEADER structure
fin.read((char*)&(_bmpFileHeader), sizeof(BITMAPFILEHEADER));

if (_bmpFileHeader.bfType != BM) {
cerr << "Error: Bitmap::OpenFile() - file "
<< fileName
<< " is not a Windows bitmap file"
<< endl;
return (false);
}

// read the BITMAPINFOHEADER
fin.read((char*)&(_bmpInfo.bmiHeader), sizeof(BITMAPINFOHEADER));

// forget about the color palette - we only support high-color bitmaps
fin.seekg(-(int)(_bmpInfo.bmiHeader.biSizeImage), ios::end);
_bmpData = new BYTE[_bmpInfo.bmiHeader.biSizeImage];
fin.read((char*)(_bmpData), (streamsize)(_bmpInfo.bmiHeader.biSizeImage));

return (true);
}

int Bitmap::GetSize() const {
return (_bmpInfo.bmiHeader.biSizeImage);
}

int Bitmap::GetWidth() const {
return (_bmpInfo.bmiHeader.biWidth);
}

int Bitmap::GetHeight() const {
return (_bmpInfo.bmiHeader.biHeight);
}

int Bitmap::GetBitCount() const {
return (_bmpInfo.bmiHeader.biBitCount);
}

const BYTE* const Bitmap::GetData() const {
return (_bmpData);
}

rts
03-28-2001, 01:34 PM
Nothing immediately jumps out as wrong there either, although I will say that #pragma is evil. That's a Visual C++-ism. You should really use:




struct BITMAPFILEHEADER
{
....
} __attribute__((packed));

etc.


instead.


When I get home I'll grab your source and try it out to see if there's something going on that I'm just not noticing in a cold code reading.

03-28-2001, 01:59 PM
Originally posted by rts:
Nothing immediately jumps out as wrong there either, although I will say that #pragma is evil. That's a Visual C++-ism. You should really use:




struct BITMAPFILEHEADER
{
....
} __attribute__((packed));

etc.


instead.


When I get home I'll grab your source and try it out to see if there's something going on that I'm just not noticing in a cold code reading.

Hmm. Okay - I didn't know about the __attribute__ thing. Can you tell I haven't been programming under Linux much? http://www.opengl.org/discussion_boards/ubb/smile.gif But thank you very much for looking at this for me - it's been driving me CRAZY. I appreciate it. http://www.opengl.org/discussion_boards/ubb/smile.gif

-Will

03-28-2001, 02:14 PM
BTW - here's that typedefs.h file; it's not too hard to figure out what's in it, but this'll save you from having to type it out, anyway. http://www.opengl.org/discussion_boards/ubb/smile.gif




#ifndef TYPEDEFS_H
#define TYPEDEFS_H

typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
typedef unsigned char BYTE;

#endif

rts
03-28-2001, 07:56 PM
Step away from the quad... http://www.opengl.org/discussion_boards/ubb/smile.gif

Change your gluLookAt to something like:




gluLookAt(320.0, 240.0, 500.0,
320.0, 240.0, -1.0,
0.0, 1.0, 0.0);


(Note the 500.0). You were standing really really close to your quad.

03-28-2001, 08:11 PM
God. Thank you. I was working on solving the problem myself just now and had just managed to narrow it down to a problem with my viewing. Now that I think about it, it makes perfect sense - I was so close that the brownish-orange I was seeing was the color of a small part of the bitmap, blown up to fill the entire field of vision. Sigh. http://www.opengl.org/discussion_boards/ubb/smile.gif

Thanks very much again - I truly appreciate it!

-Will http://www.opengl.org/discussion_boards/ubb/smile.gif