But as soon as the setMaterialType is called, the program stops responding. So the material must be false.
Have I forgotten to set something?
Code: Select all
#include <irrlicht.h>
#include <iostream>
#include <vector>
//#include "simplexnoise.h"
using namespace irr;
using namespace video;
using namespace core;
using namespace scene;
using namespace io;
using namespace gui;
IrrlichtDevice* device = 0;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
invWorld.makeInverse();
services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16);
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
core::vector3df pos = device->getSceneManager()->
getActiveCamera()->getAbsolutePosition();
services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3);
// set light color
video::SColorf col(0.0f,1.0f,1.0f,0.0f);
services->setVertexShaderConstant("mLightColor", reinterpret_cast<f32*>(&col), 4);
// set transposed world matrix
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
world = world.getTransposed();
services->setVertexShaderConstant("mTransWorld", world.pointer(), 16);
// set texture, for textures you can use both an int and a float setPixelShaderConstant interfaces (You need it only for an OpenGL driver).
s32 TextureLayerID = 0;
services->setPixelShaderConstant("myTexture", &TextureLayerID, 1);
}
};
class TMesh
{
private:
u16 Width;
u16 Height;
f32 Scale;
std::vector <std::vector<float> > Heights;
public:
SMesh* Mesh;
TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)
{
Mesh = new SMesh();
}
~TMesh()
{
Mesh->drop();
}
void init(int width, int height, f32 scale, IVideoDriver *driver)
{
Scale = scale;
Width = width;
Height = height;
Heights.resize( Width , std::vector<float>( Height , 0 ) );
for (int i = 0; i < Width; i++) {
for (int j = 0; j < Height; j++) {
Heights[i][j] = 0.f;
// octave_noise_2d( 2.f, 20.f, 0.02f, i,j)*4;
}
}
const u32 mp = driver -> getMaximalPrimitiveCount();
const u32 sw = mp / (6 * Height);
u32 i=0;
for(u32 y0 = 0; y0 < Height; y0 += sw)
{
u16 y1 = y0 + sw;
if (y1 >= Height)
y1 = Height - 1;
addstrip(y0, y1, i);
++i;
}
if (i<Mesh->getMeshBufferCount())
{
for (u32 j=i; j<Mesh->getMeshBufferCount(); ++j)
{
Mesh->getMeshBuffer(j)->drop();
}
Mesh->MeshBuffers.erase(i,Mesh->getMeshBufferCount()-i);
}
Mesh->setDirty();
Mesh->recalculateBoundingBox();
}
void addstrip(u16 y0, u16 y1, u32 bufNum)
{
SMeshBuffer *buf = 0;
if (bufNum<Mesh->getMeshBufferCount())
{
buf = (SMeshBuffer*)Mesh->getMeshBuffer(bufNum);
}
else
{
buf = new SMeshBuffer();
Mesh->addMeshBuffer(buf);
buf->drop();
}
buf->Vertices.set_used((1 + y1 - y0) * Width);
u32 i=0;
for (u16 y = y0; y <= y1; ++y)
{
for (u16 x = 0; x < Width; ++x)
{
const f32 z = Heights[y][x];
const f32 xx = (f32)x;
const f32 yy = (f32)y;
S3DVertex& v = buf->Vertices[i++];
v.Pos.set(x, z, y);
v.Color=SColor(255,255,255,255);
v.TCoords.set(xx, yy);
}
}
buf->Indices.set_used(6 * (Width - 1) * (y1 - y0));
i=0;
for(u16 y = y0; y < y1; ++y)
{
for(u16 x = 0; x < Width - 1; ++x)
{
const u16 n = (y-y0) * Width + x;
buf->Indices[i]=n;
buf->Indices[++i]=n + Width;
buf->Indices[++i]=n + Width + 1;
buf->Indices[++i]=n + Width + 1;
buf->Indices[++i]=n + 1;
buf->Indices[++i]=n;
++i;
}
}
buf->recalculateBoundingBox();
}
};
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
int main(int argc, char* argv[])
{
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(video::EDT_OPENGL,
core::dimension2du(1280, 720), 32, false, false, false,
&receiver);
if(device == 0)
return 1;
IVideoDriver *driver = device->getVideoDriver();
ISceneManager *smgr = device->getSceneManager();
device->setWindowCaption(L"Terrain Test");
io::path vsFileName;
io::path psFileName;
psFileName = "../Media/Shaders/opengl.frag";
vsFileName = "../Media/Shaders/opengl.vert";
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 tiledMaterialType = 0;
if (gpu)
{
MyShaderCallBack* mc = new MyShaderCallBack();
const video::E_GPU_SHADING_LANGUAGE shadingLanguage = video::EGSL_DEFAULT;
// create material from high level shaders (hlsl, glsl or cg)
tiledMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_2_0,
psFileName, "pixelMain", video::EPST_PS_2_0,
mc, video::EMT_SOLID, 0, shadingLanguage);
mc->drop();
}
TMesh mesh;
mesh.init(255, 255, 50.f, driver);
IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh);
meshnode->setMaterialType((video::E_MATERIAL_TYPE) tiledMaterialType);
meshnode->setMaterialFlag(video::EMF_LIGHTING,false);
meshnode->setMaterialTexture(0, driver->getTexture("../Media/Textures/Grass.jpg"));
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
if (camera)
{
camera->setPosition(vector3df(-20.f, 150.f, -20.f));
camera->setTarget(vector3df(200.f, -80.f, 150.f));
camera->setFarValue(20000.0f);
}
while(device->run())
{
if(!device->isWindowActive())
{
device->sleep(100);
continue;
}
if(receiver.IsKeyDown(irr::KEY_KEY_W))
{
meshnode->setMaterialFlag(video::EMF_WIREFRAME, !meshnode->getMaterial(0).Wireframe);
}
driver->beginScene(true, true, SColor(0xff000000));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}