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