# HG changeset patch # User John Tsiombikas # Date 1405633335 -10800 # Node ID 9b5bb05ae53ada320e32fc522e9eeb07335cbb0d # Parent 3d3656360a821430030cdf594f23bafb58e0661c foo diff -r 3d3656360a82 -r 9b5bb05ae53a Makefile --- a/Makefile Thu Jul 17 08:51:17 2014 +0300 +++ b/Makefile Fri Jul 18 00:42:15 2014 +0300 @@ -5,7 +5,7 @@ CFLAGS = -pedantic -Wall -g CXXFLAGS = $(CFLAGS) -LDFLAGS = -lGL -lGLU -lGLEW -lX11 -lm -lpthread +LDFLAGS = -lGL -lGLU -lGLEW -lX11 -lm -lpthread -limago $(bin): $(obj) $(CXX) -o $@ $(obj) $(LDFLAGS) diff -r 3d3656360a82 -r 9b5bb05ae53a src/material.cc --- a/src/material.cc Thu Jul 17 08:51:17 2014 +0300 +++ b/src/material.cc Fri Jul 18 00:42:15 2014 +0300 @@ -1,11 +1,21 @@ +#include #include +#include #include "material.h" +static const char *find_path(const char *fname); + Material::Material() : diffuse(1, 1, 1), specular(0, 0, 0) { shininess = 1.0; alpha = 1.0; + + for(int i=0; i 128 ? 128 : shininess); + + if(sdr) { + glUseProgram(sdr); + } + + if(tex[TEX_DIFFUSE]) { + glActiveTexture(GL_TEXTURE0); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(tex_offset[TEX_DIFFUSE].x, tex_offset[TEX_DIFFUSE].y, 0); + glScalef(tex_scale[TEX_DIFFUSE].x, tex_scale[TEX_DIFFUSE].y, 1); + + glBindTexture(GL_TEXTURE_2D, tex[TEX_DIFFUSE]); + glEnable(GL_TEXTURE_2D); + + int loc = glGetUniformLocation(sdr, "tex_diffuse"); + if(loc != -1) { + glUniform1i(loc, 0); + } + } + if(tex[TEX_ENVMAP]) { + glActiveTexture(GL_TEXTURE1); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(tex_offset[TEX_ENVMAP].x, tex_offset[TEX_ENVMAP].y, 0); + glScalef(tex_scale[TEX_ENVMAP].x, tex_scale[TEX_ENVMAP].y, 1); + + glBindTexture(GL_TEXTURE_2D, tex[TEX_ENVMAP]); + glEnable(GL_TEXTURE_2D); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + int loc = glGetUniformLocation(sdr, "tex_envmap"); + if(loc != -1) { + glUniform1i(loc, 1); + } + } + + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_MODELVIEW); } + +unsigned int load_texture(const char *fname) +{ + int xsz, ysz; + void *pixels; + unsigned int tex; + + const char *path = find_path(fname); + + if(!(pixels = img_load_pixels(path, &xsz, &ysz, IMG_FMT_RGBA32))) { + fprintf(stderr, "failed to load texture: %s\n", fname); + return 0; + } + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + img_free_pixels(pixels); + return tex; +} + +static char *read_shader(const char *fname) +{ + FILE *fp = fopen(fname, "r"); + if(!fp) { + return 0; + } + fseek(fp, 0, SEEK_END); + long len = ftell(); + rewind(fp); + + char *buf = new char[len + 1]; + fread(buf, len, fp); + buf[len] = 0; + fclose(fp); + + return buf; +} + +unsigned int load_shader_program(const char *vname, const char *pname) +{ + unsigned int vsdr = 0, psdr = 0; + + if(vname) { + char *src = read_shader(find_path(vname)); + if(!src) { + fprintf(stderr, "failed to load vertex shader: %s\n", vname); + return 0; + } + vsdr = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vsdr, 1, &src, 0); + delete [] src; + + int res; + glGetShaderiv(vsdr, GL_INFO_LOG_LENGTH, &res); + if(res > 0) {URE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + img_free_pixels(pixels); + return tex; +} + +static char *read_shader(const char *fname) +{ + FILE *fp = fopen(find_path(vname), "r"); + if(!fp) { + fprintf(stderr, "failed to load shader: %s\n", vname); + return 0; + char *info = new char[res]; + glGetShaderInfoLog(vsdr, res, &res, info); + printf("shader compiler log: %s\n", info); + } + glGetShaderiv(vsdr, GL_COMPILE_STATUS, &res); + if(!res) { + return 0; + } + } +} + +static const char *find_path(const char *fname) +{ + const char *ptr = fname + strlen(fname) - 1; + + do { + while(*ptr != '/' && ptr > fname - 1) { + ptr--; + } + + FILE *fp = fopen(ptr + 1, "rb"); + if(fp) { + fclose(fp); + return ptr + 1; + } + ptr -= 1; + + } while(ptr >= fname); + + return fname; +} diff -r 3d3656360a82 -r 9b5bb05ae53a src/material.h --- a/src/material.h Thu Jul 17 08:51:17 2014 +0300 +++ b/src/material.h Fri Jul 18 00:42:15 2014 +0300 @@ -3,6 +3,13 @@ #include "vmath.h" +enum { + TEX_DIFFUSE, + TEX_ENVMAP, + + NUM_TEXTURES +}; + class Material { public: Vector3 ambient; @@ -11,9 +18,17 @@ float shininess; float alpha; + unsigned int tex[NUM_TEXTURES]; + Vector2 tex_scale[NUM_TEXTURES], tex_offset[NUM_TEXTURES]; + + unsigned int sdr; + Material(); void setup() const; }; +unsigned int load_texture(const char *fname); +unsigned int load_shader_program(const char *vname, const char *pname); + #endif // MATERIAL_H_ diff -r 3d3656360a82 -r 9b5bb05ae53a src/objfile.cc --- a/src/objfile.cc Thu Jul 17 08:51:17 2014 +0300 +++ b/src/objfile.cc Fri Jul 18 00:42:15 2014 +0300 @@ -209,9 +209,12 @@ mat.shininess = vmtl[i].shininess; mat.alpha = vmtl[i].alpha; - /*if(vmtl[i].tex_dif.length()) { - mat.set_texture(get_texture(vmtl[i].tex_dif.c_str())); - }*/ + if(vmtl[i].tex_dif.length()) { + mat.tex[TEX_DIFFUSE] = load_texture(vmtl[i].tex_dif.c_str()); + } + if(vmtl[i].tex_refl.length()) { + mat.tex[TEX_ENVMAP] = load_texture(vmtl[i].tex_refl.c_str()); + } matlib[vmtl[i].name] = mat; }