-
Notifications
You must be signed in to change notification settings - Fork 2
/
Material.mm
191 lines (156 loc) · 4.65 KB
/
Material.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//
// Material.mm
// aiObjectiveC
//
// Created by Jørgen P. Tjernø on 10/30/10.
// Copyright 2010 devSoft. All rights reserved.
//
#import "Material.h"
#import "NSString+AI.h"
#import "GLErrorChecking.h"
@implementation Material
@synthesize texture, bumpmap;
+ (id) materialWithAsset:(const aiMaterial *)asset
{
return [[[self alloc] initWithAsset:asset] autorelease];
}
- (id) initWithAsset:(const aiMaterial *)asset
{
if (self = [super init])
{
bumpmap = texture = 0;
glCheckAndClearErrors();
if (asset->GetTextureCount(aiTextureType_DIFFUSE) > 0)
{
texture = [self texture:0
ofType:aiTextureType_DIFFUSE
fromAsset:asset];
}
if (asset->GetTextureCount(aiTextureType_HEIGHT) > 0)
{
bumpmap = [self texture:0
ofType:aiTextureType_HEIGHT
fromAsset:asset];
}
}
return self;
}
- (void) dealloc
{
if (texture)
glDeleteTextures(1, &texture);
if (bumpmap)
glDeleteTextures(1, &bumpmap);
[super dealloc];
}
- (GLuint) texture:(int)num
ofType:(aiTextureType)type
fromAsset:(const aiMaterial *)asset
{
aiTextureMapMode mapMode;
aiString *texturePathTmp = new aiString();
asset->GetTexture(type, num, texturePathTmp, NULL, NULL, NULL, NULL, &mapMode);
NSString *texturePath = [NSString stringWithAIString:texturePathTmp];
delete texturePathTmp;
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
if (!glHasError() && [self loadTexture:texturePath])
{
if (mapMode == aiTextureMapMode_Wrap)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
else if (mapMode == aiTextureMapMode_Clamp)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
}
else
{
NSLog(@"Unsupported texturemapmode for %@: %i", texturePath, mapMode);
}
}
else
{
NSLog(@"Failed loading texture '%@'!", texturePath);
glDeleteTextures(1, &textureId);
textureId = 0;
}
return textureId;
}
- (BOOL) loadTexture:(NSString *)path
{
glCheckAndClearErrors();
NSString *filename = [path lastPathComponent];
NSString *texturePath = [[NSBundle mainBundle] pathForResource:filename
ofType:@""
inDirectory:@"Textures"];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:texturePath];
if (!image)
{
return NO;
}
NSRect imageRect;
imageRect.origin = NSZeroPoint;
imageRect.size = [image size];
[image lockFocus];
[image setFlipped:YES];
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect];
[image unlockFocus];
[image release];
if (!imageRep)
{
return NO;
}
int bytesPerRow = [imageRep bytesPerRow];
int bitsPerPixel = [imageRep bitsPerPixel];
BOOL hasAlpha = [imageRep hasAlpha];
GLenum format = hasAlpha ? GL_RGBA : GL_RGB;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glCheckAndClearErrors();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, bytesPerRow / (bitsPerPixel >> 3));
glCheckAndClearErrors();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageRect.size.width,
imageRect.size.height, 0, format, GL_UNSIGNED_BYTE,
[imageRep bitmapData]);
[imageRep release];
if (glHasError())
{
return NO;
}
glGenerateMipmap(GL_TEXTURE_2D);
glCheckAndClearErrors();
return YES;
}
- (void) apply
{
glCheckAndClearErrorsIfDEBUG();
if (texture || bumpmap)
{
glEnable(GL_TEXTURE_2D);
}
else
{
glDisable(GL_TEXTURE_2D);
}
glCheckAndClearErrorsIfDEBUG();
if (texture)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
}
glCheckAndClearErrorsIfDEBUG();
if (bumpmap)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, bumpmap);
}
glCheckAndClearErrorsIfDEBUG();
}
@end