Hoy propongo un código para simular efecto plasma dinámicamente con instrucciones matemáticas. No se equieren recursos adicionales o dependencias a archivos de imagenes externos. Podrás encontrar una demostración de la utilización de la clase CPlasma en el archivo relacionado, al final de este artículo.
[Hagamos algo de arte en nuestro monitor]
//CPlasma.h
/****************************************************************************
**
** $Nombre: CPlasma
**
** $Autor: h0aX
**
** $Fecha: 24/agosto/2008
**
** $Descripción: Módulo para generación de texturas dinámicas
** con reproducción de efecto plasma. Este código
** está basado en uno de los demos de Jan Horn (http://www.sulaco.co.za)
**
****************************************************************************/
#ifndef CPlasmaH
#define CPlasmaH
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <glaux.h>
#include <math.h>
typedef struct
{
BYTE R;
BYTE G;
BYTE B;
}
CPixel;
class CPlasma
{
private:
GLuint PlasmaTex;
char *Plasma;
int Sr[8];
int Sc[8];
int sinHalfTable[512];
int sinOneTable[512];
int sinTwoTable[512];
int sinFourTable[512];
GLuint CreateTexture(int Width, int Height, GLvoid *pData);
public:
CPlasma();
~CPlasma();
void UpdateTexture();
};
#endif
//CPlasma.cpp
#include "CPlasma.h"
GLuint CPlasma::CreateTexture(int Width, int Height, GLvoid *pData)
{
GLuint Texture;
if (NULL == pData)
{
MessageBox(NULL, "Error creando texturas", "Plasma Module", MB_ICONERROR);
return 0;
}
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);
return Texture;
}
void CPlasma::UpdateTexture()
{
WORD x[4], xCount[4], y[4], yCount[4];
int i, j, c;
CPixel *Pixel;
for (c=0; c<4; c++)
y[c] = Sr[c+4];
for (c=0; c<4; c++)
{
xCount[c] = Sc[c];
yCount[c] = Sc[c+4];
}
for (i=0; i<64; i++)
{
for (c=0; c<4; c++)
x[c] = Sr[c];
for (c=0; c<4; c++)
{
xCount[c] = (Sc[c] + i*2) % 512;
yCount[c] = (Sc[c+4] + i*2) % 512;
}
for (j=0; j<64; j++)
{
Pixel = (CPixel *)(Plasma + (3*(i*64 + j)));
Pixel->R=((sinHalfTable[x[0]]+sinOneTable[x[1]]+sinTwoTable[x[2]]+sinFourTable[x[3]])+(sinHalfTable[y[0]]+sinOneTable[y[1]]+sinTwoTable[y[2]]+sinFourTable[y[3]]))>>3; Pixel->G=((sinHalfTable[x[2]]+sinOneTable[x[3]]+sinTwoTable[x[0]]+sinFourTable[x[1]])+(sinHalfTable[y[2]]+sinOneTable[y[3]]+sinTwoTable[y[0]]+sinFourTable[y[1]]))>>3;
Pixel->B=((sinHalfTable[x[3]]+sinOneTable[x[0]]+sinTwoTable[x[1]]+sinFourTable[x[2]])+(sinHalfTable[y[1]]+sinOneTable[y[2]]+sinTwoTable[y[3]]+sinFourTable[y[0]]))>>3;
for (c=0; c<4; c++)
{
x[c] = ((x[c] + (sinTwoTable[xCount[c]])/32 -4 + 512)) % 512;
xCount[c] = (xCount[c] + 2) % 512;
}
}
for (c=0; c<4; c++)
y[c] = (y[c] + (sinOneTable[yCount[c]])/32 -4 + 512) % 512;
}
for (c=0; c<8; c++)
{
Sr[c] = (Sr[c] + (sinTwoTable[Sc[c]])/32 -4 + 512) % 512;
Sc[c] = (Sc[c] + 2) % 512;
}
glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, Plasma);
}
CPlasma::CPlasma()
{
GLfloat temp;
Plasma = new char[64*64*3];
memset(Plasma, 255, 64*64*3);
PlasmaTex = CreateTexture(64, 64, Plasma);
UpdateTexture();
for (int i=0; i<8; i++)
{
Sr[i] = random(256);
Sc[i] = Sr[i];
}
for (int i=0; i<512; i++)
{
temp = 4 * M_PI * i / 512;
sinHalfTable[i] = (sin(temp/2)*128 + 128);
sinOneTable[i] = (sin(temp )*128 + 128);
sinTwoTable[i] = (sin(temp*2)*128 + 128);
sinFourTable[i] = (sin(temp*4)*128 + 128);
}
}
CPlasma::~CPlasma()
{
delete[] Plasma;
}
Archivos relacionados
Plasma.zip