eqemu

annotate src/material.cc @ 5:9b5bb05ae53a

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 18 Jul 2014 00:42:15 +0300
parents 3d3656360a82
children 977bc1cb055b
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@4 23 float col[] = {diffuse.x, diffuse.y, diffuse.z, alpha};
nuclear@3 24 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
nuclear@3 25
nuclear@3 26 float spec[] = {specular.x, specular.y, specular.z, 1.0};
nuclear@3 27 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
nuclear@3 28
nuclear@3 29 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess > 128 ? 128 : shininess);
nuclear@5 30
nuclear@5 31 if(sdr) {
nuclear@5 32 glUseProgram(sdr);
nuclear@5 33 }
nuclear@5 34
nuclear@5 35 if(tex[TEX_DIFFUSE]) {
nuclear@5 36 glActiveTexture(GL_TEXTURE0);
nuclear@5 37
nuclear@5 38 glMatrixMode(GL_TEXTURE);
nuclear@5 39 glLoadIdentity();
nuclear@5 40 glTranslatef(tex_offset[TEX_DIFFUSE].x, tex_offset[TEX_DIFFUSE].y, 0);
nuclear@5 41 glScalef(tex_scale[TEX_DIFFUSE].x, tex_scale[TEX_DIFFUSE].y, 1);
nuclear@5 42
nuclear@5 43 glBindTexture(GL_TEXTURE_2D, tex[TEX_DIFFUSE]);
nuclear@5 44 glEnable(GL_TEXTURE_2D);
nuclear@5 45
nuclear@5 46 int loc = glGetUniformLocation(sdr, "tex_diffuse");
nuclear@5 47 if(loc != -1) {
nuclear@5 48 glUniform1i(loc, 0);
nuclear@5 49 }
nuclear@5 50 }
nuclear@5 51 if(tex[TEX_ENVMAP]) {
nuclear@5 52 glActiveTexture(GL_TEXTURE1);
nuclear@5 53
nuclear@5 54 glMatrixMode(GL_TEXTURE);
nuclear@5 55 glLoadIdentity();
nuclear@5 56 glTranslatef(tex_offset[TEX_ENVMAP].x, tex_offset[TEX_ENVMAP].y, 0);
nuclear@5 57 glScalef(tex_scale[TEX_ENVMAP].x, tex_scale[TEX_ENVMAP].y, 1);
nuclear@5 58
nuclear@5 59 glBindTexture(GL_TEXTURE_2D, tex[TEX_ENVMAP]);
nuclear@5 60 glEnable(GL_TEXTURE_2D);
nuclear@5 61
nuclear@5 62 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
nuclear@5 63 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
nuclear@5 64 glEnable(GL_TEXTURE_GEN_S);
nuclear@5 65 glEnable(GL_TEXTURE_GEN_T);
nuclear@5 66
nuclear@5 67 int loc = glGetUniformLocation(sdr, "tex_envmap");
nuclear@5 68 if(loc != -1) {
nuclear@5 69 glUniform1i(loc, 1);
nuclear@5 70 }
nuclear@5 71 }
nuclear@5 72
nuclear@5 73 glActiveTexture(GL_TEXTURE0);
nuclear@5 74 glMatrixMode(GL_MODELVIEW);
nuclear@3 75 }
nuclear@5 76
nuclear@5 77 unsigned int load_texture(const char *fname)
nuclear@5 78 {
nuclear@5 79 int xsz, ysz;
nuclear@5 80 void *pixels;
nuclear@5 81 unsigned int tex;
nuclear@5 82
nuclear@5 83 const char *path = find_path(fname);
nuclear@5 84
nuclear@5 85 if(!(pixels = img_load_pixels(path, &xsz, &ysz, IMG_FMT_RGBA32))) {
nuclear@5 86 fprintf(stderr, "failed to load texture: %s\n", fname);
nuclear@5 87 return 0;
nuclear@5 88 }
nuclear@5 89
nuclear@5 90 glGenTextures(1, &tex);
nuclear@5 91 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@5 92 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@5 93 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@5 94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
nuclear@5 95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
nuclear@5 96 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
nuclear@5 97 img_free_pixels(pixels);
nuclear@5 98 return tex;
nuclear@5 99 }
nuclear@5 100
nuclear@5 101 static char *read_shader(const char *fname)
nuclear@5 102 {
nuclear@5 103 FILE *fp = fopen(fname, "r");
nuclear@5 104 if(!fp) {
nuclear@5 105 return 0;
nuclear@5 106 }
nuclear@5 107 fseek(fp, 0, SEEK_END);
nuclear@5 108 long len = ftell();
nuclear@5 109 rewind(fp);
nuclear@5 110
nuclear@5 111 char *buf = new char[len + 1];
nuclear@5 112 fread(buf, len, fp);
nuclear@5 113 buf[len] = 0;
nuclear@5 114 fclose(fp);
nuclear@5 115
nuclear@5 116 return buf;
nuclear@5 117 }
nuclear@5 118
nuclear@5 119 unsigned int load_shader_program(const char *vname, const char *pname)
nuclear@5 120 {
nuclear@5 121 unsigned int vsdr = 0, psdr = 0;
nuclear@5 122
nuclear@5 123 if(vname) {
nuclear@5 124 char *src = read_shader(find_path(vname));
nuclear@5 125 if(!src) {
nuclear@5 126 fprintf(stderr, "failed to load vertex shader: %s\n", vname);
nuclear@5 127 return 0;
nuclear@5 128 }
nuclear@5 129 vsdr = glCreateShader(GL_VERTEX_SHADER);
nuclear@5 130 glShaderSource(vsdr, 1, &src, 0);
nuclear@5 131 delete [] src;
nuclear@5 132
nuclear@5 133 int res;
nuclear@5 134 glGetShaderiv(vsdr, GL_INFO_LOG_LENGTH, &res);
nuclear@5 135 if(res > 0) {URE_2D, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
nuclear@5 136 img_free_pixels(pixels);
nuclear@5 137 return tex;
nuclear@5 138 }
nuclear@5 139
nuclear@5 140 static char *read_shader(const char *fname)
nuclear@5 141 {
nuclear@5 142 FILE *fp = fopen(find_path(vname), "r");
nuclear@5 143 if(!fp) {
nuclear@5 144 fprintf(stderr, "failed to load shader: %s\n", vname);
nuclear@5 145 return 0;
nuclear@5 146 char *info = new char[res];
nuclear@5 147 glGetShaderInfoLog(vsdr, res, &res, info);
nuclear@5 148 printf("shader compiler log: %s\n", info);
nuclear@5 149 }
nuclear@5 150 glGetShaderiv(vsdr, GL_COMPILE_STATUS, &res);
nuclear@5 151 if(!res) {
nuclear@5 152 return 0;
nuclear@5 153 }
nuclear@5 154 }
nuclear@5 155 }
nuclear@5 156
nuclear@5 157 static const char *find_path(const char *fname)
nuclear@5 158 {
nuclear@5 159 const char *ptr = fname + strlen(fname) - 1;
nuclear@5 160
nuclear@5 161 do {
nuclear@5 162 while(*ptr != '/' && ptr > fname - 1) {
nuclear@5 163 ptr--;
nuclear@5 164 }
nuclear@5 165
nuclear@5 166 FILE *fp = fopen(ptr + 1, "rb");
nuclear@5 167 if(fp) {
nuclear@5 168 fclose(fp);
nuclear@5 169 return ptr + 1;
nuclear@5 170 }
nuclear@5 171 ptr -= 1;
nuclear@5 172
nuclear@5 173 } while(ptr >= fname);
nuclear@5 174
nuclear@5 175 return fname;
nuclear@5 176 }