nuclear@5: #include nuclear@3: #include nuclear@5: #include nuclear@3: #include "material.h" nuclear@3: nuclear@5: static const char *find_path(const char *fname); nuclear@5: nuclear@3: Material::Material() nuclear@4: : diffuse(1, 1, 1), specular(0, 0, 0) nuclear@3: { nuclear@3: shininess = 1.0; nuclear@3: alpha = 1.0; nuclear@5: nuclear@5: for(int i=0; i 128 ? 128 : shininess); nuclear@5: nuclear@5: if(sdr) { nuclear@5: glUseProgram(sdr); nuclear@5: } nuclear@5: nuclear@5: if(tex[TEX_DIFFUSE]) { nuclear@5: glActiveTexture(GL_TEXTURE0); nuclear@5: nuclear@5: glMatrixMode(GL_TEXTURE); nuclear@5: glLoadIdentity(); nuclear@5: glTranslatef(tex_offset[TEX_DIFFUSE].x, tex_offset[TEX_DIFFUSE].y, 0); nuclear@5: glScalef(tex_scale[TEX_DIFFUSE].x, tex_scale[TEX_DIFFUSE].y, 1); nuclear@5: nuclear@5: glBindTexture(GL_TEXTURE_2D, tex[TEX_DIFFUSE]); nuclear@5: glEnable(GL_TEXTURE_2D); nuclear@5: nuclear@5: int loc = glGetUniformLocation(sdr, "tex_diffuse"); nuclear@5: if(loc != -1) { nuclear@5: glUniform1i(loc, 0); nuclear@5: } nuclear@5: } nuclear@5: if(tex[TEX_ENVMAP]) { nuclear@5: glActiveTexture(GL_TEXTURE1); nuclear@5: nuclear@5: glMatrixMode(GL_TEXTURE); nuclear@5: glLoadIdentity(); nuclear@5: glTranslatef(tex_offset[TEX_ENVMAP].x, tex_offset[TEX_ENVMAP].y, 0); nuclear@5: glScalef(tex_scale[TEX_ENVMAP].x, tex_scale[TEX_ENVMAP].y, 1); nuclear@5: nuclear@5: glBindTexture(GL_TEXTURE_2D, tex[TEX_ENVMAP]); nuclear@5: glEnable(GL_TEXTURE_2D); nuclear@5: nuclear@5: glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); nuclear@5: glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); nuclear@5: glEnable(GL_TEXTURE_GEN_S); nuclear@5: glEnable(GL_TEXTURE_GEN_T); nuclear@5: nuclear@5: int loc = glGetUniformLocation(sdr, "tex_envmap"); nuclear@5: if(loc != -1) { nuclear@5: glUniform1i(loc, 1); nuclear@5: } nuclear@5: } nuclear@5: nuclear@5: glActiveTexture(GL_TEXTURE0); nuclear@5: glMatrixMode(GL_MODELVIEW); nuclear@3: } nuclear@5: nuclear@5: unsigned int load_texture(const char *fname) nuclear@5: { nuclear@5: int xsz, ysz; nuclear@5: void *pixels; nuclear@5: unsigned int tex; nuclear@5: nuclear@5: const char *path = find_path(fname); nuclear@5: nuclear@5: if(!(pixels = img_load_pixels(path, &xsz, &ysz, IMG_FMT_RGBA32))) { nuclear@5: fprintf(stderr, "failed to load texture: %s\n", fname); nuclear@5: return 0; nuclear@5: } nuclear@5: nuclear@5: glGenTextures(1, &tex); nuclear@5: glBindTexture(GL_TEXTURE_2D, tex); nuclear@5: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nuclear@5: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); nuclear@5: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); nuclear@5: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); nuclear@5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); nuclear@5: img_free_pixels(pixels); nuclear@5: return tex; nuclear@5: } nuclear@5: nuclear@5: static char *read_shader(const char *fname) nuclear@5: { nuclear@5: FILE *fp = fopen(fname, "r"); nuclear@5: if(!fp) { nuclear@5: return 0; nuclear@5: } nuclear@5: fseek(fp, 0, SEEK_END); nuclear@5: long len = ftell(); nuclear@5: rewind(fp); nuclear@5: nuclear@5: char *buf = new char[len + 1]; nuclear@5: fread(buf, len, fp); nuclear@5: buf[len] = 0; nuclear@5: fclose(fp); nuclear@5: nuclear@5: return buf; nuclear@5: } nuclear@5: nuclear@5: unsigned int load_shader_program(const char *vname, const char *pname) nuclear@5: { nuclear@5: unsigned int vsdr = 0, psdr = 0; nuclear@5: nuclear@5: if(vname) { nuclear@5: char *src = read_shader(find_path(vname)); nuclear@5: if(!src) { nuclear@5: fprintf(stderr, "failed to load vertex shader: %s\n", vname); nuclear@5: return 0; nuclear@5: } nuclear@5: vsdr = glCreateShader(GL_VERTEX_SHADER); nuclear@5: glShaderSource(vsdr, 1, &src, 0); nuclear@5: delete [] src; nuclear@5: nuclear@5: int res; nuclear@5: glGetShaderiv(vsdr, GL_INFO_LOG_LENGTH, &res); nuclear@5: if(res > 0) {URE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); nuclear@5: img_free_pixels(pixels); nuclear@5: return tex; nuclear@5: } nuclear@5: nuclear@5: static char *read_shader(const char *fname) nuclear@5: { nuclear@5: FILE *fp = fopen(find_path(vname), "r"); nuclear@5: if(!fp) { nuclear@5: fprintf(stderr, "failed to load shader: %s\n", vname); nuclear@5: return 0; nuclear@5: char *info = new char[res]; nuclear@5: glGetShaderInfoLog(vsdr, res, &res, info); nuclear@5: printf("shader compiler log: %s\n", info); nuclear@5: } nuclear@5: glGetShaderiv(vsdr, GL_COMPILE_STATUS, &res); nuclear@5: if(!res) { nuclear@5: return 0; nuclear@5: } nuclear@5: } nuclear@5: } nuclear@5: nuclear@5: static const char *find_path(const char *fname) nuclear@5: { nuclear@5: const char *ptr = fname + strlen(fname) - 1; nuclear@5: nuclear@5: do { nuclear@5: while(*ptr != '/' && ptr > fname - 1) { nuclear@5: ptr--; nuclear@5: } nuclear@5: nuclear@5: FILE *fp = fopen(ptr + 1, "rb"); nuclear@5: if(fp) { nuclear@5: fclose(fp); nuclear@5: return ptr + 1; nuclear@5: } nuclear@5: ptr -= 1; nuclear@5: nuclear@5: } while(ptr >= fname); nuclear@5: nuclear@5: return fname; nuclear@5: }