rev |
line source |
nuclear@12
|
1 /*
|
nuclear@12
|
2 eqemu - electronic queue system emulator
|
nuclear@12
|
3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>,
|
nuclear@12
|
4 Eleni-Maria Stea <eleni@mutantstargoat.com>
|
nuclear@12
|
5
|
nuclear@12
|
6 This program is free software: you can redistribute it and/or modify
|
nuclear@12
|
7 it under the terms of the GNU General Public License as published by
|
nuclear@12
|
8 the Free Software Foundation, either version 3 of the License, or
|
nuclear@12
|
9 (at your option) any later version.
|
nuclear@12
|
10
|
nuclear@12
|
11 This program is distributed in the hope that it will be useful,
|
nuclear@12
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nuclear@12
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nuclear@12
|
14 GNU General Public License for more details.
|
nuclear@12
|
15
|
nuclear@12
|
16 You should have received a copy of the GNU General Public License
|
nuclear@12
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
nuclear@12
|
18 */
|
nuclear@5
|
19 #include <string.h>
|
nuclear@3
|
20 #include <GL/glew.h>
|
nuclear@5
|
21 #include <imago2.h>
|
nuclear@3
|
22 #include "material.h"
|
nuclear@3
|
23
|
nuclear@5
|
24 static const char *find_path(const char *fname);
|
nuclear@5
|
25
|
nuclear@3
|
26 Material::Material()
|
nuclear@4
|
27 : diffuse(1, 1, 1), specular(0, 0, 0)
|
nuclear@3
|
28 {
|
nuclear@3
|
29 shininess = 1.0;
|
nuclear@3
|
30 alpha = 1.0;
|
nuclear@5
|
31
|
nuclear@5
|
32 for(int i=0; i<NUM_TEXTURES; i++) {
|
nuclear@5
|
33 tex[i] = 0;
|
nuclear@5
|
34 tex_scale[i].x = tex_scale[i].y = 1.0f;
|
nuclear@5
|
35 }
|
nuclear@5
|
36 sdr = 0;
|
nuclear@3
|
37 }
|
nuclear@3
|
38
|
nuclear@3
|
39 void Material::setup() const
|
nuclear@3
|
40 {
|
nuclear@6
|
41 float amb[] = {ambient.x, ambient.y, ambient.z, 1.0};
|
nuclear@6
|
42 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
|
nuclear@6
|
43
|
nuclear@4
|
44 float col[] = {diffuse.x, diffuse.y, diffuse.z, alpha};
|
nuclear@6
|
45 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
nuclear@3
|
46
|
nuclear@3
|
47 float spec[] = {specular.x, specular.y, specular.z, 1.0};
|
nuclear@3
|
48 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
|
nuclear@3
|
49
|
nuclear@3
|
50 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess > 128 ? 128 : shininess);
|
nuclear@5
|
51
|
nuclear@6
|
52 float emit[] = {emissive.x, emissive.y, emissive.z, 1.0};
|
nuclear@6
|
53 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emit);
|
nuclear@5
|
54
|
nuclear@6
|
55 int num_tex = 0;
|
nuclear@5
|
56 if(tex[TEX_DIFFUSE]) {
|
nuclear@6
|
57 glActiveTexture(GL_TEXTURE0 + num_tex++);
|
nuclear@5
|
58
|
nuclear@5
|
59 glMatrixMode(GL_TEXTURE);
|
nuclear@5
|
60 glLoadIdentity();
|
nuclear@5
|
61 glTranslatef(tex_offset[TEX_DIFFUSE].x, tex_offset[TEX_DIFFUSE].y, 0);
|
nuclear@5
|
62 glScalef(tex_scale[TEX_DIFFUSE].x, tex_scale[TEX_DIFFUSE].y, 1);
|
nuclear@5
|
63
|
nuclear@5
|
64 glBindTexture(GL_TEXTURE_2D, tex[TEX_DIFFUSE]);
|
nuclear@5
|
65 glEnable(GL_TEXTURE_2D);
|
nuclear@5
|
66
|
nuclear@6
|
67 glDisable(GL_TEXTURE_GEN_S);
|
nuclear@6
|
68 glDisable(GL_TEXTURE_GEN_T);
|
nuclear@6
|
69
|
nuclear@6
|
70 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
nuclear@5
|
71 }
|
nuclear@6
|
72
|
nuclear@5
|
73 if(tex[TEX_ENVMAP]) {
|
nuclear@6
|
74 glActiveTexture(GL_TEXTURE0 + num_tex++);
|
nuclear@5
|
75
|
nuclear@5
|
76 glMatrixMode(GL_TEXTURE);
|
nuclear@5
|
77 glLoadIdentity();
|
nuclear@5
|
78 glTranslatef(tex_offset[TEX_ENVMAP].x, tex_offset[TEX_ENVMAP].y, 0);
|
nuclear@5
|
79 glScalef(tex_scale[TEX_ENVMAP].x, tex_scale[TEX_ENVMAP].y, 1);
|
nuclear@5
|
80
|
nuclear@5
|
81 glBindTexture(GL_TEXTURE_2D, tex[TEX_ENVMAP]);
|
nuclear@5
|
82 glEnable(GL_TEXTURE_2D);
|
nuclear@5
|
83
|
nuclear@5
|
84 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
nuclear@5
|
85 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
|
nuclear@5
|
86 glEnable(GL_TEXTURE_GEN_S);
|
nuclear@5
|
87 glEnable(GL_TEXTURE_GEN_T);
|
nuclear@5
|
88
|
nuclear@6
|
89 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
|
nuclear@6
|
90 }
|
nuclear@6
|
91
|
nuclear@6
|
92
|
nuclear@7
|
93 glMatrixMode(GL_TEXTURE);
|
nuclear@6
|
94 for(int i=num_tex; i<4; i++) {
|
nuclear@6
|
95 glActiveTexture(GL_TEXTURE0 + i);
|
nuclear@6
|
96 glDisable(GL_TEXTURE_2D);
|
nuclear@7
|
97 glLoadIdentity();
|
nuclear@5
|
98 }
|
nuclear@5
|
99
|
nuclear@5
|
100 glActiveTexture(GL_TEXTURE0);
|
nuclear@5
|
101 glMatrixMode(GL_MODELVIEW);
|
nuclear@3
|
102 }
|
nuclear@5
|
103
|
nuclear@5
|
104 unsigned int load_texture(const char *fname)
|
nuclear@5
|
105 {
|
nuclear@5
|
106 int xsz, ysz;
|
nuclear@5
|
107 void *pixels;
|
nuclear@5
|
108 unsigned int tex;
|
nuclear@5
|
109
|
nuclear@5
|
110 const char *path = find_path(fname);
|
nuclear@5
|
111
|
nuclear@5
|
112 if(!(pixels = img_load_pixels(path, &xsz, &ysz, IMG_FMT_RGBA32))) {
|
nuclear@5
|
113 fprintf(stderr, "failed to load texture: %s\n", fname);
|
nuclear@5
|
114 return 0;
|
nuclear@5
|
115 }
|
nuclear@5
|
116
|
nuclear@5
|
117 glGenTextures(1, &tex);
|
nuclear@5
|
118 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@5
|
119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@5
|
120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@5
|
121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
nuclear@5
|
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
nuclear@5
|
123 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
nuclear@5
|
124 img_free_pixels(pixels);
|
nuclear@5
|
125 return tex;
|
nuclear@5
|
126 }
|
nuclear@5
|
127
|
nuclear@5
|
128 static const char *find_path(const char *fname)
|
nuclear@5
|
129 {
|
nuclear@5
|
130 const char *ptr = fname + strlen(fname) - 1;
|
nuclear@5
|
131
|
nuclear@5
|
132 do {
|
nuclear@5
|
133 while(*ptr != '/' && ptr > fname - 1) {
|
nuclear@5
|
134 ptr--;
|
nuclear@5
|
135 }
|
nuclear@5
|
136
|
nuclear@5
|
137 FILE *fp = fopen(ptr + 1, "rb");
|
nuclear@5
|
138 if(fp) {
|
nuclear@5
|
139 fclose(fp);
|
nuclear@5
|
140 return ptr + 1;
|
nuclear@5
|
141 }
|
nuclear@5
|
142 ptr -= 1;
|
nuclear@5
|
143
|
nuclear@5
|
144 } while(ptr >= fname);
|
nuclear@5
|
145
|
nuclear@5
|
146 return fname;
|
nuclear@5
|
147 }
|