181 changes: 110 additions & 71 deletions src/mapblock_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "shader.h"
#include "settings.h"
#include "util/directiontables.h"
#include <IMeshManipulator.h>

static void applyFacesShading(video::SColor& color, float factor)
{
Expand Down Expand Up @@ -1028,6 +1029,8 @@ static void updateAllFastFaceRows(MeshMakeData *data,
MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_mesh(new scene::SMesh()),
m_gamedef(data->m_gamedef),
m_tsrc(m_gamedef->getTextureSource()),
m_shdrsrc(m_gamedef->getShaderSource()),
m_animation_force_timer(0), // force initial animation
m_last_crack(-1),
m_crack_materials(),
Expand Down Expand Up @@ -1063,7 +1066,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
Convert FastFaces to MeshCollector
*/

MeshCollector collector;
MeshCollector collector(m_enable_shaders);

{
// avg 0ms (100ms spikes when loading textures the first time)
Expand Down Expand Up @@ -1110,8 +1113,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
/*
Convert MeshCollector to SMesh
*/
ITextureSource *tsrc = m_gamedef->tsrc();
IShaderSource *shdrsrc = m_gamedef->getShaderSource();

for(u32 i = 0; i < collector.prebuffers.size(); i++)
{
Expand All @@ -1123,13 +1124,13 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
{
// Find the texture name plus ^[crack:N:
std::ostringstream os(std::ios::binary);
os<<tsrc->getTextureName(p.tile.texture_id)<<"^[crack";
os<<m_tsrc->getTextureName(p.tile.texture_id)<<"^[crack";
if(p.tile.material_flags & MATERIAL_FLAG_CRACK_OVERLAY)
os<<"o"; // use ^[cracko
os<<":"<<(u32)p.tile.animation_frame_count<<":";
m_crack_materials.insert(std::make_pair(i, os.str()));
// Replace tile texture with the cracked one
p.tile.texture = tsrc->getTextureForMesh(
p.tile.texture = m_tsrc->getTextureForMesh(
os.str()+"0",
&p.tile.texture_id);
}
Expand All @@ -1155,23 +1156,28 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):

if(m_enable_highlighting && p.tile.material_flags & MATERIAL_FLAG_HIGHLIGHTED)
m_highlighted_materials.push_back(i);

for(u32 j = 0; j < p.vertices.size(); j++)


u32 pitch = p.getVertexPitch();
u32 vertex_count = p.getVertexCount();
u8 *vertices = p.getVertices();
for(u32 j = 0; j < vertex_count; j++)
{
video::S3DVertex *vertex = ((video::S3DVertex *)(vertices + j * pitch));
// Note applyFacesShading second parameter is precalculated sqrt
// value for speed improvement
// Skip it for lightsources and top faces.
video::SColor &vc = p.vertices[j].Color;
video::SColor &vc = vertex->Color;
if (!vc.getBlue()) {
if (p.vertices[j].Normal.Y < -0.5) {
if (vertex->Normal.Y < -0.5) {
applyFacesShading (vc, 0.447213);
} else if (p.vertices[j].Normal.X > 0.5) {
} else if (vertex->Normal.X > 0.5) {
applyFacesShading (vc, 0.670820);
} else if (p.vertices[j].Normal.X < -0.5) {
} else if (vertex->Normal.X < -0.5) {
applyFacesShading (vc, 0.670820);
} else if (p.vertices[j].Normal.Z > 0.5) {
} else if (vertex->Normal.Z > 0.5) {
applyFacesShading (vc, 0.836660);
} else if (p.vertices[j].Normal.Z < -0.5) {
} else if (vertex->Normal.Z < -0.5) {
applyFacesShading (vc, 0.836660);
}
}
Expand Down Expand Up @@ -1199,31 +1205,41 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
} else {
if (m_enable_shaders) {
material.MaterialType = shdrsrc->getShaderInfo(p.tile.shader_id).material;
material.MaterialType = m_shdrsrc->getShaderInfo(p.tile.shader_id).material;
p.tile.applyMaterialOptionsWithShaders(material);
if (p.tile.normal_texture) {
material.setTexture(1, p.tile.normal_texture);
material.setTexture(2, tsrc->getTextureForMesh("enable_img.png"));
material.setTexture(2, m_tsrc->getTextureForMesh("enable_img.png"));
} else {
material.setTexture(2, tsrc->getTextureForMesh("disable_img.png"));
material.setTexture(2, m_tsrc->getTextureForMesh("disable_img.png"));
}
} else {
p.tile.applyMaterialOptions(material);
}
}

// Create meshbuffer
// This is a "Standard MeshBuffer",
// it's a typedeffed CMeshBuffer<video::S3DVertex>
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// Set material
buf->Material = material;
// Add to mesh
m_mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(&p.vertices[0], p.vertices.size(),
if (m_enable_shaders) {
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
// Set material
buf->Material = material;
// Add to mesh
m_mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(&p.tangent_vertices[0], p.tangent_vertices.size(),
&p.indices[0], p.indices.size());
} else {
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// Set material
buf->Material = material;
// Add to mesh
m_mesh->addMeshBuffer(buf);
// Mesh grabbed it
buf->drop();
buf->append(&p.vertices[0], p.vertices.size(),
&p.indices[0], p.indices.size());
}
}

m_camera_offset = camera_offset;
Expand All @@ -1234,6 +1250,11 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):

translateMesh(m_mesh, intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));

if (m_enable_shaders) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to always do this if shaders are enabled? I was under the impression that tangents only needed to be calculated when parallax occlusion is enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong impression, see comment above.

scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator();
meshmanip->recalculateTangents(m_mesh, true, false, false);
}

if(m_mesh)
{
#if 0
Expand Down Expand Up @@ -1272,7 +1293,6 @@ MapBlockMesh::~MapBlockMesh()

bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio)
{

if(!m_has_animation)
{
m_animation_force_timer = 100000;
Expand All @@ -1292,12 +1312,11 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
std::string basename = i->second;

// Create new texture name from original
ITextureSource *tsrc = m_gamedef->getTextureSource();
std::ostringstream os;
os<<basename<<crack;
u32 new_texture_id = 0;
video::ITexture *new_texture =
tsrc->getTextureForMesh(os.str(), &new_texture_id);
m_tsrc->getTextureForMesh(os.str(), &new_texture_id);
buf->getMaterial().setTexture(0, new_texture);

// If the current material is also animated,
Expand Down Expand Up @@ -1333,16 +1352,15 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
m_animation_frames[i->first] = frame;

scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
ITextureSource *tsrc = m_gamedef->getTextureSource();

FrameSpec animation_frame = tile.frames[frame];
buf->getMaterial().setTexture(0, animation_frame.texture);
if (m_enable_shaders) {
if (animation_frame.normal_texture) {
buf->getMaterial().setTexture(1, animation_frame.normal_texture);
buf->getMaterial().setTexture(2, tsrc->getTextureForMesh("enable_img.png"));
buf->getMaterial().setTexture(2, m_tsrc->getTextureForMesh("enable_img.png"));
} else {
buf->getMaterial().setTexture(2, tsrc->getTextureForMesh("disable_img.png"));
buf->getMaterial().setTexture(2, m_tsrc->getTextureForMesh("disable_img.png"));
}
}
}
Expand All @@ -1355,15 +1373,16 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
i != m_daynight_diffs.end(); i++)
{
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u8 *vertices = (u8 *)buf->getVertices();
for(std::map<u32, std::pair<u8, u8 > >::iterator
j = i->second.begin();
j != i->second.end(); j++)
{
u32 vertexIndex = j->first;
u8 day = j->second.first;
u8 night = j->second.second;
finalColorBlend(vertices[vertexIndex].Color,
finalColorBlend(((video::S3DVertex *)(vertices + vertexIndex * stride))->Color,
day, night, daynight_ratio);
}
}
Expand All @@ -1388,9 +1407,10 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
i != m_highlighted_materials.end(); i++)
{
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(*i);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u8 *vertices = (u8 *)buf->getVertices();
for (u32 j = 0; j < buf->getVertexCount() ;j++)
vertices[j].Color = hc;
((video::S3DVertex *)(vertices + j * stride))->Color = hc;
}
}

Expand All @@ -1409,47 +1429,62 @@ void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
MeshCollector
*/

MeshCollector::MeshCollector (bool enable_shaders):
m_enable_shaders(enable_shaders)
{
}
MeshCollector::~MeshCollector ()
{
}

void MeshCollector::append(const TileSpec &tile,
const video::S3DVertex *vertices, u32 numVertices,
const u16 *indices, u32 numIndices)
{
if(numIndices > 65535)
{
if (numIndices > 65535) {
dstream<<"FIXME: MeshCollector::append() called with numIndices="<<numIndices<<" (limit 65535)"<<std::endl;
return;
}

PreMeshBuffer *p = NULL;
for(u32 i=0; i<prebuffers.size(); i++)
{
for (u32 i = 0; i < prebuffers.size(); i++) {
PreMeshBuffer &pp = prebuffers[i];
if(pp.tile != tile)
if (pp.tile != tile)
continue;
if(pp.indices.size() + numIndices > 65535)
if (pp.indices.size() + numIndices > 65535)
continue;

p = &pp;
break;
}

if(p == NULL)
{
PreMeshBuffer pp;
if (p == NULL) {
PreMeshBuffer pp(m_enable_shaders);
pp.tile = tile;
prebuffers.push_back(pp);
p = &prebuffers[prebuffers.size()-1];
p = &prebuffers[prebuffers.size() - 1];
}

u32 vertex_count = p->vertices.size();
for(u32 i=0; i<numIndices; i++)
{
u32 vertex_count;
if (m_enable_shaders) {
vertex_count = p->tangent_vertices.size();
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal,
vertices[i].Color, vertices[i].TCoords);
p->tangent_vertices.push_back(vert);
}
} else {
vertex_count = p->vertices.size();
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal,
vertices[i].Color, vertices[i].TCoords);
p->vertices.push_back(vert);
}
}
for (u32 i = 0; i < numIndices; i++) {
u32 j = indices[i] + vertex_count;
p->indices.push_back(j);
}
for(u32 i=0; i<numVertices; i++)
{
p->vertices.push_back(vertices[i]);
}
}

/*
Expand All @@ -1461,15 +1496,13 @@ void MeshCollector::append(const TileSpec &tile,
const u16 *indices, u32 numIndices,
v3f pos, video::SColor c)
{
if(numIndices > 65535)
{
if (numIndices > 65535) {
dstream<<"FIXME: MeshCollector::append() called with numIndices="<<numIndices<<" (limit 65535)"<<std::endl;
return;
}

PreMeshBuffer *p = NULL;
for(u32 i=0; i<prebuffers.size(); i++)
{
for (u32 i = 0; i < prebuffers.size(); i++) {
PreMeshBuffer &pp = prebuffers[i];
if(pp.tile != tile)
continue;
Expand All @@ -1480,25 +1513,31 @@ void MeshCollector::append(const TileSpec &tile,
break;
}

if(p == NULL)
{
PreMeshBuffer pp;
if (p == NULL) {
PreMeshBuffer pp(m_enable_shaders);
pp.tile = tile;
prebuffers.push_back(pp);
p = &prebuffers[prebuffers.size()-1];
p = &prebuffers[prebuffers.size() - 1];
}

u32 vertex_count = p->vertices.size();
for(u32 i=0; i<numIndices; i++)
{
u32 vertex_count;
if (m_enable_shaders) {
vertex_count = p->tangent_vertices.size();
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertexTangents vert(vertices[i].Pos + pos, vertices[i].Normal,
c, vertices[i].TCoords);
p->tangent_vertices.push_back(vert);
}
} else {
vertex_count = p->vertices.size();
for (u32 i = 0; i < numVertices; i++) {
video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal,
c, vertices[i].TCoords);
p->vertices.push_back(vert);
}
}
for (u32 i = 0; i < numIndices; i++) {
u32 j = indices[i] + vertex_count;
p->indices.push_back(j);
}
for(u32 i=0; i<numVertices; i++)
{
video::S3DVertex vert = vertices[i];
vert.Pos += pos;
vert.Color = c;
p->vertices.push_back(vert);
}
}
59 changes: 57 additions & 2 deletions src/mapblock_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <map>

class IGameDef;
class IShaderSource;

/*
Mesh making stuff
Expand Down Expand Up @@ -123,6 +124,8 @@ class MapBlockMesh
private:
scene::SMesh *m_mesh;
IGameDef *m_gamedef;
ITextureSource *m_tsrc;
IShaderSource *m_shdrsrc;

bool m_enable_shaders;
bool m_enable_highlighting;
Expand Down Expand Up @@ -161,17 +164,69 @@ class MapBlockMesh
/*
This is used because CMeshBuffer::append() is very slow
*/
struct PreMeshBuffer
class PreMeshBuffer
{
private:
bool m_enable_shaders;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should be renamed to something else that's more accurate, such as "m_has_tangents"

u32 m_vertex_pitch;
public:
TileSpec tile;
std::vector<u16> indices;
std::vector<video::S3DVertex> vertices;
std::vector<video::S3DVertexTangents> tangent_vertices;

PreMeshBuffer(bool enable_shaders):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're missing a space between the end of the constructor's prototype and the :

m_enable_shaders(enable_shaders)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initializer list is supposed to be indented another level.

{
if (m_enable_shaders)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be a good idea to preallocate some memory here, since we know there are going to be at least a couple hundred vertices. vertices.reserve(512); or something perhaps

m_vertex_pitch = getVertexPitchFromType(video::EVT_TANGENTS);
else
m_vertex_pitch = getVertexPitchFromType(video::EVT_STANDARD);
}

~PreMeshBuffer()
{
}

u32 getVertexPitch ()
{
return m_vertex_pitch;
}

u32 getVertexCount ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra space between getVertexCount and ().
It's supposed to be "u32 getVertexCount()".

{
if (m_enable_shaders)
return tangent_vertices.size();
else
return vertices.size();
}

u8 * getVertices()
{
if (m_enable_shaders)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make this code more compact by rewriting it as: return m_enable_shaders ? &tangent_vertices[0] : &vertices[0];

return (u8 *)&tangent_vertices[0];
else
return (u8 *)&vertices[0];
}

u8 * getVertex(u32 index)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make these return a void *. sizeof(u8 *) != sizeof(S3DVertex *) on some systems, I hope you realize. void * is guaranteed to fit any pointer type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, there's an extra space between the * and the function name. It's supposed to be:
"void *getVertex(u32 index)"

{
if (m_enable_shaders)
return (u8 *)&tangent_vertices[index];
else
return (u8 *)&vertices[index];
}
};

struct MeshCollector
class MeshCollector
{
private:
bool m_enable_shaders;
public:
std::vector<PreMeshBuffer> prebuffers;

MeshCollector(bool enable_shaders);
~MeshCollector();
void append(const TileSpec &material,
const video::S3DVertex *vertices, u32 numVertices,
const u16 *indices, u32 numIndices);
Expand Down
61 changes: 29 additions & 32 deletions src/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,26 +94,25 @@ scene::IAnimatedMesh* createCubeMesh(v3f scale)

void scaleMesh(scene::IMesh *mesh, v3f scale)
{
if(mesh == NULL)
if (mesh == NULL)
return;

core::aabbox3d<f32> bbox;
bbox.reset(0,0,0);
bbox.reset(0, 0, 0);

u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
for (u16 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Pos *= scale;
}
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *)buf->getVertices();
for (u16 i = 0; i < vertex_count; i++)
((video::S3DVertex *)(vertices + i * stride))->Pos *= scale;

buf->recalculateBoundingBox();

// calculate total bounding box
if(j == 0)
if (j == 0)
bbox = buf->getBoundingBox();
else
bbox.addInternalBox(buf->getBoundingBox());
Expand All @@ -123,48 +122,46 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)

void translateMesh(scene::IMesh *mesh, v3f vec)
{
if(mesh == NULL)
if (mesh == NULL)
return;

core::aabbox3d<f32> bbox;
bbox.reset(0,0,0);
bbox.reset(0, 0, 0);

u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
for (u16 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Pos += vec;
}
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *)buf->getVertices();
for (u16 i = 0; i < vertex_count; i++)
((video::S3DVertex *)(vertices + i * stride))->Pos += vec;

buf->recalculateBoundingBox();

// calculate total bounding box
if(j == 0)
if (j == 0)
bbox = buf->getBoundingBox();
else
bbox.addInternalBox(buf->getBoundingBox());
}
mesh->setBoundingBox(bbox);
}


void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
{
if(mesh == NULL)
if (mesh == NULL)
return;

u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
for (u16 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Color = color;
}
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *)buf->getVertices();
for (u16 i = 0; i < vertex_count; i++)
((video::S3DVertex *)(vertices + i * stride))->Color = color;
}
}

Expand Down
17 changes: 12 additions & 5 deletions src/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
shaders_header += "\n";

if (g_settings->getBool("generate_normalmaps")){
shaders_header += "#define GENERATE_NORMALMAPS\n";
shaders_header += "#define GENERATE_NORMALMAPS 1\n";
shaders_header += "#define NORMALMAPS_STRENGTH ";
shaders_header += ftos(g_settings->getFloat("normalmaps_strength"));
shaders_header += "\n";
Expand All @@ -704,18 +704,26 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
shaders_header += "#define SAMPLE_STEP ";
shaders_header += ftos(sample_step);
shaders_header += "\n";
}
} else {
shaders_header += "#define GENERATE_NORMALMAPS 0\n";
}

if (g_settings->getBool("enable_bumpmapping"))
shaders_header += "#define ENABLE_BUMPMAPPING\n";

if (g_settings->getBool("enable_parallax_occlusion")){
float scale = g_settings->getFloat("parallax_occlusion_scale");
float bias = g_settings->getFloat("parallax_occlusion_bias");
int iterations = g_settings->getFloat("parallax_occlusion_iterations");
shaders_header += "#define ENABLE_PARALLAX_OCCLUSION\n";
shaders_header += "#define PARALLAX_OCCLUSION_SCALE ";
shaders_header += ftos(g_settings->getFloat("parallax_occlusion_scale"));
shaders_header += ftos(scale);
shaders_header += "\n";
shaders_header += "#define PARALLAX_OCCLUSION_BIAS ";
shaders_header += ftos(g_settings->getFloat("parallax_occlusion_bias"));
shaders_header += ftos(bias);
shaders_header += "\n";
shaders_header += "#define PARALLAX_OCCLUSION_ITERATIONS ";
shaders_header += itos(iterations);
shaders_header += "\n";
}

Expand Down Expand Up @@ -755,7 +763,6 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
vertex_program = shaders_header + vertex_program;
if(geometry_program != "")
geometry_program = shaders_header + geometry_program;

// Call addHighLevelShaderMaterial() or addShaderMaterial()
const c8* vertex_program_ptr = 0;
const c8* pixel_program_ptr = 0;
Expand Down