diff --git a/source/codeblocks/AssaultCube.cbp b/source/codeblocks/AssaultCube.cbp
index 760bee54..45b622db 100644
--- a/source/codeblocks/AssaultCube.cbp
+++ b/source/codeblocks/AssaultCube.cbp
@@ -296,6 +296,9 @@
+
+
+
diff --git a/source/src/Makefile b/source/src/Makefile
index 3122d239..b7252583 100644
--- a/source/src/Makefile
+++ b/source/src/Makefile
@@ -189,199 +189,205 @@ depend:
# DO NOT DELETE
crypto.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-crypto.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-crypto.o: protos.h
+crypto.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+crypto.o: console.h protos.h
audiomanager.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-audiomanager.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-audiomanager.o: protos.h
+audiomanager.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+audiomanager.o: console.h protos.h
client.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-client.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-client.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h bot/ac_bot.h
+client.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+client.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+client.o: bot/ac_bot.h
clientgame.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-clientgame.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-clientgame.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+clientgame.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+clientgame.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
clientgame.o: bot/ac_bot.h
clients2c.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-clients2c.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-clients2c.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+clients2c.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+clients2c.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
clients2c.o: bot/ac_bot.h
command.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-command.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-command.o: protos.h
+command.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+command.o: console.h protos.h
console.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-console.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-console.o: protos.h
+console.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+console.o: console.h protos.h
docs.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-docs.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+docs.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
editing.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-editing.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-editing.o: protos.h
+editing.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+editing.o: console.h protos.h
entities.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-entities.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-entities.o: protos.h
+entities.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+entities.o: console.h protos.h
i18n.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-i18n.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+i18n.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
log.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-log.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+log.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
main.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-main.o: entity.h world.h i18n.h command.h vote.h console.h protos.h jpegenc.h
+main.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
+main.o: jpegenc.h
menus.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-menus.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+menus.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
oggstream.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-oggstream.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-oggstream.o: protos.h
+oggstream.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+oggstream.o: console.h protos.h
openal.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-openal.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-openal.o: protos.h
+openal.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+openal.o: console.h protos.h
packetqueue.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-packetqueue.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-packetqueue.o: protos.h
+packetqueue.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+packetqueue.o: console.h protos.h
physics.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-physics.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-physics.o: protos.h
+physics.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+physics.o: console.h protos.h
protocol.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-protocol.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-protocol.o: protos.h
+protocol.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+protocol.o: console.h protos.h
rendercubes.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-rendercubes.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-rendercubes.o: protos.h
+rendercubes.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+rendercubes.o: console.h protos.h
rendergl.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-rendergl.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-rendergl.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h bot/ac_bot.h
+rendergl.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+rendergl.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+rendergl.o: bot/ac_bot.h
renderhud.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-renderhud.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-renderhud.o: protos.h
+renderhud.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+renderhud.o: console.h protos.h
rendermodel.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-rendermodel.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-rendermodel.o: protos.h tristrip.h modelcache.h vertmodel.h md2.h md3.h
+rendermodel.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+rendermodel.o: console.h protos.h tristrip.h modelcache.h vertmodel.h md2.h
+rendermodel.o: md3.h
renderparticles.o: cube.h platform.h tools.h geom.h model.h protocol.h
-renderparticles.o: sound.h weapon.h entity.h world.h i18n.h command.h vote.h
-renderparticles.o: console.h protos.h
+renderparticles.o: sound.h weapon.h entity.h world.h i18n.h command.h
+renderparticles.o: varray.h vote.h console.h protos.h
rendertext.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-rendertext.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-rendertext.o: protos.h
+rendertext.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+rendertext.o: console.h protos.h
rndmap.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-rndmap.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-rndmap.o: protos.h
+rndmap.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+rndmap.o: console.h protos.h
scoreboard.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-scoreboard.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-scoreboard.o: protos.h
+scoreboard.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+scoreboard.o: console.h protos.h
serverms.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-serverms.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-serverms.o: protos.h
+serverms.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+serverms.o: console.h protos.h
server.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-server.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-server.o: protos.h server.h servercontroller.h serverfiles.h serverchecks.h
-server.o: serverevents.h serveractions.h
+server.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+server.o: console.h protos.h server.h servercontroller.h serverfiles.h
+server.o: serverchecks.h serverevents.h serveractions.h
serverbrowser.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-serverbrowser.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-serverbrowser.o: protos.h
+serverbrowser.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+serverbrowser.o: console.h protos.h
shadow.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-shadow.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-shadow.o: protos.h
+shadow.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+shadow.o: console.h protos.h
sound.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-sound.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+sound.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
soundlocation.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-soundlocation.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-soundlocation.o: protos.h
+soundlocation.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+soundlocation.o: console.h protos.h
soundscheduler.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-soundscheduler.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-soundscheduler.o: protos.h
+soundscheduler.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+soundscheduler.o: console.h protos.h
stream.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-stream.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-stream.o: protos.h
+stream.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+stream.o: console.h protos.h
texture.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-texture.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-texture.o: protos.h scale.h
+texture.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+texture.o: console.h protos.h scale.h
tools.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-tools.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+tools.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
water.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-water.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+water.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
weapon.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-weapon.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-weapon.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h bot/ac_bot.h
-weapon.o: hudgun.h
+weapon.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+weapon.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+weapon.o: bot/ac_bot.h hudgun.h
wizard.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-wizard.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-wizard.o: protos.h
+wizard.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+wizard.o: console.h protos.h
world.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-world.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+world.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
world.o: bot/bot.h bot/bot_util.h bot/bot_waypoint.h bot/ac_bot.h
worldio.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-worldio.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-worldio.o: protos.h
+worldio.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+worldio.o: console.h protos.h
worldlight.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-worldlight.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-worldlight.o: protos.h
+worldlight.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+worldlight.o: console.h protos.h
worldocull.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-worldocull.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-worldocull.o: protos.h
+worldocull.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+worldocull.o: console.h protos.h
worldrender.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-worldrender.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-worldrender.o: protos.h
+worldrender.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+worldrender.o: console.h protos.h
zip.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-zip.o: entity.h world.h i18n.h command.h vote.h console.h protos.h
+zip.o: entity.h world.h i18n.h command.h varray.h vote.h console.h protos.h
bot/bot.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-bot/bot.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-bot/bot.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h bot/ac_bot.h
+bot/bot.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+bot/bot.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+bot/bot.o: bot/ac_bot.h
bot/botmanager.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-bot/botmanager.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-bot/botmanager.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
-bot/botmanager.o: bot/ac_bot.h
+bot/botmanager.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+bot/botmanager.o: console.h protos.h bot/bot.h bot/bot_util.h
+bot/botmanager.o: bot/bot_waypoint.h bot/ac_bot.h
bot/bot_ai.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-bot/bot_ai.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-bot/bot_ai.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+bot/bot_ai.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+bot/bot_ai.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
bot/bot_ai.o: bot/ac_bot.h
bot/bot_util.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-bot/bot_util.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-bot/bot_util.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
-bot/bot_util.o: bot/ac_bot.h
+bot/bot_util.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+bot/bot_util.o: console.h protos.h bot/bot.h bot/bot_util.h
+bot/bot_util.o: bot/bot_waypoint.h bot/ac_bot.h
bot/bot_waypoint.o: cube.h platform.h tools.h geom.h model.h protocol.h
-bot/bot_waypoint.o: sound.h weapon.h entity.h world.h i18n.h command.h vote.h
-bot/bot_waypoint.o: console.h protos.h bot/bot.h bot/bot_util.h
-bot/bot_waypoint.o: bot/bot_waypoint.h bot/ac_bot.h
+bot/bot_waypoint.o: sound.h weapon.h entity.h world.h i18n.h command.h
+bot/bot_waypoint.o: varray.h vote.h console.h protos.h bot/bot.h
+bot/bot_waypoint.o: bot/bot_util.h bot/bot_waypoint.h bot/ac_bot.h
bot/ac_bot.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-bot/ac_bot.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-bot/ac_bot.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
+bot/ac_bot.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+bot/ac_bot.o: console.h protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
bot/ac_bot.o: bot/ac_bot.h
bot/ac_bot_ai.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-bot/ac_bot_ai.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-bot/ac_bot_ai.o: protos.h bot/bot.h bot/bot_util.h bot/bot_waypoint.h
-bot/ac_bot_ai.o: bot/ac_bot.h
+bot/ac_bot_ai.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+bot/ac_bot_ai.o: console.h protos.h bot/bot.h bot/bot_util.h
+bot/ac_bot_ai.o: bot/bot_waypoint.h bot/ac_bot.h
cube.h.gch: platform.h tools.h geom.h model.h protocol.h sound.h weapon.h
-cube.h.gch: entity.h world.h i18n.h command.h vote.h console.h protos.h
+cube.h.gch: entity.h world.h i18n.h command.h varray.h vote.h console.h
+cube.h.gch: protos.h
crypto-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
crypto-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-crypto-standalone.o: vote.h console.h protos.h
+crypto-standalone.o: varray.h vote.h console.h protos.h
log-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h sound.h
-log-standalone.o: weapon.h entity.h world.h i18n.h command.h vote.h console.h
-log-standalone.o: protos.h
+log-standalone.o: weapon.h entity.h world.h i18n.h command.h varray.h vote.h
+log-standalone.o: console.h protos.h
protocol-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
protocol-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-protocol-standalone.o: vote.h console.h protos.h
+protocol-standalone.o: varray.h vote.h console.h protos.h
serverms-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
serverms-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-serverms-standalone.o: vote.h console.h protos.h
+serverms-standalone.o: varray.h vote.h console.h protos.h
server-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
server-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-server-standalone.o: vote.h console.h protos.h server.h servercontroller.h
-server-standalone.o: serverfiles.h serverchecks.h serverevents.h
-server-standalone.o: serveractions.h
+server-standalone.o: varray.h vote.h console.h protos.h server.h
+server-standalone.o: servercontroller.h serverfiles.h serverchecks.h
+server-standalone.o: serverevents.h serveractions.h
stream-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
stream-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-stream-standalone.o: vote.h console.h protos.h
+stream-standalone.o: varray.h vote.h console.h protos.h
tools-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
-tools-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h vote.h
-tools-standalone.o: console.h protos.h
+tools-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
+tools-standalone.o: varray.h vote.h console.h protos.h
wizard-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
wizard-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-wizard-standalone.o: vote.h console.h protos.h
+wizard-standalone.o: varray.h vote.h console.h protos.h
command-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
command-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-command-standalone.o: vote.h console.h protos.h
+command-standalone.o: varray.h vote.h console.h protos.h
master-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h
master-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h
-master-standalone.o: vote.h console.h protos.h
+master-standalone.o: varray.h vote.h console.h protos.h
diff --git a/source/src/cube.h b/source/src/cube.h
index b74d0bd5..594a8d2e 100644
--- a/source/src/cube.h
+++ b/source/src/cube.h
@@ -17,6 +17,7 @@
#include "command.h"
#ifndef STANDALONE
+ #include "varray.h"
#include "vote.h"
#include "console.h"
#endif
diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp
index ed323f3c..c9d6cce0 100644
--- a/source/src/rendergl.cpp
+++ b/source/src/rendergl.cpp
@@ -190,6 +190,9 @@ void disablepolygonoffset(GLenum type, bool restore)
}
}
+#define VARRAY_INTERNAL
+#include "varray.h"
+
void line(int x1, int y1, float z1, int x2, int y2, float z2)
{
glBegin(GL_TRIANGLE_STRIP);
diff --git a/source/src/tools.h b/source/src/tools.h
index bb6dfeb8..3e8a2662 100644
--- a/source/src/tools.h
+++ b/source/src/tools.h
@@ -473,6 +473,13 @@ template struct vector
advance(p.length());
}
+ T *pad(int n)
+ {
+ T *buf = reserve(n).buf;
+ advance(n);
+ return buf;
+ }
+
void put(const T &v) { add(v); }
void put(const T *v, int n)
diff --git a/source/src/varray.h b/source/src/varray.h
new file mode 100644
index 00000000..a8481b1c
--- /dev/null
+++ b/source/src/varray.h
@@ -0,0 +1,234 @@
+namespace varray
+{
+#ifndef VARRAY_INTERNAL
+ enum
+ {
+ ATTRIB_VERTEX = 1<<0,
+ ATTRIB_COLOR = 1<<1,
+ ATTRIB_NORMAL = 1<<2,
+ ATTRIB_TEXCOORD0 = 1<<3,
+ ATTRIB_TEXCOORD1 = 1<<4,
+ MAXATTRIBS = 5
+ };
+
+ extern vector data;
+
+ extern void enable();
+ extern void begin(GLenum mode);
+ extern void defattrib(int type, int size, GLenum format);
+
+ template
+ static inline void attrib(T x)
+ {
+ T *buf = (T *)data.pad(sizeof(T));
+ buf[0] = x;
+ }
+
+ template
+ static inline void attrib(T x, T y)
+ {
+ T *buf = (T *)data.pad(2*sizeof(T));
+ buf[0] = x;
+ buf[1] = y;
+ }
+
+ template
+ static inline void attrib(T x, T y, T z)
+ {
+ T *buf = (T *)data.pad(3*sizeof(T));
+ buf[0] = x;
+ buf[1] = y;
+ buf[2] = z;
+ }
+
+ template
+ static inline void attrib(T x, T y, T z, T w)
+ {
+ T *buf = (T *)data.pad(4*sizeof(T));
+ buf[0] = x;
+ buf[1] = y;
+ buf[2] = z;
+ buf[3] = w;
+ }
+
+ template
+ static inline void attribv(const T *v)
+ {
+ data.put((const uchar *)v, N*sizeof(T));
+ }
+
+ extern int end();
+ extern void disable();
+
+#else
+ struct attribinfo
+ {
+ int type, size, formatsize;
+ GLenum format;
+
+ attribinfo() : type(0), size(0), formatsize(0), format(GL_FALSE) {}
+
+ bool operator==(const attribinfo &a) const
+ {
+ return type == a.type && size == a.size && format == a.format;
+ }
+ bool operator!=(const attribinfo &a) const
+ {
+ return type != a.type || size != a.size || format != a.format;
+ }
+ };
+
+ vector data;
+ static attribinfo attribs[MAXATTRIBS], lastattribs[MAXATTRIBS];
+ static int enabled = 0, numattribs = 0, attribmask = 0, numlastattribs = 0, lastattribmask = 0, vertexsize = 0;
+ static GLenum primtype = GL_TRIANGLES;
+ static uchar *lastbuf = NULL;
+ static bool changedattribs = false;
+
+ void enable()
+ {
+ enabled = 0;
+ numlastattribs = lastattribmask = 0;
+ lastbuf = NULL;
+ }
+
+ void begin(GLenum mode)
+ {
+ primtype = mode;
+ }
+
+ void defattrib(int type, int size, GLenum format)
+ {
+ if(type == ATTRIB_VERTEX)
+ {
+ numattribs = 0;
+ vertexsize = 0;
+ }
+ changedattribs = true;
+ attribmask |= type;
+ attribinfo &a = attribs[numattribs++];
+ a.type = type;
+ a.size = size;
+ a.format = format;
+ switch(format)
+ {
+ case GL_UNSIGNED_BYTE: a.formatsize = 1; break;
+ case GL_BYTE: a.formatsize = 1; break;
+ case GL_UNSIGNED_SHORT: a.formatsize = 2; break;
+ case GL_SHORT: a.formatsize = 2; break;
+ case GL_UNSIGNED_INT: a.formatsize = 4; break;
+ case GL_INT: a.formatsize = 4; break;
+ case GL_FLOAT: a.formatsize = 4; break;
+ case GL_DOUBLE: a.formatsize = 8; break;
+ default: a.formatsize = 0; break;
+ }
+ a.formatsize *= size;
+ vertexsize += a.formatsize;
+ }
+
+ static inline void setattrib(const attribinfo &a, uchar *buf)
+ {
+ switch(a.type)
+ {
+ case ATTRIB_VERTEX:
+ if(!(enabled&a.type)) glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(a.size, a.format, vertexsize, buf);
+ break;
+ case ATTRIB_COLOR:
+ if(!(enabled&a.type)) glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(a.size, a.format, vertexsize, buf);
+ break;
+ case ATTRIB_NORMAL:
+ if(!(enabled&a.type)) glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(a.format, vertexsize, buf);
+ break;
+ case ATTRIB_TEXCOORD0:
+ if(!(enabled&a.type)) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(a.size, a.format, vertexsize, buf);
+ break;
+ case ATTRIB_TEXCOORD1:
+ glClientActiveTexture_(GL_TEXTURE1_ARB);
+ if(!(enabled&a.type)) glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(a.size, a.format, vertexsize, buf);
+ glClientActiveTexture_(GL_TEXTURE0_ARB);
+ break;
+ }
+ enabled |= a.type;
+ }
+
+ static inline void unsetattrib(const attribinfo &a)
+ {
+ switch(a.type)
+ {
+ case ATTRIB_VERTEX:
+ glDisableClientState(GL_VERTEX_ARRAY);
+ break;
+ case ATTRIB_COLOR:
+ glDisableClientState(GL_COLOR_ARRAY);
+ break;
+ case ATTRIB_NORMAL:
+ glDisableClientState(GL_NORMAL_ARRAY);
+ break;
+ case ATTRIB_TEXCOORD0:
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ break;
+ case ATTRIB_TEXCOORD1:
+ glClientActiveTexture_(GL_TEXTURE1_ARB);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTexture_(GL_TEXTURE0_ARB);
+ break;
+ }
+ }
+
+ int end()
+ {
+ if(data.empty()) return 0;
+ uchar *buf = data.getbuf();
+ bool forceattribs = numattribs != numlastattribs || buf != lastbuf;
+ if(forceattribs || changedattribs)
+ {
+ int diffmask = enabled & lastattribmask & ~attribmask;
+ if(diffmask) loopi(numlastattribs)
+ {
+ const attribinfo &a = lastattribs[i];
+ if(diffmask & a.type) unsetattrib(a);
+ }
+ loopi(numattribs)
+ {
+ const attribinfo &a = attribs[i];
+ if(forceattribs || a != lastattribs[i])
+ {
+ setattrib(a, buf);
+ lastattribs[i] = a;
+ }
+ buf += a.formatsize;
+ }
+ lastbuf = buf;
+ numlastattribs = numattribs;
+ lastattribmask = attribmask;
+ changedattribs = false;
+ }
+ int numvertexes = data.length()/vertexsize;
+ glDrawArrays(primtype, 0, numvertexes);
+ data.setsize(0);
+ return numvertexes;
+ }
+
+ void disable()
+ {
+ if(!enabled) return;
+ if(enabled&ATTRIB_VERTEX) glDisableClientState(GL_VERTEX_ARRAY);
+ if(enabled&ATTRIB_COLOR) glDisableClientState(GL_COLOR_ARRAY);
+ if(enabled&ATTRIB_NORMAL) glDisableClientState(GL_NORMAL_ARRAY);
+ if(enabled&ATTRIB_TEXCOORD0) glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ if(enabled&ATTRIB_TEXCOORD1)
+ {
+ glClientActiveTexture_(GL_TEXTURE1_ARB);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTexture_(GL_TEXTURE0_ARB);
+ }
+ enabled = 0;
+ }
+#endif
+}
+
diff --git a/source/src/water.cpp b/source/src/water.cpp
index 7aaa4e0c..27161521 100644
--- a/source/src/water.cpp
+++ b/source/src/water.cpp
@@ -28,39 +28,68 @@ COMMANDN(watercolour, setwatercolor, ARG_4STR);
// renders water for bounding rect area that contains water... simple but very inefficient
-#define VERTW(vertw, body) \
+#define VERTW(vertw, defbody, body) \
+ static inline void def##vertw() \
+ { \
+ varray::defattrib(varray::ATTRIB_VERTEX, 3, GL_FLOAT); \
+ defbody; \
+ } \
inline void vertw(float v1, float v2, float v3, float t) \
{ \
- float angle = v1*v2*0.1f + t; \
- float h = 0.3f*sinf(angle); \
+ float angle = v1*v2*0.1f/(2*M_PI) + t; \
+ float s = angle - int(angle) - 0.5f; \
+ s *= 8 - fabs(s)*16; \
+ float h = 0.3f*s; \
+ varray::attrib(v1, v2, v3+h); \
body; \
- glVertex3f(v1, v2, v3+h); \
}
-#define VERTWT(vertwt, body) VERTW(vertwt, { float v = cosf(angle); float duv = 0.2f*v; body; })
-VERTW(vertw, {})
-VERTW(vertwc, {
- float v = cosf(angle);
- glColor4ub(hdr.watercolor[0], hdr.watercolor[1], hdr.watercolor[2], (uchar)(hdr.watercolor[3] + (max(v, 0.0f) - 0.5f)*51.0f));
+#define VERTWC(vertwc, defbody, body) \
+ VERTW(vertwc, defbody, { \
+ float v = angle - int(angle+0.25) - 0.25; \
+ v *= 8 - fabs(v)*16; \
+ body; \
+ })
+#define VERTWT(vertwt, defbody, body) \
+ VERTWC(vertwt, defbody, { \
+ float duv = 0.2f*v; \
+ body; \
+ })
+
+VERTW(vertw, {}, {})
+VERTWC(vertwc, {
+ varray::defattrib(varray::ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE);
+}, {
+ varray::attrib(hdr.watercolor[0], hdr.watercolor[1], hdr.watercolor[2], (uchar)(hdr.watercolor[3] + (max(v, 0.0f) - 0.5f)*51.0f));
})
VERTWT(vertwt, {
- glTexCoord3f(v1+duv, v2+duv, v3+h);
+ varray::defattrib(varray::ATTRIB_TEXCOORD0, 3, GL_FLOAT);
+}, {
+ varray::attrib(v1+duv, v2+duv, v3+h);
})
VERTWT(vertwtc, {
- glColor4f(1, 1, 1, 0.15f + max(v, 0.0f)*0.15f);
- glTexCoord3f(v1+duv, v2+duv, v3+h);
+ varray::defattrib(varray::ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE);
+ varray::defattrib(varray::ATTRIB_TEXCOORD0, 3, GL_FLOAT);
+}, {
+ varray::attrib(255, 255, 255, uchar(38 + max(v, 0.0f)*38));
+ varray::attrib(v1+duv, v2+duv, v3+h);
})
VERTWT(vertwmtc, {
- glColor4f(1, 1, 1, 0.15f + max(v, 0.0f)*0.15f);
- glMultiTexCoord3f_(GL_TEXTURE0_ARB, v1-duv, v2+duv, v3+h);
- glMultiTexCoord3f_(GL_TEXTURE1_ARB, v1+duv, v2+duv, v3+h);
+ varray::defattrib(varray::ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE);
+ varray::defattrib(varray::ATTRIB_TEXCOORD0, 3, GL_FLOAT);
+ varray::defattrib(varray::ATTRIB_TEXCOORD1, 3, GL_FLOAT);
+}, {
+ varray::attrib(255, 255, 255, uchar(38 + max(v, 0.0f)*38));
+ varray::attrib(v1-duv, v2+duv, v3+h);
+ varray::attrib(v1+duv, v2+duv, v3+h);
})
extern int nquads;
#define renderwaterstrips(vertw, hf, t) \
+ def##vertw(); \
for(int x = wx1; x=2 && reflecttex)
{
+ varray::enable();
+
if(refracttex)
{
setupmultitexrefract(reflecttex, refracttex);
@@ -158,6 +188,8 @@ int renderwater(float hf, GLuint reflecttex, GLuint refracttex)
}
cleanupmultitex(reflecttex, refracttex);
+ varray::disable();
+
return nquads;
}
@@ -169,6 +201,8 @@ int renderwater(float hf, GLuint reflecttex, GLuint refracttex)
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ varray::enable();
+
if(reflecttex)
{
if(!refracttex)
@@ -196,6 +230,8 @@ int renderwater(float hf, GLuint reflecttex, GLuint refracttex)
if(reflecttex) { renderwaterstrips(vertwtc, hf, t); }
else { renderwaterstrips(vertwc, hf, t); }
+ varray::disable();
+
if(reflecttex)
{
glLoadIdentity();
diff --git a/source/vcpp/cube.vcproj b/source/vcpp/cube.vcproj
index ffacc575..fcfcf4d3 100644
--- a/source/vcpp/cube.vcproj
+++ b/source/vcpp/cube.vcproj
@@ -685,6 +685,26 @@
/>
+
+
+
+
+
+
+
+