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@6
|
75 for(int i=num_tex; i<4; i++) {
|
nuclear@6
|
76 glActiveTexture(GL_TEXTURE0 + i);
|
nuclear@6
|
77 glDisable(GL_TEXTURE_2D);
|
nuclear@5
|
78 }
|
nuclear@5
|
79
|
nuclear@5
|
80 glActiveTexture(GL_TEXTURE0);
|
nuclear@5
|
81 glMatrixMode(GL_MODELVIEW);
|
nuclear@3
|
82 }
|
nuclear@5
|
83
|
nuclear@5
|
84 unsigned int load_texture(const char *fname)
|
nuclear@5
|
85 {
|
nuclear@5
|
86 int xsz, ysz;
|
nuclear@5
|
87 void *pixels;
|
nuclear@5
|
88 unsigned int tex;
|
nuclear@5
|
89
|
nuclear@5
|
90 const char *path = find_path(fname);
|
nuclear@5
|
91
|
nuclear@5
|
92 if(!(pixels = img_load_pixels(path, &xsz, &ysz, IMG_FMT_RGBA32))) {
|
nuclear@5
|
93 fprintf(stderr, "failed to load texture: %s\n", fname);
|
nuclear@5
|
94 return 0;
|
nuclear@5
|
95 }
|
nuclear@5
|
96
|
nuclear@5
|
97 glGenTextures(1, &tex);
|
nuclear@5
|
98 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@5
|
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@5
|
100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@5
|
101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
nuclear@5
|
102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
nuclear@5
|
103 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
nuclear@5
|
104 img_free_pixels(pixels);
|
nuclear@5
|
105 return tex;
|
nuclear@5
|
106 }
|
nuclear@5
|
107
|
nuclear@5
|
108 static const char *find_path(const char *fname)
|
nuclear@5
|
109 {
|
nuclear@5
|
110 const char *ptr = fname + strlen(fname) - 1;
|
nuclear@5
|
111
|
nuclear@5
|
112 do {
|
nuclear@5
|
113 while(*ptr != '/' && ptr > fname - 1) {
|
nuclear@5
|
114 ptr--;
|
nuclear@5
|
115 }
|
nuclear@5
|
116
|
nuclear@5
|
117 FILE *fp = fopen(ptr + 1, "rb");
|
nuclear@5
|
118 if(fp) {
|
nuclear@5
|
119 fclose(fp);
|
nuclear@5
|
120 return ptr + 1;
|
nuclear@5
|
121 }
|
nuclear@5
|
122 ptr -= 1;
|
nuclear@5
|
123
|
nuclear@5
|
124 } while(ptr >= fname);
|
nuclear@5
|
125
|
nuclear@5
|
126 return fname;
|
nuclear@5
|
127 }
|