#ifndef MATERIAL_H #define MATERIAL_H #include #include #include using namespace std; #include "opengl.h" #include "util.h" #include "shader.h" inline void std_vsh () { using namespace shader::compile; vout.position = ftransform (); } inline void std_vsh (const shader::gluvar &vertex) { using namespace shader::compile; vout.position = model_view_projection_matrix * vertex; } struct material { // the vertex shader fragment. it should check ctx.pass_data->light and // only generate varying data when light is non-null. it should also use // std_vsh () whenever possible. virtual void vsh (view &ctx) = 0; // the fragment shader fragment :). it should check ctx.pass_data->light // and, if null, best do nothing. if non-null, it should call // light->value to get the per-pixel light colour and apply it to the // surface as neccessary. virtual void fsh (view &ctx) = 0; virtual void enable (view &ctx); virtual void disable (view &ctx); virtual ~material (); }; struct texture_execption { texture_execption (string s) : msg(s) { } string msg; }; struct texture { SDL_Surface *image; GLuint name; GLfloat texcoord[4]; GLuint load_texture (SDL_Surface *surface, GLfloat *texcoord, int flags); enum { DISABLE_MIPMAP = 1, CLAMP = 2, }; texture (const char *f, int flags = 0) { image = IMG_Load (f); if (!image) throw (texture_execption ("Couldn't load " + (string) f + ": " + (string) IMG_GetError ())); name = load_texture (image, (GLfloat*)&texcoord, flags); if (name == 0) throw (texture_execption ("Couldn't make GL Texture, failed to create new RGB SWSurface")); } }; ///////////////////////////////////////////////////////////////////////////// struct test_material : material { texture tex, norm; shader::sampler_2d texvar, normvar; void vsh (view &ctx); void fsh (view &ctx); void enable (view &ctx); void disable (view &ctx); test_material (); }; struct skybox_material : material { shader::sampler_2d tex; void vsh (view &ctx); void fsh (view &ctx); void enable (view &ctx); void disable (view &ctx); skybox_material (); }; struct mat_timed : material { shader::uniform_1f time; void enable (view &ctx); void disable (view &ctx); void vsh (view &ctx); void fsh (view &ctx); protected: shader::varying_3f f_normal; shader::uniform_3f sh_colour; }; struct mat_gouraud_shaded : material { // texture tex, norm; // shader::sampler_2d texvar, normvar; colour c; void vsh (view &ctx); void fsh (view &ctx); void enable (view &ctx); void disable (view &ctx); mat_gouraud_shaded (const colour &c) : c(c) { } protected: shader::uniform_3f sh_colour; shader::varying_3f f_normal; }; struct mat_debug : material { void vsh (view &ctx); void fsh (view &ctx); void enable (view &ctx); void disable (view &ctx); mat_debug () { } }; extern test_material *testmat; extern mat_gouraud_shaded *testmat2; extern mat_timed *testmat3; extern mat_debug *debugmat; #endif