diff --git a/dat/outfit.xml b/dat/outfit.xml
index 5d87879..5a225e2 100644
--- a/dat/outfit.xml
+++ b/dat/outfit.xml
@@ -163,6 +163,7 @@
     <turn>50</turn>
     <energy>130</energy>
     <damage type="energy">100</damage>
+    <gfx>beam_ragnarok</gfx>
   </specific>
  </outfit>
  <outfit name="Seeker Launcher">
diff --git a/dat/ship.xml b/dat/ship.xml
index e4b8dc8..4dcbdaf 100644
--- a/dat/ship.xml
+++ b/dat/ship.xml
@@ -238,7 +238,8 @@
    <cap_cargo>10</cap_cargo>
   </characteristics>
   <outfits>
-   <outfit quantity="2">Ripper MK2</outfit>
+    <outfit quantity="2">Ripper MK2</outfit>
+    <outfit quantity="1">Ragnarok Beam</outfit>
    <outfit quantity="1">Headhunter Launcher</outfit>
    <outfit quantity="20">Headhunter</outfit>
   </outfits>
diff --git a/gfx/outfit/space/beam_ragnarok.png b/gfx/outfit/space/beam_ragnarok.png
new file mode 100644
index 0000000..50d6245
Binary files /dev/null and b/gfx/outfit/space/beam_ragnarok.png differ
diff --git a/src/opengl.c b/src/opengl.c
index 45f2256..30ce204 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -313,6 +313,10 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int *rw, int* rh) {
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
+  /* Always wrap just in case. */
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
   /* Now lead the texture data up. */
   SDL_LockSurface(surface);
   glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel,
diff --git a/src/outfit.c b/src/outfit.c
index 12cb330..9efc09f 100644
--- a/src/outfit.c
+++ b/src/outfit.c
@@ -280,6 +280,7 @@ int outfit_isMap(const Outfit* o) {
  */
 glTexture* outfit_gfx(const Outfit* o) {
   if(outfit_isBolt(o))        return o->u.blt.gfx_space;
+  else if(outfit_isBeam(o))   return o->u.bem.gfx;
   else if(outfit_isAmmo(o))   return o->u.amm.gfx_space;
   else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
   return NULL;
@@ -561,22 +562,32 @@ static void outfit_parseSBolt(Outfit* tmp, const xmlNodePtr parent) {
  */
 static void outfit_parseSBeam(Outfit* tmp, const xmlNodePtr parent) {
   xmlNodePtr node;
-  
+  char str[PATH_MAX] = "\0";
+
   node = parent->xmlChildrenNode;
   do {  /* Load all the data. */
     xmlr_float(node, "range",     tmp->u.bem.range);
     xmlr_float(node, "turn",      tmp->u.bem.turn);
     xmlr_float(node, "energy",    tmp->u.bem.energy);
     xmlr_long(node,  "delay",     tmp->u.bem.delay);
+    xmlr_float(node, "warmup",    tmp->u.bem.warmup);
     xmlr_float(node, "duration",  tmp->u.bem.duration);
 
-    if(xml_isNode(node, "damage"))
+    if(xml_isNode(node, "damage")) {
       outfit_parseDamage(&tmp->u.bem.dtype, &tmp->u.bem.damage, node);
+      continue;
+    }
+
+    if(xml_isNode(node, "gfx")) {
+      snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
+          OUTFIT_GFX"space/%s.png", xml_get(node));
+      tmp->u.bem.gfx = gl_newSprite(str, 1, 1);
+      continue;
+    }
   } while(xml_nextNode(node));
   
-  tmp->u.bem.colour = &cWhite; /** @todo Make it loadable. */
-
 #define MELEMENT(o,s) if(0) WARN("Outfit '%s' missing/invalid '"s"' element", tmp->name)
+  MELEMENT(tmp->u.bem.gfx==NULL,    "gfx");
   MELEMENT(tmp->u.bem.delay==0,     "range");
   MELEMENT(tmp->u.bem.duration==0,  "duration");
   MELEMENT(tmp->u.bem.range==0,     "range");
@@ -590,8 +601,8 @@ static void outfit_parseSBeam(Outfit* tmp, const xmlNodePtr parent) {
 /* Parse the specific area for a launcher and loads it into Outfit. */
 static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
   xmlNodePtr node;
+  
   node = parent->xmlChildrenNode;
-
   do {
     /* Load the dataz. */
     if(xml_isNode(node, "delay")) tmp->u.lau.delay = xml_getInt(node);
diff --git a/src/outfit.h b/src/outfit.h
index 5a96911..e4ba241 100644
--- a/src/outfit.h
+++ b/src/outfit.h
@@ -52,6 +52,7 @@ typedef struct OutfitBoltData_ {
   DamageType dtype;     /**< Damage type. */
   double damage;        /**< damage. */
 
+  /* Sound and graphics. */
   glTexture* gfx_space; /**< Graphic. */
   int sound;            /**< Sound to play. */
   int spfx;             /**< Special effect on hit. */
@@ -63,14 +64,21 @@ typedef struct OutfitBoltData_ {
  * @brief Represents the particular properties of a beam weapon.
  */
 typedef struct OutfitBeamData_ {
+  /* Time stuff. */
   unsigned int delay;     /**< Delay between usage. */
-  unsigned int duration;  /**< How long the beam lasts active. */
+  double warmup;          /**< How long it takes to warm up. */
+  double duration;        /**< How long the beam lasts active. */
+
+  /* Beam properties. */
   double range;           /**< How far it goes. */
   double turn;            /**< How fast it can turn. Only for turrets. */
   glColour* colour;       /**< Beam colour. */
   double energy;          /**< Amount of energy it drains (per second). */
   DamageType dtype;       /**< Damage type. */
   double damage;          /**< Damage amount. */
+
+  /* Graphics */
+  glTexture* gfx;         /**< Base texture. */
 } OutfitBeamData;
 
 /**
diff --git a/src/weapon.c b/src/weapon.c
index 78d7635..5d9a5b3 100644
--- a/src/weapon.c
+++ b/src/weapon.c
@@ -373,16 +373,51 @@ static void weapon_render(const Weapon* w) {
     /* Beam weapons. */
     case OUTFIT_TYPE_BEAM:
     case OUTFIT_TYPE_TURRET_BEAM:
+      gfx = outfit_gfx(w->outfit);
       x = w->solid->pos.x - VX(*gl_camera) + gui_xoff;
       y = w->solid->pos.y - VY(*gl_camera) + gui_yoff;
-      ACOLOUR(*w->outfit->u.bem.colour, 0.8);
-      glLineWidth(3.);
-      glBegin(GL_LINES);
-        glVertex2d(x, y);
-        glVertex2d(x + w->outfit->u.bem.range * cos(w->solid->dir),
-            y + w->outfit->u.bem.range * sin(w->solid->dir));
+
+      /* Set up the matrix. */
+      glMatrixMode(GL_PROJECTION);
+      glPushMatrix();
+        glTranslated(x, y, 0.);
+        glRotated(270. + w->solid->dir / M_PI * 180., 0., 0., 1.);
+
+      /* Preparatives. */
+      glEnable(GL_TEXTURE_2D);
+      glBindTexture(GL_TEXTURE_2D, gfx->texture);
+      glShadeModel(GL_SMOOTH);
+
+      /* Actual rendering. */
+      glBegin(GL_QUAD_STRIP);
+        COLOUR(cWhite);
+
+        /* Full strength. */
+        glTexCoord2d(0., 0.);
+        glVertex2d(-gfx->sh/2., 0.);
+
+        glTexCoord2d(0., 1.);
+        glVertex2d(+gfx->sh/2., 0.);
+
+        glTexCoord2d(0.8*w->outfit->u.bem.range / gfx->sw, 0.);
+        glVertex2d(+gfx->sh/2., 0.8*w->outfit->u.bem.range);
+
+        /* Fades out. */
+        ACOLOUR(cWhite, 0.);
+
+        glTexCoord2d(w->outfit->u.bem.range / gfx->sw, 0.);
+        glVertex2d(-gfx->sh/2., w->outfit->u.bem.range);
+
+        glTexCoord2d(w->outfit->u.bem.range / gfx->sw, 1.);
+        glVertex2d(+gfx->sh/2., w->outfit->u.bem.range);
       glEnd();
-      glLineWidth(1.);
+
+      /* Clean up. */
+      glDisable(GL_TEXTURE_2D);
+      glShadeModel(GL_FLAT);
+      glPopMatrix();
+      gl_checkErr();
+
       break;
 
     default: