rev |
line source |
nuclear@5
|
1 #include <string.h>
|
nuclear@3
|
2 #include <GL/glew.h>
|
nuclear@5
|
3 #include <imago2.h>
|
nuclear@3
|
4 #include "material.h"
|
nuclear@3
|
5
|
nuclear@5
|
6 static const char *find_path(const char *fname);
|
nuclear@5
|
7
|
nuclear@3
|
8 Material::Material()
|
nuclear@4
|
9 : diffuse(1, 1, 1), specular(0, 0, 0)
|
nuclear@3
|
10 {
|
nuclear@3
|
11 shininess = 1.0;
|
nuclear@3
|
12 alpha = 1.0;
|
nuclear@5
|
13
|
nuclear@5
|
14 for(int i=0; i<NUM_TEXTURES; i++) {
|
nuclear@5
|
15 tex[i] = 0;
|
nuclear@5
|
16 tex_scale[i].x = tex_scale[i].y = 1.0f;
|
nuclear@5
|
17 }
|
nuclear@5
|
18 sdr = 0;
|
nuclear@3
|
19 }
|
nuclear@3
|
20
|
nuclear@3
|
21 void Material::setup() const
|
nuclear@3
|
22 {
|
nuclear@6
|
23 float amb[] = {ambient.x, ambient.y, ambient.z, 1.0};
|
nuclear@6
|
24 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
|
nuclear@6
|
25
|
nuclear@4
|
26 float col[] = {diffuse.x, diffuse.y, diffuse.z, alpha};
|
nuclear@6
|
27 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
nuclear@3
|
28
|
nuclear@3
|
29 float spec[] = {specular.x, specular.y, specular.z, 1.0};
|
nuclear@3
|
30 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
|
nuclear@3
|
31
|
nuclear@3
|
32 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess > 128 ? 128 : shininess);
|
nuclear@5
|
33
|
nuclear@6
|
34 float emit[] = {emissive.x, emissive.y, emissive.z, 1.0};
|
nuclear@6
|
35 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emit);
|
nuclear@5
|
36
|
nuclear@6
|
37 int num_tex = 0;
|
nuclear@5
|
38 if(tex[TEX_DIFFUSE]) {
|
nuclear@6
|
39 glActiveTexture(GL_TEXTURE0 + num_tex++);
|
nuclear@5
|
40
|
nuclear@5
|
41 glMatrixMode(GL_TEXTURE);
|
nuclear@5
|
42 glLoadIdentity();
|
nuclear@5
|
43 glTranslatef(tex_offset[TEX_DIFFUSE].x, tex_offset[TEX_DIFFUSE].y, 0);
|
nuclear@5
|
44 glScalef(tex_scale[TEX_DIFFUSE].x, tex_scale[TEX_DIFFUSE].y, 1);
|
nuclear@5
|
45
|
nuclear@5
|
46 glBindTexture(GL_TEXTURE_2D, tex[TEX_DIFFUSE]);
|
nuclear@5
|
47 glEnable(GL_TEXTURE_2D);
|
nuclear@5
|
48
|
nuclear@6
|
49 glDisable(GL_TEXTURE_GEN_S);
|
nuclear@6
|
50 glDisable(GL_TEXTURE_GEN_T);
|
nuclear@6
|
51
|
nuclear@6
|
52 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
nuclear@5
|
53 }
|
nuclear@6
|
54
|
nuclear@5
|
55 if(tex[TEX_ENVMAP]) {
|
nuclear@6
|
56 glActiveTexture(GL_TEXTURE0 + num_tex++);
|
nuclear@5
|
57
|
nuclear@5
|
58 glMatrixMode(GL_TEXTURE);
|
nuclear@5
|
59 glLoadIdentity();
|
nuclear@5
|
60 glTranslatef(tex_offset[TEX_ENVMAP].x, tex_offset[TEX_ENVMAP].y, 0);
|
nuclear@5
|
61 glScalef(tex_scale[TEX_ENVMAP].x, tex_scale[TEX_ENVMAP].y, 1);
|
nuclear@5
|
62
|
nuclear@5
|
63 glBindTexture(GL_TEXTURE_2D, tex[TEX_ENVMAP]);
|
nuclear@5
|
64 glEnable(GL_TEXTURE_2D);
|
nuclear@5
|
65
|
nuclear@5
|
66 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
nuclear@5
|
67 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
nuclear@5
|
68 glEnable(GL_TEXTURE_GEN_S);
|
nuclear@5
|
69 glEnable(GL_TEXTURE_GEN_T);
|
nuclear@5
|
70
|
nuclear@6
|
71 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
|
nuclear@6
|
72 }
|
nuclear@6
|
73
|
nuclear@6
|
74
|
nuclear@7
|
75 glMatrixMode(GL_TEXTURE);
|
nuclear@6
|
76 for(int i=num_tex; i<4; i++) {
|
nuclear@6
|
77 glActiveTexture(GL_TEXTURE0 + i);
|
nuclear@6
|
78 glDisable(GL_TEXTURE_2D);
|
nuclear@7
|
79 glLoadIdentity();
|
nuclear@5
|
80 }
|
nuclear@5
|
81
|
nuclear@5
|
82 glActiveTexture(GL_TEXTURE0);
|
nuclear@5
|
83 glMatrixMode(GL_MODELVIEW);
|
nuclear@3
|
84 }
|
nuclear@5
|
85
|
nuclear@5
|
86 unsigned int load_texture(const char *fname)
|
nuclear@5
|
87 {
|
nuclear@5
|
88 int xsz, ysz;
|
nuclear@5
|
89 void *pixels;
|
nuclear@5
|
90 unsigned int tex;
|
nuclear@5
|
91
|
nuclear@5
|
92 const char *path = find_path(fname);
|
nuclear@5
|
93
|
nuclear@5
|
94 if(!(pixels = img_load_pixels(path, &xsz, &ysz, IMG_FMT_RGBA32))) {
|
nuclear@5
|
95 fprintf(stderr, "failed to load texture: %s\n", fname);
|
nuclear@5
|
96 return 0;
|
nuclear@5
|
97 }
|
nuclear@5
|
98
|
nuclear@5
|
99 glGenTextures(1, &tex);
|
nuclear@5
|
100 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@5
|
101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@5
|
102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@5
|
103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
nuclear@5
|
104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
nuclear@5
|
105 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
nuclear@5
|
106 img_free_pixels(pixels);
|
nuclear@5
|
107 return tex;
|
nuclear@5
|
108 }
|
nuclear@5
|
109
|
nuclear@5
|
110 static const char *find_path(const char *fname)
|
nuclear@5
|
111 {
|
nuclear@5
|
112 const char *ptr = fname + strlen(fname) - 1;
|
nuclear@5
|
113
|
nuclear@5
|
114 do {
|
nuclear@5
|
115 while(*ptr != '/' && ptr > fname - 1) {
|
nuclear@5
|
116 ptr--;
|
nuclear@5
|
117 }
|
nuclear@5
|
118
|
nuclear@5
|
119 FILE *fp = fopen(ptr + 1, "rb");
|
nuclear@5
|
120 if(fp) {
|
nuclear@5
|
121 fclose(fp);
|
nuclear@5
|
122 return ptr + 1;
|
nuclear@5
|
123 }
|
nuclear@5
|
124 ptr -= 1;
|
nuclear@5
|
125
|
nuclear@5
|
126 } while(ptr >= fname);
|
nuclear@5
|
127
|
nuclear@5
|
128 return fname;
|
nuclear@5
|
129 }
|