texture mipmap levels

This commit is contained in:
Vadim Lopatin 2016-04-06 12:17:33 +03:00
parent ca71fe2e54
commit 0d3fc3b1b5
4 changed files with 47 additions and 8 deletions

View File

@ -122,7 +122,7 @@ class UiWidget : VerticalLayout, CellVisitor {
dirLightNode.translateX(2); dirLightNode.translateX(2);
dirLightNode.translateY(3); dirLightNode.translateY(3);
dirLightNode.translateZ(0); dirLightNode.translateZ(0);
dirLightNode.light = Light.createPoint(vec3(3, 3, 3), 15); //Light.createDirectional(vec3(1, 0.5, 0.5)); dirLightNode.light = Light.createPoint(vec3(2, 2, 2), 15); //Light.createDirectional(vec3(1, 0.5, 0.5));
//dirLightNode.light = Light.createDirectional(vec3(1, 0.5, 0.8)); //dirLightNode.light = Light.createDirectional(vec3(1, 0.5, 0.8));
dirLightNode.light.enabled = true; dirLightNode.light.enabled = true;
_scene.addChild(dirLightNode); _scene.addChild(dirLightNode);

View File

@ -853,7 +853,7 @@ static class GLTexture : RefCountedObject {
} }
uint * pixels = buf.scanLine(0); uint * pixels = buf.scanLine(0);
buf.invertAlpha(); buf.invertAlpha();
if (!glSupport.setTextureImage(_texture, buf.width, buf.height, cast(ubyte*)pixels)) { if (!glSupport.setTextureImage(_texture, buf.width, buf.height, cast(ubyte*)pixels, 10)) {
destroy(_texture); destroy(_texture);
_texture = null; _texture = null;
buf.invertAlpha(); buf.invertAlpha();

View File

@ -951,7 +951,33 @@ final class GLSupport {
checkgl!glFlush(); checkgl!glFlush();
} }
bool setTextureImage(Tex2D texture, int dx, int dy, ubyte * pixels) { bool generateMipmap(int dx, int dy, ubyte * pixels, int level, ref ubyte[] dst) {
if ((dx & 1) || (dy & 1) || dx < 2 || dy < 2)
return false; // size is not even
int newdx = dx / 2;
int newdy = dy / 2;
int newlen = newdx * newdy * 4;
if (newlen > dst.length)
dst.length = newlen;
ubyte * dstptr = dst.ptr;
ubyte * srcptr = pixels;
int srcstride = dx * 4;
for (int y = 0; y < newdy; y++) {
for (int x = 0; x < newdx; x++) {
dstptr[0] = cast(ubyte)((srcptr[0+0] + srcptr[0+4] + srcptr[0+srcstride] + srcptr[0+srcstride + 4])>>2);
dstptr[1] = cast(ubyte)((srcptr[1+0] + srcptr[1+4] + srcptr[1+srcstride] + srcptr[1+srcstride + 4])>>2);
dstptr[2] = cast(ubyte)((srcptr[2+0] + srcptr[2+4] + srcptr[2+srcstride] + srcptr[2+srcstride + 4])>>2);
dstptr[3] = cast(ubyte)((srcptr[3+0] + srcptr[3+4] + srcptr[3+srcstride] + srcptr[3+srcstride + 4])>>2);
dstptr += 4;
srcptr += 8;
}
srcptr += srcstride; // skip srcline
}
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, newdx, newdy, 0, GL_RGBA, GL_UNSIGNED_BYTE, dst.ptr);
return true;
}
bool setTextureImage(Tex2D texture, int dx, int dy, ubyte * pixels, int mipmapLevels = 0) {
checkError("before setTextureImage"); checkError("before setTextureImage");
texture.bind(); texture.bind();
checkgl!glPixelStorei(GL_UNPACK_ALIGNMENT, 1); checkgl!glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -963,6 +989,19 @@ final class GLSupport {
Log.e("Cannot set image for texture"); Log.e("Cannot set image for texture");
return false; return false;
} }
if (mipmapLevels > 1) {
ubyte[] buffer;
ubyte * src = pixels;
int ndx = dx;
int ndy = dy;
for (int i = 1; i < mipmapLevels; i++) {
if (!generateMipmap(ndx, ndy, src, i, buffer))
break;
ndx /= 2;
ndy /= 2;
src = buffer.ptr;
}
}
texture.unbind(); texture.unbind();
return true; return true;
} }
@ -1145,9 +1184,9 @@ class GLObject(GLObjectTypes type, GLuint target = 0) {
static if(type == GLObjectTypes.Texture) static if(type == GLObjectTypes.Texture)
{ {
void setSamplerParams(bool linear, bool clamp = false) { void setSamplerParams(bool linear, bool clamp = false, bool mipmap = false) {
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, linear ? (!mipmap ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR) : (!mipmap ? GL_NEAREST : GL_NEAREST_MIPMAP_NEAREST));
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, linear ? (!mipmap ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR) : (!mipmap ? GL_NEAREST : GL_NEAREST_MIPMAP_NEAREST));
checkError("filtering - glTexParameteri"); checkError("filtering - glTexParameteri");
if(clamp) { if(clamp) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@ -150,11 +150,11 @@ class Material : RefCountedObject {
effect.bind(); effect.bind();
if (!texture.isNull) { if (!texture.isNull) {
texture.texture.setup(); texture.texture.setup();
texture.texture.setSamplerParams(true); texture.texture.setSamplerParams(true, true, true);
} }
if (!bumpTexture.isNull) { if (!bumpTexture.isNull) {
bumpTexture.texture.setup(1); bumpTexture.texture.setup(1);
bumpTexture.texture.setSamplerParams(true); bumpTexture.texture.setSamplerParams(true, true, true);
} }
// matrixes, positions uniforms // matrixes, positions uniforms
if (_effect.hasUniform(DefaultUniform.u_worldViewProjectionMatrix)) if (_effect.hasUniform(DefaultUniform.u_worldViewProjectionMatrix))