#include "opengl.h" #include "material.h" #include #include #include namespace shader { refcounted::~refcounted () { #if 0 if (refcnt) abort (); #endif } const char str_float [] = "float"; const char str_float2 [] = "float2"; const char str_float3 [] = "float3"; const char str_float4 [] = "float4"; const char str_float4x4 [] = "float4x4"; const char str_sampler1d [] = "sampler1d"; const char str_sampler2d [] = "sampler2d"; const char str_sampler3d [] = "sampler3d"; const char str_samplerCUBE [] = "samplerCUBE"; const char str_samplerRECT [] = "samplerRECT"; static CGcontext cg_context = cgCreateContext (); int var_i::next_name = 0; var_i::var_i (CGtype cgtype, const char *typestr) : typestr (typestr) { name = ++next_name; param = cgCreateParameter (cg_context, cgtype); } var_i::~var_i () { cgDestroyParameter (param); } void var_i::build_decl (ostringstream &b) { b << typestr << ' ' << "V" << name; } void uniform_i::build_decl (ostringstream &b) { b << "uniform " << typestr << ' ' << "V" << name; } void stream_i::build_decl (ostringstream &b) { b << typestr << ' ' << "V" << name; b << " : " << binding; } void var_i::build (shader_builder &b) { b << "V" << name; } void uniform_i::build (shader_builder &b) { var_i::build (b); if (find (b.refs.begin (), b.refs.end (), uniform (*this)) == b.refs.end ()) b.refs.push_back (*this); } void stream_i::build (shader_builder &b) { var_i::build (b); if (find (b.streams.begin (), b.streams.end (), var (*this)) == b.streams.end ()) b.streams.push_back (*this); } void temporary_i::build (shader_builder &b) { var_i::build (b); if (find (b.temps.begin (), b.temps.end (), var (*this)) == b.temps.end ()) b.temps.push_back (*this); } void fragment_const_string_i::build (shader_builder &b) { b << str; } struct vin vin; // MUST update is-function below varying_3f vin::position_3f ("POSITION"); varying_4f vin::position_4f ("POSITION"); varying_3f vin::normal_3f ("NORMAL"); varying_4f vin::normal_4f ("NORMAL"); varying_3f vin::color0_3f ("COLOR0"); varying_4f vin::color0_4f ("COLOR0"); varying_3f vin::color1_3f ("COLOR1"); varying_4f vin::color1_4f ("COLOR1"); varying_1f vin::texcoord_1f[8] = { varying_1f ("TEXCOORD0"), varying_1f ("TEXCOORD1"), varying_1f ("TEXCOORD2"), varying_1f ("TEXCOORD3"), varying_1f ("TEXCOORD4"), varying_1f ("TEXCOORD5"), varying_1f ("TEXCOORD6"), varying_1f ("TEXCOORD7"), }; varying_2f vin::texcoord_2f[8] = { varying_2f ("TEXCOORD0"), varying_2f ("TEXCOORD1"), varying_2f ("TEXCOORD2"), varying_2f ("TEXCOORD3"), varying_2f ("TEXCOORD4"), varying_2f ("TEXCOORD5"), varying_2f ("TEXCOORD6"), varying_2f ("TEXCOORD7"), }; varying_3f vin::texcoord_3f[8] = { varying_3f ("TEXCOORD0"), varying_3f ("TEXCOORD1"), varying_3f ("TEXCOORD2"), varying_3f ("TEXCOORD3"), varying_3f ("TEXCOORD4"), varying_3f ("TEXCOORD5"), varying_3f ("TEXCOORD6"), varying_3f ("TEXCOORD7"), }; varying_4f vin::texcoord_4f[8] = { varying_4f ("TEXCOORD0"), varying_4f ("TEXCOORD1"), varying_4f ("TEXCOORD2"), varying_4f ("TEXCOORD3"), varying_4f ("TEXCOORD4"), varying_4f ("TEXCOORD5"), varying_4f ("TEXCOORD6"), varying_4f ("TEXCOORD7"), }; varying_1f vin::psize_1f ("PSIZE"); varying_1f vin::attr6_1f ("ATTR6"); varying_1f vin::attr7_1f ("ATTR7"); varying_2f vin::attr6_2f ("ATTR6"); varying_2f vin::attr7_2f ("ATTR7"); varying_3f vin::attr6_3f ("ATTR6"); varying_3f vin::attr7_3f ("ATTR7"); varying_4f vin::attr6_4f ("ATTR6"); varying_4f vin::attr7_4f ("ATTR7"); bool vin::is (const var &r) { return r == vin::position_3f || r == vin::position_4f || r == vin::normal_3f || r == vin::normal_4f || r == vin::color0_3f || r == vin::color0_4f || r == vin::color1_3f || r == vin::color1_4f || r == vin::texcoord_1f[0] || r == vin::texcoord_1f[1] || r == vin::texcoord_1f[2] || r == vin::texcoord_1f[3] || r == vin::texcoord_1f[4] || r == vin::texcoord_1f[5] || r == vin::texcoord_1f[6] || r == vin::texcoord_1f[7] || r == vin::texcoord_2f[0] || r == vin::texcoord_2f[1] || r == vin::texcoord_2f[2] || r == vin::texcoord_2f[3] || r == vin::texcoord_2f[4] || r == vin::texcoord_2f[5] || r == vin::texcoord_2f[6] || r == vin::texcoord_2f[7] || r == vin::texcoord_3f[0] || r == vin::texcoord_3f[1] || r == vin::texcoord_3f[2] || r == vin::texcoord_3f[3] || r == vin::texcoord_3f[4] || r == vin::texcoord_3f[5] || r == vin::texcoord_3f[6] || r == vin::texcoord_3f[7] || r == vin::texcoord_4f[0] || r == vin::texcoord_4f[1] || r == vin::texcoord_4f[2] || r == vin::texcoord_4f[3] || r == vin::texcoord_4f[4] || r == vin::texcoord_4f[5] || r == vin::texcoord_4f[6] || r == vin::texcoord_4f[7] || r == vin::psize_1f || r == vin::attr6_1f || r == vin::attr7_1f || r == vin::attr6_2f || r == vin::attr7_2f || r == vin::attr6_3f || r == vin::attr7_3f || r == vin::attr6_4f || r == vin::attr7_4f; } struct fin fin; struct fin &vout = fin; // MUST update is-function below varying_4f fin::position_4f ("HPOS"); varying_4f fin::color0_4f ("COLOR0"); varying_4f fin::color1_4f ("COLOR1"); varying_4f fin::texcoord_4f[8] = { varying_4f ("TEXCOORD0"), varying_4f ("TEXCOORD1"), varying_4f ("TEXCOORD2"), varying_4f ("TEXCOORD3"), varying_4f ("TEXCOORD4"), varying_4f ("TEXCOORD5"), varying_4f ("TEXCOORD6"), varying_4f ("TEXCOORD7"), }; bool fin::is (const var &r) { return r == fin::position_4f || r == fin::color0_4f || r == fin::color1_4f || r == fin::texcoord_4f[0] || r == fin::texcoord_4f[1] || r == fin::texcoord_4f[2] || r == fin::texcoord_4f[3] || r == fin::texcoord_4f[4] || r == fin::texcoord_4f[5] || r == fin::texcoord_4f[6] || r == fin::texcoord_4f[7]; } struct fout fout; // MUST update is-function below varying_4f fout::color0_4f ("COLOR0"); varying_3f fout::color0_3f ("COLOR0"); varying_4f fout::color1_4f ("COLOR1"); varying_3f fout::color1_3f ("COLOR1"); varying_1f fout::depth_1f ("DEPTH"); bool fout::is (const var &r) { return r == fout::color0_4f || r == fout::color0_3f || r == fout::color1_4f || r == fout::color1_3f || r == fout::depth_1f; } uniform_matrix_f mvp, mv, proj; void fragment_vector_i::build (shader_builder &b) { for (vector::iterator i = begin (); i != end (); i++) (*i)->build (b); } void shader_program::print () { shader_builder b; build (b); ostringstream os; os << "void main (\n"; for (vector::iterator i = b.streams.begin (); i != b.streams.end (); i++) { os << " "; if (is_vertex) { if (vin.is (*i)) os << "in "; if (vout.is (*i)) os << "out "; } else { if (fin.is (*i)) os << "in "; if (fout.is (*i)) os << "out "; } (*i)->build_decl (os); os << ",\n"; } for (vector::iterator i = b.refs.begin (); i != b.refs.end (); i++) { os << " "; (*i)->build_decl (os); os << ",\n"; } os << " uniform float unused_cg_broken_syntax\n"; os << ")\n{\n"; for (vector::iterator i = b.temps.begin (); i != b.temps.end (); i++) { (*i)->build_decl (os); os << ";\n"; } os << "\n"; os << b.source.str (); os << "\n}\n"; printf ("%s\n", os.str ().c_str ()); } void debdebdebdebug ()//D { vertex_program p; temp_4f t1, t2; sampler2d s2d (1); p << t2 << " = tex2D (" << s2d << ", " << vin.position_4f << ".xy);\n"; p << t1 << " = mul (" << vin.position_4f << "," << mvp << ");\n"; p << vout.position_4f << " = " << t1 << ";\n"; p.print (); //exit (0); } } material::~material () { } void simple_material::begin () { glMaterialfv (GL_FRONT, GL_DIFFUSE, (GLfloat *) & diffuse); glMaterialfv (GL_FRONT, GL_SPECULAR, (GLfloat *) & specular); glMaterialfv (GL_FRONT, GL_EMISSION, (GLfloat *) & emission); glMaterialf (GL_FRONT, GL_SHININESS, shininess); } void simple_material::end () { } void osama_material::begin () { cgGLEnableProfile (vsh_profile); cgGLEnableProfile (fsh_profile); cgGLEnableTextureParameter (g_Texture); } void osama_material::end () { cgGLDisableTextureParameter (g_Texture); // cgGLUnbindProgram (vsh_profile); // cgGLUnbindProgram (fsh_profile); cgGLDisableProfile (vsh_profile); cgGLDisableProfile (fsh_profile); } GLuint texture::load_texture (SDL_Surface * surface, GLfloat * tex2oord) { GLuint textur; int w, h; SDL_Surface *image; SDL_Rect area; Uint32 saved_flags; Uint8 saved_alpha; /* Use the surface width and height expanded to powers of 2 */ //w = power_of_two (surface->w); //h = power_of_two (surface->h); w = power_of_two (surface->w); h = power_of_two (surface->h); tex2oord[0] = 0.0f; /* Min X */ tex2oord[1] = 0.0f; /* Min Y */ tex2oord[2] = (GLfloat) surface->w / w; /* Max X */ tex2oord[3] = (GLfloat) surface->h / h; /* Max Y */ image = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); if (image == NULL) return 0; /* Save the alpha blending attributes */ saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); saved_alpha = surface->format->alpha; if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) SDL_SetAlpha (surface, 0, 0); /* Copy the surface into the GL texture image */ area.x = 0; area.y = 0; area.w = surface->w; area.h = surface->h; SDL_BlitSurface (surface, &area, image, &area); /* Restore the alpha blending attributes */ if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) SDL_SetAlpha (surface, saved_flags, saved_alpha); /* Create an OpenGL texture for the image */ glGenTextures (1, &textur); glBindTexture (GL_TEXTURE_2D, textur); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); // GENERATE_MIPMAP_SGIS glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); SDL_FreeSurface (image); /* No longer needed */ return textur; } CGcontext cgc; void init_shaders () { cgc = cgCreateContext (); }