Original Post
Hello, I''m making a test particle engine demo - from Nehe tutorial 18. Everything works, except the texture isn''t "gl_modulating" with the current color. Could someone please tell me what I''m doing wrong?
I don''t have a signature
// Created 3/20/03 - Another test particle demo
#include "setupwindow.h"
#include "imagefilefunc.h"
#include <ctime>
#include <cstdlib>
struct PARTICLE
{
bool bActive; // Is this particle active or not
int iLife; // Life of this particle
unsigned char ucFade; // Subtract life to kill the particle
float xpos; // Base x position of particle
float ypos; // Base y position of particle
float zpos; // Base z position of particle
float xdir; // X direction particle is heading
float ydir; // y direction particle is heading
float zdir; // z direction particle is heading
float xgrv; // x gravity
float ygrv; // y gravity
float zgrv; // z gravity
unsigned char ucRed; // Red component of particle
unsigned char ucGreen; // Green component of particle
unsigned char ucBlue; // Blue component of particle
};
const int MAX_PARTICLES = 1000;
float xspeed = 0.0f; // x direction particles are heading
float yspeed = 0.0f; // y direction partilces are heading
float slowdown = 2.0f; // Speed particles are spurting.
float zoom = -40; // Zoom factor for particles
PARTICLE ple[MAX_PARTICLES]; // Particles that are to be display
unsigned char* startex = 0, *bgtex =0; // Textures for particles and background, respectively
BITMAPINFOHEADER bmp1, bmp2; // The bitmap info header
GLuint texobj[2]; // Our texture objects
SetupWindow wnd; // Window creation object
bool extern keypad[256]; // Keyboard handler
int Error;
int InitGL()
{
int error = 0;
if(error = BitmapLoad("particle.bmp", &startex, &bmp1))
return (error);
if(error = BitmapLoad("bgtex.bmp", &bgtex, &bmp2))
{
free(startex);
return (error);
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_LIGHTING); // Disable lighting
glGenTextures(2, texobj);
glBindTexture(GL_TEXTURE_2D, texobj[0]); // The star texture is the first
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);
error = glGetError();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bmp1.biWidth, bmp1.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, startex);
glBindTexture(GL_TEXTURE_2D, texobj[1]); // The background texture is the second texture
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_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bmp2.biWidth, bmp2.biHeight, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, bgtex);
free(startex);
free(bgtex);
startex = 0;
bgtex = 0;
srand(time(0)); // Initialize the random seed generator
for(int loop = 0; loop < MAX_PARTICLES; loop++)
{
ple[loop].bActive = true; // Make all particles active
ple[loop].iLife = rand() % 256; // Give each particle random life
ple[loop].ucFade = rand() % 70; // Give each particle random fade value
ple[loop].xdir = float((rand() % 53) - 26.0f); // Give particle initial random direction
ple[loop].ydir = float((rand() % 53) - 26.0f);
ple[loop].zdir = float((rand() % 53) - 26.0f);
ple[loop].xgrv = 0.0f; // Give particle initial 0 x gravity
ple[loop].ygrv = -0.9f; // Give particle initial -0.9 y gravity
ple[loop].zgrv = 0.0f; // Give particle initial 0 z gravity
ple[loop].ucRed = rand() % 256; // Give particle random red color
ple[loop].ucGreen = rand() % 256; // Give particle random green color
ple[loop].ucBlue = rand() % 256; // Give partilce random blue color
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Set the blending mode, but don''t enable it yet
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
error = glGetError();
return (error);
}
void CheckKeyboard()
{
if((keypad[VK_UP]) && (yspeed < 200.0f)) // Up arrow key pressed?
yspeed += 1.0f;
if((keypad[VK_DOWN]) && (yspeed > -200.0f)) // Down arrow key pressed?
yspeed -= 1.0f;
if((keypad[VK_RIGHT]) && (xspeed < 200.0f)) // Right arrow key presseD?
xspeed += 1.0f;
if((keypad[VK_LEFT]) && (xspeed > -200.0f)) // Left arrow key pressed?
xspeed -= 1.0f;
if(keypad[VK_NEXT]) // Page down key pressed?
zoom -= 0.1f;
if(keypad[VK_PRIOR]) // Page up key pressed?
zoom += 0.1f;
if(keypad[VK_ADD] && slowdown > -1.0f)
slowdown -= 0.01f;
if(keypad[VK_SUBTRACT] && slowdown < 4.0f)
slowdown += 0.01f;
}
void Render(HDC hDc)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texobj[1]); // Make the background texture the current texture
glDisable(GL_BLEND); // Disable blending
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-500, -500, -1000);
glTexCoord2i(1, 0); glVertex3f(500, -500, -1000);
glTexCoord2i(1, 1); glVertex3f(500, 500, -1000);
glTexCoord2i(0, 1); glVertex3f(-500, 500, -1000);
glEnd();
glBindTexture(GL_TEXTURE_2D, texobj[0]); // Make the star texture the current textue
glEnable(GL_BLEND);
for(int i = 0; i < MAX_PARTICLES; i++)
{
if(ple[i].bActive)
{
float x = ple[i].xpos;
float y = ple[i].ypos;
float z = ple[i].zpos + zoom;
glColor4ub(ple[i].ucRed, ple[i].ucGreen, ple[i].ucBlue, ple[i].iLife);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2i(1, 1); glVertex3f(x + 0.5f, y + 0.5f, z);
glTexCoord2i(0, 1); glVertex3f(x - 0.5f, y + 0.5f, z);
glTexCoord2i(1, 0); glVertex3f(x + 0.5f, y - 0.5f, z);
glTexCoord2i(0, 0); glVertex3f(x - 0.5f, y - 0.5f, z);
glEnd();
ple[i].xpos += ple[i].xdir / (slowdown * 1000); // Move the particle
ple[i].ypos += ple[i].ydir / (slowdown * 1000); // Move the particle
ple[i].zpos += ple[i].zdir / (slowdown * 1000); // Move the particle
ple[i].xdir += ple[i].xgrv; // Bring x gravity into play
ple[i].ydir += ple[i].ygrv; // Bring y gravity into play
ple[i].zdir += ple[i].zgrv; // Bring z gravity into play
ple[i].iLife -= ple[i].ucFade; // Take away some life
if(ple[i].iLife < 0.0f)
{
// Rejuvinate this particle
ple[i].iLife = 255;
ple[i].ucFade = (rand() % 70) + 1 ; // Give random fade value. Add 1 so Fade can''t be 0
ple[i].xpos = 0.0f;
ple[i].ypos = 0.0f;
ple[i].zpos = 0.0f;
ple[i].xdir = xspeed + float((rand() % 60) - 30.0f); // Give random x dir
ple[i].ydir = yspeed + float((rand() % 60) - 30.0f); // Give random y dir
ple[i].zdir = float((rand() % 60) - 30.0f);
ple[i].ucRed = rand() % 256;
ple[i].ucGreen = rand() % 256;
ple[i].ucBlue = rand() % 256;
}
if((keypad[VK_NUMPAD6]) && (ple[i].xgrv < 1.5f))
ple[i].xgrv += 0.01f; // Increase gravity to the right
if((keypad[VK_NUMPAD4]) && (ple[i].xgrv > -1.5f))
ple[i].xgrv -= 0.01f; // Increase gravity to the left
if((keypad[VK_NUMPAD8]) && (ple[i].ygrv < 1.5f))
ple[i].ygrv += 0.01f; // Increase gravity upwards
if((keypad[VK_NUMPAD2]) && (ple[i].ygrv > -1.5f))
ple[i].ygrv -= 0.01f; // Increase gravity downwards
if(keypad[VK_TAB])
{
// Reset everything
ple[i].xpos = 0.0f;
ple[i].ypos = 0.0f;
ple[i].zpos = 0.0f;
ple[i].xdir = float((rand() % 50) - 25.0f) * 10.0f;
ple[i].ydir = float((rand() % 50) - 25.0f) * 10.0f;
ple[i].zdir = float((rand() % 50) - 25.0f) * 10.0f;
}
} // End if
}// End for loop
SwapBuffers(hDc);
glFlush();
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE,
LPSTR,
int)
{
MSG msg;
wnd.wc.lpfnWndProc = PreDefWindowProc;
wnd.RegClass(hInstance);
wnd.CreateAWindow(false, 16, 1024, 768, "Particle Demo 2");
wnd.DisplayWindow();
wnd.SetupPixelFormat();
if(InitGL())
{
wnd.ReleaseAll();
return (0);
}
while(true)
{
if(PeekMessage(&msg, wnd.GetHandletoWindow(), 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CheckKeyboard();
Render(wnd.GetHdc());
}
glDeleteTextures(2, texobj);
wnd.ReleaseAll();
return (msg.wParam);
}