jueves, 28 de agosto de 2008

Plasma

h0aX [blackhat4all@gmail.com]

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

Artículos relacionados


No hay comentarios: