Here's a picture of the problem,
Basically I managed to get textures onto quads for billboards and then I managed to get the shader to rotate them to face the camera but now the blending is not quite normal as it should be. I'm just not sure how to go about making this work. I wondered how Irrlicht implemented their particle system, I noticed it doesn't use a shader so I assume it's all cpu but I figure a shader would be effective too. For the shaders, I've tried video::EMT_TRANSPARENT_ADD_COLOR and video::EMT_SOLID. Anyways here's the complete code
main.cpp
Code: Select all
#include "irrlicht.h"
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace irr;
class EventReceiver : public irr::IEventReceiver
{
public:
virtual bool OnEvent(const irr::SEvent& event);
virtual bool IsKeyDown( irr::EKEY_CODE keyCode) const;
EventReceiver();
private:
bool KeyIsDown[ irr::KEY_KEY_CODES_COUNT];
};
bool EventReceiver::OnEvent(const irr::SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
bool EventReceiver::IsKeyDown( irr::EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
EventReceiver::EventReceiver()
{
for ( irr::u32 i = 0; i < irr::KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
scene::SMeshBuffer Buffer;
video::IVideoDriver* driver;
video::E_DRIVER_TYPE driverType;
s32 shader_1_MaterialType1 = 0;
s32 shader_1_MaterialType2 = 0;
video::IGPUProgrammingServices* gpu;
class BILLBOARD : public video::IShaderConstantSetCallBack
{
public:
io::path vsFileName;
io::path psFileName;
BILLBOARD()
{
vsFileName = "billboard.vert";
psFileName = "billboard.frag";
}
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
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::matrix4 viewMatrix = driver->getTransform(video::ETS_VIEW);
services->setVertexShaderConstant("viewMatrix", viewMatrix.pointer(), 16);
core::matrix4 projectionMatrix = driver->getTransform(video::ETS_PROJECTION);
services->setVertexShaderConstant("projectionMatrix", projectionMatrix.pointer(), 16);
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
world = world.getTransposed();
services->setVertexShaderConstant("mTransWorld", world.pointer(), 16);
core::matrix4 modelviewmatrix;
modelviewmatrix = driver->getTransform(video::ETS_VIEW);
modelviewmatrix *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("modelviewmatrix", world.pointer(), 16);
s32 TextureLayerID = 0;
services->setPixelShaderConstant("inputTexture", &TextureLayerID, 1);
}
};
unsigned int INDEX = 0;
unsigned int vertexCount;
unsigned int primCount = 0;
video::SMaterial material;
void init_indices()
{
Buffer.Indices.push_back( 0+INDEX);
Buffer.Indices.push_back( 1+INDEX);
Buffer.Indices.push_back( 2+INDEX);
Buffer.Indices.push_back( 2+INDEX);
Buffer.Indices.push_back( 3+INDEX);
Buffer.Indices.push_back( 0+INDEX);
}
void init_points( float x, float y, float z)
{
init_indices();
float a = 10.0;
int r, g, b;
r = g = b = 255;
Buffer.Vertices.push_back(video::S3DVertex( x,y,z, 1,1,0,video::SColor(0,r,g,b), 0, 1));
Buffer.Vertices.push_back(video::S3DVertex( x, a + y, z, 1,0,0,video::SColor(0,r,g,b), 1, 1));
Buffer.Vertices.push_back(video::S3DVertex( a+x, a+y, z, 0,1,1, video::SColor(0,r,g,b), 1, 0));
Buffer.Vertices.push_back(video::S3DVertex( a+x, y, z, 0,0,1, video::SColor(0,r,g,b) , 0, 0));
INDEX+=4;
primCount+=2;
}
void render()
{
material.Wireframe = false;
material.Lighting = false;//true
material.setTexture( 0, driver->getTexture("../../../textures/particlewhite.bmp") );//Can also be found in the media folder with irrlicht
material.MaterialType = irr::video::EMT_TRANSPARENT_ADD_COLOR;
material.setFlag( irr::video::EMF_ZWRITE_ENABLE, false);
material.MaterialType = (irr::video::E_MATERIAL_TYPE)shader_1_MaterialType1;
driver->setMaterial( material);
driver->drawVertexPrimitiveList(Buffer.getVertices(), INDEX, Buffer.getIndices(), primCount, irr::video::EVT_STANDARD, irr::scene::EPT_TRIANGLES, irr::video::EIT_16BIT);
}
int main()
{
EventReceiver receiver;
IrrlichtDevice *device = createDevice( irr::video::EDT_OPENGL,
irr::core::dimension2d< irr::u32>( 1024, 768),
16,
false,
false,
false,
&receiver);
if (device == 0)
return 1;
device->setWindowCaption(L"IRRLICHT");
driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
driver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, true);
gpu = driver->getGPUProgrammingServices();
if (gpu)
{
BILLBOARD* billboard = new BILLBOARD();
const video::E_GPU_SHADING_LANGUAGE shadingLanguage =
video::EGSL_DEFAULT;
shader_1_MaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
billboard->vsFileName, "vertexMain", video::EVST_VS_1_1,
billboard->psFileName, "pixelMain", video::EPST_PS_1_1,
billboard, video::EMT_SOLID, 0, shadingLanguage);
shader_1_MaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
billboard->vsFileName, "vertexMain", video::EVST_VS_1_1,
billboard->psFileName, "pixelMain", video::EPST_PS_1_1,
billboard, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage);
billboard->drop();
}
init_points(-5.0,-5.0, -2.0);
init_points( 0.0, 0.0, -1.0);
init_points( 5.0, 0.0, 0.0);
irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
cam->setTarget( core::vector3df(0,0,0));
cam->setPosition( core::vector3df(-15,0,-15));
device->getCursorControl()->setVisible( true);
u32 frames=0;
while(device->run())
{
driver->beginScene( true, true, video::SColor( 0, 0, 0, 0));
render();
smgr->drawAll();
driver->endScene();
if (++frames==100)
{
core::stringw str = L"Irrlicht Engine [";
str += driver->getName();
str += L"] FPS: ";
str += (s32)driver->getFPS();
device->setWindowCaption(str.c_str());
frames=0;
}
}
device->drop();
return 0;
}
billboard.vert
Code: Select all
uniform mat4 mWorldViewProj;// ETS_PROJECTION*ETS_VIEW*ETS_WORLD
uniform mat4 mTransWorld;// ETS_WORLD.getTransposed()
uniform mat4 viewMatrix;
uniform mat4 modelviewmatrix;
uniform mat4 projectionMatrix;
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ProjectionMatrix * (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(gl_Vertex.x, gl_Vertex.y, 0.0, 0.0));
}
Code: Select all
uniform sampler2D inputTexture;
void main()
{
vec4 tex_color = texture2D( inputTexture, gl_TexCoord [ 0].xy);
gl_FragColor = tex_color;
}