PDA

View Full Version : textures are slow



07-09-2003, 06:30 PM
I know I have an old and slow computer and I am trying to save for a new one. It only has a Riva TNT graphics card and was purchased in 2001. But my textures are so slow that I might as well not use them.

1). Is there a way to speed them up?

2). The card has 80M for textures but can only support textures of sizes 1024x1024. Is this a normal limitation?

Orzech
07-10-2003, 07:17 AM
Hello!

Why do you say that textures are so slow? What are you trying to do? Even your Riva TNT is able to draw textured primitivies well. There are games which are fully 3d and run fluently of Riva TNT's. It means that
you are making some extreme use of your graphics card, aren't you? http://www.opengl.org/discussion_boards/ubb/wink.gif

Meaby you can post some code so I can look what's wrong. But there is plenty of things you should remember about :
- don't use big textures (stop with maximum 256x256 on your Riva)
- use fast texture filters GL_NEAREST, GL_LINEAR
- using mipmap textures makes application runs more slowly
- try to group your commands in display lists

That's all for know. Give some example and meaby I can help you more

JanHH
07-10-2003, 07:33 AM
when the tnt was new it was cool, not slow http://www.opengl.org/discussion_boards/ubb/wink.gif. even mipmapping should run great, on my tnt2 (i guess you have one if its from 2001) games like unreal and quake 3 were absolutely fluently. so if your graphic is not more complex than these, it should run well http://www.opengl.org/discussion_boards/ubb/wink.gif.

Jan

07-11-2003, 05:48 PM
Thanks for the replies. I am just experimenting with textures and it is not at all a complicated program or graphic. I do have the TNT2. Unreal tournament runs perfectly but it favors DirectX over openGL.
Textures are fine until the users perspective gets close to it. Then it slows to a crawl.
Here is the code:

-----------------begin code -----------------------
// FScreen.c
// OpenGL SuperBible, Chapter 17
// Program by Richard S. Wright Jr.
// This program shows a how to create a full screen
// window and render into it with OpenGL.
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl/glut.h>
#include <math.h>
#include <math.h>
#include "bitmap.h" //for: BITMAPINFO, BITMAPFILEHEADER
#include <stdio.h> //for: fopen, fclose, fread
#include <stdlib.h>
#include <errno.h>


///////////////////////////GLOBALS SECTION//////////////////////////////////

HPALETTE hPalette = NULL;
// Keep track of windows changing width and height
GLfloat windowWidth;
GLfloat windowHeight;
static LPCTSTR lpszAppName = "GLRect";
#define DEGTORAD(x) ((x)*0.017453292519943296)
LPCTSTR wd = "C:\\Program Files\\Microsoft Visual Studio\\MyProjects\\Textures\\";

struct CAMERA
{
float position[3];
float orientation[3];
} cameraData;


float linearSpeed = 1.0;
float angularSpeed = 3.0;


////////////////////////////////////////////////////////////////////////////

////////////////////////FUNCTION PROTOTYPES/////////////////////////////////
HPALETTE GetOpenGLPalette(HDC hDC);
// Declaration for Window procedure
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);

// Set Pixel Format function - forward declaration
void SetDCPixelFormat(HDC hDC);
GLubyte * LoadDIBitmap(const char *filename, BITMAPINFO **info) ;
void SetDCPixelFormat(HDC hDC);
////////////////////////////////////////////////////////////////////////////


void a()
{
MessageBox(NULL, "YOU MADE IT", "YEP", NULL);
}

void ChangeSize(GLsizei w, GLsizei h)
{
// Prevent a divide by zero, when window is too short
/* // (you cant make a window of zero width).
if(h == 0)
h = 1;

// Set the viewport to be the entire window
glViewport(0, 0, w, h);

// Reset the coordinate system before modifying

glMatrixMode(GL_PROJECTION);
glLoadIdentity();


gluPerspective(45,1.25,1,1000);

glMatrixMode(GL_MODELVIEW);
*/

}


void checkKeyPresses()
{

if (GetAsyncKeyState(VK_LEFT) )
{
cameraData.position[0] += sin(DEGTORAD(cameraData.orientation[1]-90)) * linearSpeed;
cameraData.position[2] += cos(DEGTORAD(cameraData.orientation[1]-90)) * linearSpeed;
}

if (GetAsyncKeyState(VK_RIGHT))
{
cameraData.position[0] += sin(DEGTORAD(cameraData.orientation[1]+90)) * linearSpeed;
cameraData.position[2] += cos(DEGTORAD(cameraData.orientation[1]+90)) * linearSpeed;
}

if (GetAsyncKeyState(VK_UP))
{
cameraData.position[0] += sin(DEGTORAD(cameraData.orientation[1])) * linearSpeed;
cameraData.position[2] -= cos(DEGTORAD(cameraData.orientation[1])) * linearSpeed;
}

if (GetAsyncKeyState(VK_DOWN) )
{
cameraData.position[0] -= sin(DEGTORAD(cameraData.orientation[1])) * linearSpeed;
cameraData.position[2] += cos(DEGTORAD(cameraData.orientation[1])) * linearSpeed;
}

if (GetAsyncKeyState(VK_INSERT))
{
linearSpeed += .1;
angularSpeed += .1;
}

if (GetAsyncKeyState(VK_DELETE))
{
if (!(linearSpeed < 0)) linearSpeed -= .1;
if (!(angularSpeed < 0)) angularSpeed -= .1;
}

if (cameraData.position[2] < 5) cameraData.position[2] = 5;
}

void setCamera()
{

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(cameraData.orientation[0], 1,0,0);
glRotatef(cameraData.orientation[1], 0,1,0);
glRotatef(cameraData.orientation[2], 0,0,1);

glTranslatef(-cameraData.position[0],
-cameraData.position[1],
-cameraData.position[2]);
}

// Called by AUX library to draw scene
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(-100,0,0);
glVertex3f(100,0,0);

glColor3f(0,1,0);
glVertex3f(0,-100,0);
glVertex3f(0,100,0);

glColor3f(0,0,1);
glVertex3f(0,0,-100);
glVertex3f(0,0,100);

glVertex3f(-5,0,3);
glVertex3f(5,0,3);
glEnd();


glEnable(GL_TEXTURE_2D);

glBegin(GL_QUADS);
glColor3f(1,1,1);
glTexCoord2f(0,0); glVertex3f(0,0,0);
glTexCoord2f(0,1); glVertex3f(0,3,0);
glTexCoord2f(1,1); glVertex3f(3,3,0);
glTexCoord2f(1,0); glVertex3f(3,0,0);
glEnd();
glDisable(GL_TEXTURE_2D);

checkKeyPresses();
setCamera();
}


void setUp(void)
{
BITMAPINFO *info;
GLubyte *pixels;
GLuint texNames;
glClearColor(0,0,0,1);

glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(30, 1.25, 1,250);

cameraData.orientation[0] = 0;
cameraData.orientation[1] = 0;
cameraData.orientation[2] = 0;
cameraData.position[0] = 0;
cameraData.position[1] = 1;
cameraData.position[2] = 20;

pixels = LoadDIBitmap("C:\\Program Files\\Microsoft Visual Studio\\MyProjects\\Textures\\floor.bmp",&info);
glGenTextures(1, &texNames);
glBindTexture(GL_TEXTURE_2D, texNames);



glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_DECAL);

glTexImage2D(GL_TEXTURE_2D,0,3, info->bmiHeader.biWidth,
info->bmiHeader.biHeight,0,GL_BGR_EXT,
GL_UNSIGNED_BYTE,pixels);

}


// Entry point of all Windows programs
int APIENTRY WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; // Windows message structure
WNDCLASS wc; // Windows class structure
HWND hWnd; // Storeage for window handle
HWND hDesktopWnd;// Storeage for desktop window handle
HDC hDesktopDC; // Storeage for desktop window device context
int nScreenX, nScreenY; // Screen Dimensions


// Register Window style
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursorFromFile("Blank.cur");


// No need for background brush for OpenGL window
wc.hbrBackground = NULL;

wc.lpszMenuName = NULL;
wc.lpszClassName = lpszAppName;

// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;

// Get he Window handle and Device context to the desktop
hDesktopWnd = GetDesktopWindow();
hDesktopDC = GetDC(hDesktopWnd);



// Get the screen size
nScreenX = GetDeviceCaps(hDesktopDC, HORZRES);
nScreenY = GetDeviceCaps(hDesktopDC, VERTRES);

// Release the desktop device context
ReleaseDC(hDesktopWnd, hDesktopDC);

// Create the main application window
hWnd = CreateWindow(
lpszAppName,
lpszAppName,

// OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,

// Window position and size
0, 0,
nScreenX, nScreenY,
NULL,
NULL,
hInstance,
NULL);


// If window was not created, quit
if(hWnd == NULL)
return FALSE;


// Display the window
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);


// Process application messages until the application closes
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

// Window procedure, handles all messages for this program
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HGLRC hRC; // Permenant Rendering context
static HDC hDC; // Private GDI Device context

switch (message)
{
// Window creation, setup for OpenGL
case WM_CREATE:
// Store the device context
hDC = GetDC(hWnd);

// Select the pixel format
SetDCPixelFormat(hDC);

// Create the rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

// Create the palette
hPalette = GetOpenGLPalette(hDC);
setUp();


break;

case WM_MOUSEMOVE:

if (LOWORD(lParam) > 400) cameraData.orientation[1] += angularSpeed;
if (LOWORD(lParam) < 400) cameraData.orientation[1] -= angularSpeed;
if (HIWORD(lParam) > 300) cameraData.orientation[0] += angularSpeed;
if (HIWORD(lParam) < 300) cameraData.orientation[0] -= angularSpeed;

SetCursorPos(400,300);

if (cameraData.orientation[0] > 90) cameraData.orientation[0] = 90;
if (cameraData.orientation[0] < -90) cameraData.orientation[0] =-90;

RenderScene();
SwapBuffers(hDC);
ValidateRect(hWnd,NULL);
break;


// Window is being destroyed, cleanup
case WM_DESTROY:
// Kill the timer that we created
KillTimer(hWnd,101);

// Deselect the current rendering context and delete it
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);

// Delete the palette
if(hPalette != NULL)
DeleteObject(hPalette);

// Tell the application to terminate after the window
// is gone.
PostQuitMessage(0);
break;

// Window is resized.
case WM_SIZE:
// Call our function which modifies the clipping
// volume and viewport
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;

// The painting function. This message sent by Windows
// whenever the screen needs updating.
case WM_PAINT:
{
RenderScene();
SwapBuffers(hDC);
ValidateRect(hWnd,NULL);
}
break;


// Windows is telling the application that it may modify
// the system palette. This message in essance asks the
// application for a new palette.
case WM_QUERYNEWPALETTE:
// If the palette was created.
if(hPalette)
{
int nRet;

// Selects the palette into the current device context
SelectPalette(hDC, hPalette, FALSE);

// Map entries from the currently selected palette to
// the system palette. The return value is the number
// of palette entries modified.
nRet = RealizePalette(hDC);

// Repaint, forces remap of palette in current window
InvalidateRect(hWnd,NULL,FALSE);

return nRet;
}
break;


// This window may set the palette, even though it is not the
// currently active window.
case WM_PALETTECHANGED:
// Don't do anything if the palette does not exist, or if
// this is the window that changed the palette.
if((hPalette != NULL) && ((HWND)wParam != hWnd))
{
// Select the palette into the device context
SelectPalette(hDC,hPalette,FALSE);

// Map entries to system palette
RealizePalette(hDC);

// Remap the current colors to the newly realized palette
UpdateColors(hDC);
return 0;
}
break;


default: // Passes it on if unproccessed
return (DefWindowProc(hWnd, message, wParam, lParam));

}

return (0L);
}

// If necessary, creates a 3-3-2 palette for the device context listed.
HPALETTE GetOpenGLPalette(HDC hDC)
{
HPALETTE hRetPal = NULL; // Handle to palette to be created
PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
LOGPALETTE *pPal; // Pointer to memory for logical palette
int nPixelFormat; // Pixel format index
int nColors; // Number of entries in palette
int i; // Counting variable
BYTE RedRange,GreenRange,BlueRange;
// Range for each color entry (7,7,and 3)


// Get the pixel format index and retrieve the pixel format description
nPixelFormat = GetPixelFormat(hDC);
DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

// Does this pixel format require a palette? If not, do not create a
// palette and just return NULL
if(!(pfd.dwFlags & PFD_NEED_PALETTE))
return NULL;

// Number of entries in palette. 8 bits yeilds 256 entries
nColors = 1 << pfd.cColorBits;

// Allocate space for a logical palette structure plus all the palette entries
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));

// Fill in palette header
pPal->palVersion = 0x300; // Windows 3.0
pPal->palNumEntries = nColors; // table size

// Build mask of all 1's. This creates a number represented by having
// the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
// pfd.cBlueBits.
RedRange = (1 << pfd.cRedBits) -1;
GreenRange = (1 << pfd.cGreenBits) - 1;
BlueRange = (1 << pfd.cBlueBits) -1;

// Loop through all the palette entries
for(i = 0; i < nColors; i++)
{
// Fill in the 8-bit equivalents for each component
pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
pPal->palPalEntry[i].peRed = (unsigned char)(
(double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);

pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
pPal->palPalEntry[i].peGreen = (unsigned char)(
(double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);

pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
pPal->palPalEntry[i].peBlue = (unsigned char)(
(double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);

pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
}


// Create the palette
hRetPal = CreatePalette(pPal);

// Go ahead and select and realize the palette for this device context
SelectPalette(hDC,hRetPal,FALSE);
RealizePalette(hDC);

// Free the memory used for the logical palette structure
free(pPal);

// Return the handle to the new palette
return hRetPal;
}
// Select the pixel format for a given device context
void SetDCPixelFormat(HDC hDC)
{
int nPixelFormat;

static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
PFD_DOUBLEBUFFER, // Double buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
32, // Want 32 bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
16, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
0, // Not used to select mode
0, // Not used to select mode
0,0,0 }; // Not used to select mode

// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hDC, &pfd);

// Set the pixel format for the device context
SetPixelFormat(hDC, nPixelFormat, &pfd);
}

-------------------end code-----------------

07-11-2003, 05:54 PM
Here is bitmap.c and bitmap.h. Blank.cur is just a transparent cursor file.

----------bitmap.c-----------------------


/*
* Windows BMP file functions for OpenGL.
*
* Written by Michael Sweet.
*/

#include "bitmap.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>


#ifdef WIN32
/*
* 'LoadDIBitmap()' - Load a DIB/BMP file from disk.
*
* Returns a pointer to the bitmap if successful, NULL otherwise...
*/

GLubyte * /* O - Bitmap data */
LoadDIBitmap(const char *filename, /* I - File to load */
BITMAPINFO **info) /* O - Bitmap information */
{
FILE *fp; /* Open file pointer */
GLubyte *bits; /* Bitmap pixel bits */
int bitsize; /* Size of bitmap */
int infosize; /* Size of header information */
BITMAPFILEHEADER header; /* File header */


/* Try opening the file; use "rb" mode to read this *binary* file. */
if ((fp = fopen(filename, "rb")) == NULL)
return (NULL);

/* Read the file header and any following bitmap information... */
if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1)
{
/* Couldn't read the file header - return NULL... */
fclose(fp);
return (NULL);
}

if (header.bfType != 'MB') /* Check for BM reversed... */
{
/* Not a bitmap file - return NULL... */
fclose(fp);
return (NULL);
}

infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER);
if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL)
{
/* Couldn't allocate memory for bitmap info - return NULL... */
fclose(fp);
return (NULL);
}

if (fread(*info, 1, infosize, fp) < infosize)
{
/* Couldn't read the bitmap header - return NULL... */
free(*info);
fclose(fp);
return (NULL);
}

/* Now that we have all the header info read in, allocate memory for *
* the bitmap and read *it* in... */
if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0)
bitsize = ((*info)->bmiHeader.biWidth *
(*info)->bmiHeader.biBitCount + 7) / 8 *
abs((*info)->bmiHeader.biHeight);

if ((bits = malloc(bitsize)) == NULL)
{
/* Couldn't allocate memory - return NULL! */
free(*info);
fclose(fp);
return (NULL);
}

if (fread(bits, 1, bitsize, fp) < bitsize)
{
/* Couldn't read bitmap - free memory and return NULL! */
free(*info);
free(bits);
fclose(fp);
return (NULL);
}

/* OK, everything went fine - return the allocated bitmap... */
fclose(fp);
return (bits);
}


/*
* 'SaveDIBitmap()' - Save a DIB/BMP file to disk.
*
* Returns 0 on success or -1 on failure...
*/

int /* O - 0 = success, -1 = failure */
SaveDIBitmap(const char *filename, /* I - File to load */
BITMAPINFO *info, /* I - Bitmap information */
GLubyte *bits) /* I - Bitmap data */
{
FILE *fp; /* Open file pointer */
int size, /* Size of file */
infosize, /* Size of bitmap info */
bitsize; /* Size of bitmap pixels */
BITMAPFILEHEADER header; /* File header */


/* Try opening the file; use "wb" mode to write this *binary* file. */
if ((fp = fopen(filename, "wb")) == NULL)
return (-1);

/* Figure out the bitmap size */
if (info->bmiHeader.biSizeImage == 0)
bitsize = (info->bmiHeader.biWidth *
info->bmiHeader.biBitCount + 7) / 8 *
abs(info->bmiHeader.biHeight);
else
bitsize = info->bmiHeader.biSizeImage;

/* Figure out the header size */
infosize = sizeof(BITMAPINFOHEADER);
switch (info->bmiHeader.biCompression)
{
case BI_BITFIELDS :
infosize += 12; /* Add 3 RGB doubleword masks */
if (info->bmiHeader.biClrUsed == 0)
break;
case BI_RGB :
if (info->bmiHeader.biBitCount > 8 &&
info->bmiHeader.biClrUsed == 0)
break;
case BI_RLE8 :
case BI_RLE4 :
if (info->bmiHeader.biClrUsed == 0)
infosize += (1 << info->bmiHeader.biBitCount) * 4;
else
infosize += info->bmiHeader.biClrUsed * 4;
break;
}

size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;

/* Write the file header, bitmap information, and bitmap pixel data... */
header.bfType = 'MB'; /* Non-portable... sigh */
header.bfSize = size;
header.bfReserved1 = 0;
header.bfReserved2 = 0;
header.bfOffBits = sizeof(BITMAPFILEHEADER) + infosize;

if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER))
{
/* Couldn't write the file header - return... */
fclose(fp);
return (-1);
}

if (fwrite(info, 1, infosize, fp) < infosize)
{
/* Couldn't write the bitmap header - return... */
fclose(fp);
return (-1);
}

if (fwrite(bits, 1, bitsize, fp) < bitsize)
{
/* Couldn't write the bitmap - return... */
fclose(fp);
return (-1);
}

/* OK, everything went fine - return... */
fclose(fp);
return (0);
}


#else /* !WIN32 */
/*
* Functions for reading and writing 16- and 32-bit little-endian integers.
*/

static unsigned short read_word(FILE *fp);
static unsigned int read_dword(FILE *fp);
static int read_long(FILE *fp);

static int write_word(FILE *fp, unsigned short w);
static int write_dword(FILE *fp, unsigned int dw);
static int write_long(FILE *fp, int l);


/*
* 'LoadDIBitmap()' - Load a DIB/BMP file from disk.
*
* Returns a pointer to the bitmap if successful, NULL otherwise...
*/

GLubyte * /* O - Bitmap data */
LoadDIBitmap(const char *filename, /* I - File to load */
BITMAPINFO **info) /* O - Bitmap information */
{
FILE *fp; /* Open file pointer */
GLubyte *bits; /* Bitmap pixel bits */
GLubyte *ptr; /* Pointer into bitmap */
GLubyte temp; /* Temporary variable to swap red and blue */
int x, y; /* X and Y position in image */
int length; /* Line length */
int bitsize; /* Size of bitmap */
int infosize; /* Size of header information */
BITMAPFILEHEADER header; /* File header */


/* Try opening the file; use "rb" mode to read this *binary* file. */
if ((fp = fopen(filename, "rb")) == NULL)
return (NULL);

/* Read the file header and any following bitmap information... */
header.bfType = read_word(fp);
header.bfSize = read_dword(fp);
header.bfReserved1 = read_word(fp);
header.bfReserved2 = read_word(fp);
header.bfOffBits = read_dword(fp);

if (header.bfType != BF_TYPE) /* Check for BM reversed... */
{
/* Not a bitmap file - return NULL... */
fclose(fp);
return (NULL);
}

infosize = header.bfOffBits - 18;
if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFO))) == NULL)
{
/* Couldn't allocate memory for bitmap info - return NULL... */
fclose(fp);
return (NULL);
}

(*info)->bmiHeader.biSize = read_dword(fp);
(*info)->bmiHeader.biWidth = read_long(fp);
(*info)->bmiHeader.biHeight = read_long(fp);
(*info)->bmiHeader.biPlanes = read_word(fp);
(*info)->bmiHeader.biBitCount = read_word(fp);
(*info)->bmiHeader.biCompression = read_dword(fp);
(*info)->bmiHeader.biSizeImage = read_dword(fp);
(*info)->bmiHeader.biXPelsPerMeter = read_long(fp);
(*info)->bmiHeader.biYPelsPerMeter = read_long(fp);
(*info)->bmiHeader.biClrUsed = read_dword(fp);
(*info)->bmiHeader.biClrImportant = read_dword(fp);

if (infosize > 40)
if (fread((*info)->bmiColors, infosize - 40, 1, fp) < 1)
{
/* Couldn't read the bitmap header - return NULL... */
free(*info);
fclose(fp);
return (NULL);
}

/* Now that we have all the header info read in, allocate memory for *
* the bitmap and read *it* in... */
if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0)
bitsize = ((*info)->bmiHeader.biWidth *
(*info)->bmiHeader.biBitCount + 7) / 8 *
abs((*info)->bmiHeader.biHeight);

if ((bits = malloc(bitsize)) == NULL)
{
/* Couldn't allocate memory - return NULL! */
free(*info);
fclose(fp);
return (NULL);
}

if (fread(bits, 1, bitsize, fp) < bitsize)
{
/* Couldn't read bitmap - free memory and return NULL! */
free(*info);
free(bits);
fclose(fp);
return (NULL);
}

/* Swap red and blue */
length = ((*info)->bmiHeader.biWidth * 3 + 3) & ~3;
for (y = 0; y < (*info)->bmiHeader.biHeight; y ++)
for (ptr = bits + y * length, x = (*info)->bmiHeader.biWidth;
x > 0;
x --, ptr += 3)
{
temp = ptr[0];
ptr[0] = ptr[2];
ptr[2] = temp;
}

/* OK, everything went fine - return the allocated bitmap... */
fclose(fp);
return (bits);
}


/*
* 'SaveDIBitmap()' - Save a DIB/BMP file to disk.
*
* Returns 0 on success or -1 on failure...
*/

int /* O - 0 = success, -1 = failure */
SaveDIBitmap(const char *filename, /* I - File to load */
BITMAPINFO *info, /* I - Bitmap information */
GLubyte *bits) /* I - Bitmap data */
{
FILE *fp; /* Open file pointer */
int size, /* Size of file */
infosize, /* Size of bitmap info */
bitsize; /* Size of bitmap pixels */


/* Try opening the file; use "wb" mode to write this *binary* file. */
if ((fp = fopen(filename, "wb")) == NULL)
return (-1);

/* Figure out the bitmap size */
if (info->bmiHeader.biSizeImage == 0)
bitsize = (info->bmiHeader.biWidth *
info->bmiHeader.biBitCount + 7) / 8 *
abs(info->bmiHeader.biHeight);
else
bitsize = info->bmiHeader.biSizeImage;

/* Figure out the header size */
infosize = sizeof(BITMAPINFOHEADER);
switch (info->bmiHeader.biCompression)
{
case BI_BITFIELDS :
infosize += 12; /* Add 3 RGB doubleword masks */
if (info->bmiHeader.biClrUsed == 0)
break;
case BI_RGB :
if (info->bmiHeader.biBitCount > 8 &&
info->bmiHeader.biClrUsed == 0)
break;
case BI_RLE8 :
case BI_RLE4 :
if (info->bmiHeader.biClrUsed == 0)
infosize += (1 << info->bmiHeader.biBitCount) * 4;
else
infosize += info->bmiHeader.biClrUsed * 4;
break;
}

size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;

/* Write the file header, bitmap information, and bitmap pixel data... */
write_word(fp, BF_TYPE); /* bfType */
write_dword(fp, size); /* bfSize */
write_word(fp, 0); /* bfReserved1 */
write_word(fp, 0); /* bfReserved2 */
write_dword(fp, 18 + infosize); /* bfOffBits */

write_dword(fp, info->bmiHeader.biSize);
write_long(fp, info->bmiHeader.biWidth);
write_long(fp, info->bmiHeader.biHeight);
write_word(fp, info->bmiHeader.biPlanes);
write_word(fp, info->bmiHeader.biBitCount);
write_dword(fp, info->bmiHeader.biCompression);
write_dword(fp, info->bmiHeader.biSizeImage);
write_long(fp, info->bmiHeader.biXPelsPerMeter);
write_long(fp, info->bmiHeader.biYPelsPerMeter);
write_dword(fp, info->bmiHeader.biClrUsed);
write_dword(fp, info->bmiHeader.biClrImportant);

if (infosize > 40)
if (fwrite(info->bmiColors, infosize - 40, 1, fp) < 1)
{
/* Couldn't write the bitmap header - return... */
fclose(fp);
return (-1);
}

if (fwrite(bits, 1, bitsize, fp) < bitsize)
{
/* Couldn't write the bitmap - return... */
fclose(fp);
return (-1);
}

/* OK, everything went fine - return... */
fclose(fp);
return (0);
}


/*
* 'read_word()' - Read a 16-bit unsigned integer.
*/

static unsigned short /* O - 16-bit unsigned integer */
read_word(FILE *fp) /* I - File to read from */
{
unsigned char b0, b1; /* Bytes from file */

b0 = getc(fp);
b1 = getc(fp);

return ((b1 << 8) | b0);
}


/*
* 'read_dword()' - Read a 32-bit unsigned integer.
*/

static unsigned int /* O - 32-bit unsigned integer */
read_dword(FILE *fp) /* I - File to read from */
{
unsigned char b0, b1, b2, b3; /* Bytes from file */

b0 = getc(fp);
b1 = getc(fp);
b2 = getc(fp);
b3 = getc(fp);

return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}


/*
* 'read_long()' - Read a 32-bit signed integer.
*/

static int /* O - 32-bit signed integer */
read_long(FILE *fp) /* I - File to read from */
{
unsigned char b0, b1, b2, b3; /* Bytes from file */

b0 = getc(fp);
b1 = getc(fp);
b2 = getc(fp);
b3 = getc(fp);

return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}


/*
* 'write_word()' - Write a 16-bit unsigned integer.
*/

static int /* O - 0 on success, -1 on error */
write_word(FILE *fp, /* I - File to write to */
unsigned short w) /* I - Integer to write */
{
putc(w, fp);
return (putc(w >> 8, fp));
}


/*
* 'write_dword()' - Write a 32-bit unsigned integer.
*/

static int /* O - 0 on success, -1 on error */
write_dword(FILE *fp, /* I - File to write to */
unsigned int dw) /* I - Integer to write */
{
putc(dw, fp);
putc(dw >> 8, fp);
putc(dw >> 16, fp);
return (putc(dw >> 24, fp));
}


/*
* 'write_long()' - Write a 32-bit signed integer.
*/

static int /* O - 0 on success, -1 on error */
write_long(FILE *fp, /* I - File to write to */
int l) /* I - Integer to write */
{
putc(l, fp);
putc(l >> 8, fp);
putc(l >> 16, fp);
return (putc(l >> 24, fp));
}
#endif /* WIN32 */

---------------bitmap.h---------------------

/*
* Windows BMP file definitions for OpenGL.
*
* Written by Michael Sweet.
*/

#ifndef _BITMAP_H_
# define _BITMAP_H_

/*
* Include necessary headers.
*/

# include <GL/glut.h>
# ifdef WIN32
# include <windows.h>
# include <wingdi.h>
# endif /* WIN32 */

/*
* Make this header file work with C and C++ source code...
*/

# ifdef __cplusplus
extern "C" {
# endif /* __cplusplus */


/*
* Bitmap file data structures (these are defined in <wingdi.h> under
* Windows...)
*
* Note that most Windows compilers will pack the following structures, so
* when reading them under MacOS or UNIX we need to read individual fields
* to avoid differences in alignment...
*/

# ifndef WIN32
typedef struct /**** BMP file header structure ****/
{
unsigned short bfType; /* Magic number for file */
unsigned int bfSize; /* Size of file */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* Offset to bitmap data */
} BITMAPFILEHEADER;

# define BF_TYPE 0x4D42 /* "MB" */

typedef struct /**** BMP file info structure ****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */
} BITMAPINFOHEADER;

/*
* Constants for the biCompression field...
*/

# define BI_RGB 0 /* No compression - straight BGR data */
# define BI_RLE8 1 /* 8-bit run-length compression */
# define BI_RLE4 2 /* 4-bit run-length compression */
# define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */

typedef struct /**** Colormap entry structure ****/
{
unsigned char rgbBlue; /* Blue value */
unsigned char rgbGreen; /* Green value */
unsigned char rgbRed; /* Red value */
unsigned char rgbReserved; /* Reserved */
} RGBQUAD;

typedef struct /**** Bitmap information structure ****/
{
BITMAPINFOHEADER bmiHeader; /* Image header */
RGBQUAD bmiColors[256]; /* Image colormap */
} BITMAPINFO;
# endif /* !WIN32 */

/*
* Prototypes...
*/

extern GLubyte *LoadDIBitmap(const char *filename, BITMAPINFO **info);
extern int SaveDIBitmap(const char *filename, BITMAPINFO *info,
GLubyte *bits);

# ifdef __cplusplus
}
# endif /* __cplusplus */
#endif /* !_BITMAP_H_ */

JanHH
07-11-2003, 07:42 PM
where do textures slow down, in unreal tournament or your program? if in unreal torunament, something else in your computer seems to be broken as it should run perfectly on tnt2 (or your cpu is REALLY slow), if the second is the case, your program must be wrong somewhere, althoug i did not look at it as its too long and i do neither like nor am i experienced with windows programming.

Orzech
07-12-2003, 01:13 AM
Well I looked through the source code but I didn't find anything
supiciuous. Since it comes from OpenGL SuperBible it should be
correct. One thing I can say is that creating OpenGL window and
drawing is much simpler than they suggest. Meaby you should try
The Red Book or some we tutorials (www.gametutorials.com or some
of the Nehe's tuts). Anyway it shouldn't be cause of you program.
If use say that UT runs perfectly but it favors DirectX meaby it
means that you have some old OpenGL drivers. You should check it.

07-12-2003, 06:32 AM
Thank you orkeck. You are right. My video driver is very old. I finally downloaded the newer Nvidia drivers and things are flying now. I did not want to try it because the driver 18 megs and my apartment complex does not allow anything but a dial up. It took 2.5 hours. Thanks everyone.

Orzech
07-12-2003, 09:51 AM
Sure. No problem

Asshen
07-13-2003, 04:15 AM
Considering it slows down when you zoom on the primitive with texture, I'd say it's more of a fillrate problem.

Kris.