Changeset 190
- Timestamp:
- 06/27/10 14:17:58 (2 years ago)
- Files:
-
- trunk/src/yage/resource/collada.d (modified) (1 diff)
- trunk/src/yage/resource/dds.d (added)
- trunk/src/yage/resource/geometry.d (modified) (4 diffs)
- trunk/src/yage/resource/texture.d (modified) (5 diffs)
- trunk/src/yage/system/graphics/api/opengl.d (modified) (2 diffs)
- trunk/src/yage/system/graphics/probe.d (modified) (3 diffs)
- trunk/src/yage/system/window.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/yage/resource/collada.d
r189 r190 420 420 // Enable blending if there's alpha. 421 421 if (pass.blend==MaterialPass.Blend.NONE) 422 if (pass.diffuse.a < 255 || (pass.textures.length && pass.textures[0].texture.getImage() .getChannels()==4))422 if (pass.diffuse.a < 255 || (pass.textures.length && pass.textures[0].texture.getImage() && pass.textures[0].texture.getImage().getChannels()==4)) 423 423 pass.blend = MaterialPass.Blend.AVERAGE; 424 424 trunk/src/yage/resource/geometry.d
r189 r190 11 11 import yage.core.format; 12 12 import yage.core.math.vector; 13 import yage.core.object2; 13 14 import yage.resource.manager; 14 15 import yage.resource.material; … … 86 87 * Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html */ 87 88 public Vec3f[] createTangentVectors() 88 { 89 // TODO: Multiple meshes 90 89 { 91 90 Vec3f[] vertices = cast(Vec3f[])getAttribute(Geometry.VERTICES); 92 91 Vec3f[] normals = cast(Vec3f[])getAttribute(Geometry.NORMALS); 92 93 93 float[] texCoords = cast(float[])getAttribute(Geometry.TEXCOORDS0); 94 94 int texCoordCount = getVertexBuffer(Geometry.TEXCOORDS0).components; 95 95 assert(texCoords.length/texCoordCount == vertices.length); 96 96 97 98 97 Vec3f[] tan1 = new Vec3f[vertices.length]; 99 Vec3f[] tan2 = new Vec3f[vertices.length]; 100 98 //Vec3f[] tan2 = new Vec3f[vertices.length]; 101 99 Vec3f[] tangents = new Vec3f[vertices.length]; 102 100 103 101 foreach (mesh; meshes) 104 102 foreach (tri; mesh.getTriangles()) 105 { 106 103 { 107 104 Vec3f v1 = vertices[tri.x]; 108 105 Vec3f v2 = vertices[tri.y]; 109 106 Vec3f v3 = vertices[tri.z]; 110 107 111 Vec2f w1 = Vec2f(texCoords[tri.x*texCoordCount..tri.x*texCoordCount+1]); 112 Vec2f w2 = Vec2f(texCoords[tri.y*texCoordCount..tri.y*texCoordCount+1]); 113 Vec2f w3 = Vec2f(texCoords[tri.z*texCoordCount..tri.z*texCoordCount+1]); 108 Vec2f w1, w2, w3; 109 if (texCoordCount==2) 110 { w1 = (cast(Vec2f[])texCoords)[tri.x]; 111 w2 = (cast(Vec2f[])texCoords)[tri.y]; 112 w3 = (cast(Vec2f[])texCoords)[tri.z]; 113 } else if (texCoordCount==3) 114 { w1 = Vec2f((cast(Vec3f[])texCoords)[tri.x].v); 115 w2 = Vec2f((cast(Vec3f[])texCoords)[tri.y].v); 116 w3 = Vec2f((cast(Vec3f[])texCoords)[tri.z].v); 117 } else 118 throw new ResourceException("Texture coordinates must have 2 or 3 components to generate tangent vectors."); 114 119 115 120 float x1 = v2.x - v1.x; … … 139 144 tan1[tri.z] += sdir; 140 145 141 tan2[tri.x] += tdir;142 tan2[tri.y] += tdir;143 tan2[tri.z] += tdir;146 //tan2[tri.x] += tdir; 147 //tan2[tri.y] += tdir; 148 //tan2[tri.z] += tdir; 144 149 } 145 150 … … 149 154 Vec3f t = tan1[i]; 150 155 151 tangents[i] = (t-n * n.dot(t)).normalize(); 152 153 //tangents[i].w = n.cross(t).dot(tan2[i]) < 0 ? -1 : 1; 154 156 tangents[i] = (t-n * n.dot(t)).normalize(); 157 //tangents[i].w = n.cross(t).dot(tan2[i]) < 0 ? -1 : 1; 155 158 } 156 159 delete tan1; 157 delete tan2;160 //delete tan2; 158 161 159 162 return tangents; trunk/src/yage/resource/texture.d
r188 r190 13 13 import yage.core.math.vector; 14 14 import yage.core.object2; 15 import yage.resource.dds; 15 16 import yage.resource.image; 16 17 import yage.resource.manager; … … 135 136 protected char[] source; 136 137 protected Image image; // if not null, the texture will be updated with this image the next time it is used. 138 //protected ubyte[] ddsImageData; 139 protected DDSImageData* ddsImageData; 140 141 142 public char[] ddsFile; 143 144 //public char[] ddsFile; // if not null, a dds texture will be loaded from this file the next time the texture is used. 137 145 Vec2i padding; // padding stores how many pixels of the original texture are unused. 138 146 // e.g. getWidth() returns the used texture + the padding. … … 154 162 this.format = format; 155 163 this.mipmap = mipmap; 156 setImage(new Image(source), format, mipmap, source); 157 } 158 164 165 if (filename[$-4..$]==".dds") 166 { ddsFile = source; 167 ubyte[] contents = ResourceManager.getFile(filename); 168 ddsImageData = loadDDSTextureFile(contents); 169 } 170 else 171 setImage(new Image(source), format, mipmap, source); 172 } 173 174 /// 159 175 this(Image image, Format format=Texture.Format.AUTO, bool mipmap=true, char[] source="", bool padding=false) 160 176 { this.format = format; … … 162 178 setImage(image, format, mipmap, source, padding); 163 179 } 164 180 181 /** 182 * If the texture is loaded from a dds file instead of an image, return the unparsed dds file contents. 183 * Otherwise an empty array is returned. */ 184 DDSImageData* getDDSImageData() 185 { return ddsImageData; 186 } 187 165 188 /// Get / set the Image used by this texture. 166 189 Image getImage() … … 173 196 } 174 197 198 /// 175 199 void setImage(Image image) 176 200 { setImage(image, format, mipmap, source, padding.length2() != 0); 177 } 178 201 } 202 /// ditto 179 203 void setImage(Image image, Format format, bool mipmap=true, char[] source="", bool pad=false) /// ditto 180 204 { assert(image !is null); 181 assert(image.getData() !is null); 205 assert(image.getData() !is null); 206 ddsImageData = null; 207 182 208 this.image = image; 183 209 this.format = format; trunk/src/yage/system/graphics/api/opengl.d
r188 r190 20 20 import yage.gui.surface; 21 21 import yage.gui.style; 22 import yage.resource.dds; 22 23 import yage.resource.geometry; 23 24 import yage.resource.image; … … 648 649 { 649 650 Timer timer = new Timer(true); 651 assert(gpuTexture.getImage() || gpuTexture.ddsFile.length); 650 652 651 653 // Upload new image to graphics card memory 652 654 Image image = gpuTexture.getImage(); 653 assert(image); 654 655 // Convert auto format to a real format based on the image given. 656 Texture.Format format; 657 if (gpuTexture.getFormat() == Texture.Format.AUTO) 658 switch(image.getChannels()) // This will support float formats when we switch to using Image2. 659 { case 1: format = Texture.Format.COMPRESSED_LUMINANCE; break; 660 case 2: format = Texture.Format.COMPRESSED_LUMINANCE_ALPHA; break; 661 case 3: format = Texture.Format.COMPRESSED_RGB; break; 662 case 4: format = Texture.Format.COMPRESSED_RGBA; break; 663 default: throw new ResourceException("Images with more than 4 channels are not supported."); 655 if (image) 656 { 657 // Convert auto format to a real format based on the image given. 658 Texture.Format format; 659 if (gpuTexture.getFormat() == Texture.Format.AUTO) 660 switch(image.getChannels()) // This will support float formats when we switch to using Image2. 661 { case 1: format = Texture.Format.COMPRESSED_LUMINANCE; break; 662 case 2: format = Texture.Format.COMPRESSED_LUMINANCE_ALPHA; break; 663 case 3: format = Texture.Format.COMPRESSED_RGB; break; 664 case 4: format = Texture.Format.COMPRESSED_RGBA; break; 665 default: throw new ResourceException("Images with more than 4 channels are not supported."); 666 } 667 else if (gpuTexture.getFormat() == Texture.Format.AUTO_UNCOMPRESSED) 668 switch(image.getChannels()) // This will support float formats when we switch to using Image2. 669 { case 1: format = Texture.Format.LUMINANCE8; break; 670 case 2: format = Texture.Format.LUMINANCE8_ALPHA8; break; 671 case 3: format = Texture.Format.RGB8; break; 672 case 4: format = Texture.Format.RGBA8; break; 673 default: throw new ResourceException("Images with more than 4 channels are not supported."); 674 } 675 676 // Convert from Texture.Format to OpenGL format constants. 677 uint[Texture.Format] glFormatMap = [ 678 Texture.Format.COMPRESSED_LUMINANCE : GL_LUMINANCE, 679 Texture.Format.COMPRESSED_LUMINANCE_ALPHA : GL_LUMINANCE_ALPHA, 680 Texture.Format.COMPRESSED_RGB : GL_RGB, 681 Texture.Format.COMPRESSED_RGBA : GL_RGBA, 682 Texture.Format.LUMINANCE8 : GL_LUMINANCE, 683 Texture.Format.LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA, 684 Texture.Format.RGB8 : GL_RGB, 685 Texture.Format.RGBA8 : GL_RGBA, 686 ]; 687 uint[Texture.Format] glInternalFormatMap = [ 688 Texture.Format.COMPRESSED_LUMINANCE : GL_COMPRESSED_LUMINANCE, 689 Texture.Format.COMPRESSED_LUMINANCE_ALPHA : GL_COMPRESSED_LUMINANCE_ALPHA, 690 Texture.Format.COMPRESSED_RGB : GL_COMPRESSED_RGB, 691 Texture.Format.COMPRESSED_RGBA : GL_COMPRESSED_RGBA, 692 Texture.Format.LUMINANCE8 : GL_LUMINANCE, 693 Texture.Format.LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA, 694 Texture.Format.RGB8 : GL_RGB, 695 Texture.Format.RGBA8 : GL_RGBA, 696 ]; 697 uint glFormat = glFormatMap[format]; 698 uint glInternalFormat = glInternalFormatMap[format]; 699 700 701 gpuTexture.width = image.getWidth(); 702 gpuTexture.height = image.getHeight(); 703 704 uint max = Probe.feature(Probe.Feature.MAX_TEXTURE_SIZE); 705 uint new_width = image.getWidth(); 706 uint new_height= image.getHeight(); 707 708 // Ensure power of two sized if required 709 if (!Probe.feature(Probe.Feature.NON_2_TEXTURE)) 710 { 711 if (log2(new_height) != floor(log2(new_height))) 712 new_height = nextPow2(new_height); 713 if (log2(new_width) != floor(log2(new_width))) 714 new_width = nextPow2(new_width); 715 716 // Resize if necessary 717 if (new_width != gpuTexture.width || new_height != gpuTexture.height) 718 image = image.resize(min(new_width, max), min(new_height, max)); 664 719 } 665 else if (gpuTexture.getFormat() == Texture.Format.AUTO_UNCOMPRESSED) 666 switch(image.getChannels()) // This will support float formats when we switch to using Image2. 667 { case 1: format = Texture.Format.LUMINANCE8; break; 668 case 2: format = Texture.Format.LUMINANCE8_ALPHA8; break; 669 case 3: format = Texture.Format.RGB8; break; 670 case 4: format = Texture.Format.RGBA8; break; 671 default: throw new ResourceException("Images with more than 4 channels are not supported."); 720 721 // Build mipmaps (doing it ourself is several times faster than gluBuild2DMipmaps, 722 int level = 0; 723 while(true) { 724 glTexImage2D(GL_TEXTURE_2D, level, glInternalFormat, image.getWidth(), image.getHeight(), 0, glFormat, GL_UNSIGNED_BYTE, image.getData().ptr); 725 level++; 726 727 if (!gpuTexture.mipmap || image.getWidth() <= 4 || image.getHeight() <= 4) 728 break; 729 730 image = image.resize(image.getWidth()/2, image.getHeight()/2); 731 672 732 } 673 674 // Convert from Texture.Format to OpenGL format constants. 675 uint[Texture.Format] glFormatMap = [ 676 Texture.Format.COMPRESSED_LUMINANCE : GL_LUMINANCE, 677 Texture.Format.COMPRESSED_LUMINANCE_ALPHA : GL_LUMINANCE_ALPHA, 678 Texture.Format.COMPRESSED_RGB : GL_RGB, 679 Texture.Format.COMPRESSED_RGBA : GL_RGBA, 680 Texture.Format.LUMINANCE8 : GL_LUMINANCE, 681 Texture.Format.LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA, 682 Texture.Format.RGB8 : GL_RGB, 683 Texture.Format.RGBA8 : GL_RGBA, 684 ]; 685 uint[Texture.Format] glInternalFormatMap = [ 686 Texture.Format.COMPRESSED_LUMINANCE : GL_COMPRESSED_LUMINANCE, 687 Texture.Format.COMPRESSED_LUMINANCE_ALPHA : GL_COMPRESSED_LUMINANCE_ALPHA, 688 Texture.Format.COMPRESSED_RGB : GL_COMPRESSED_RGB, 689 Texture.Format.COMPRESSED_RGBA : GL_COMPRESSED_RGBA, 690 Texture.Format.LUMINANCE8 : GL_LUMINANCE, 691 Texture.Format.LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA, 692 Texture.Format.RGB8 : GL_RGB, 693 Texture.Format.RGBA8 : GL_RGBA, 694 ]; 695 uint glFormat = glFormatMap[format]; 696 uint glInternalFormat = glInternalFormatMap[format]; 697 698 699 gpuTexture.width = image.getWidth(); 700 gpuTexture.height = image.getHeight(); 701 702 uint max = Probe.feature(Probe.Feature.MAX_TEXTURE_SIZE); 703 uint new_width = image.getWidth(); 704 uint new_height= image.getHeight(); 705 706 // Ensure power of two sized if required 707 if (!Probe.feature(Probe.Feature.NON_2_TEXTURE)) 708 { 709 if (log2(new_height) != floor(log2(new_height))) 710 new_height = nextPow2(new_height); 711 if (log2(new_width) != floor(log2(new_width))) 712 new_width = nextPow2(new_width); 713 714 // Resize if necessary 715 if (new_width != gpuTexture.width || new_height != gpuTexture.height) 716 image = image.resize(min(new_width, max), min(new_height, max)); 717 } 718 719 // Build mipmaps (doing it ourself is several times faster than gluBuild2DMipmaps, 720 int level = 0; 721 while(true) { 722 glTexImage2D(GL_TEXTURE_2D, level, glInternalFormat, image.getWidth(), image.getHeight(), 0, glFormat, GL_UNSIGNED_BYTE, image.getData().ptr); 723 level++; 724 725 if (!gpuTexture.mipmap || image.getWidth() <= 4 || image.getHeight() <= 4) 726 break; 727 728 image = image.resize(image.getWidth()/2, image.getHeight()/2); 729 730 } 731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level-1); 732 733 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level-1); 734 735 } else if (gpuTexture.getDDSImageData() ){ 736 737 // This block is from Bill Baxter's DDS loader, See license in resource/dds.d 738 DDSImageData* ddsData = gpuTexture.getDDSImageData(); 739 if(ddsData) { 740 int nHeight = ddsData.height; 741 int nWidth = ddsData.width; 742 int nNumMipMaps = ddsData.numMipMaps; 743 int nBlockSize; 744 if(ddsData.format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) 745 nBlockSize = 8; 746 else 747 nBlockSize = 16; 748 glGenTextures(1, &info.id); 749 glBindTexture(GL_TEXTURE_2D, info.id); 750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 752 int nSize; 753 int nOffset = 0; 754 // Load the mip-map levels 755 for(int k = 0; k < nNumMipMaps; ++k) { 756 if(nWidth == 0) 757 nWidth = 1; 758 if(nHeight == 0) 759 nHeight = 1; 760 nSize = ((nWidth + 3) / 4) * ((nHeight + 3) / 4) * nBlockSize; 761 glCompressedTexImage2DARB(GL_TEXTURE_2D, k, ddsData.format, nWidth, nHeight, 0, nSize, &ddsData.pixels[0] + nOffset); 762 nOffset += nSize; 763 // Half the image size for the next mip-map level... 764 nWidth = (nWidth / 2); 765 nHeight = (nHeight / 2); 766 } 767 } 768 // end resource/dds.d license 769 } 733 770 gpuTexture.dirty = false; 734 771 gpuTexture.flipped = false; trunk/src/yage/system/graphics/probe.d
r187 r190 20 20 { 21 21 private static char[] extensions; // return value from glGetString(GL_EXTENSIONS) 22 private static int fbo=-1, shader=-1, vbo=-1, mt=-1, np2=-1 ; // so lookup only has to occur once.22 private static int fbo=-1, shader=-1, vbo=-1, mt=-1, np2=-1, textureCompression=-1; // so lookup only has to occur once. 23 23 24 24 /** … … 27 27 { MAX_LIGHTS, /// Maximum number of lights that can be used at one time (isn't this always 8?) 28 28 MAX_TEXTURE_SIZE, /// Maximum allowed size for a texture 29 MAX_TEXTURE_UNITS, /// Maximum number of textures that can be used in multitexturing 29 MAX_TEXTURE_UNITS, /// Maximum number of textures that can be used in multitexturing 30 30 31 31 FBO, /// Hardware support for rendering directly to a texture (Frame Buffer Object); first available in GeForce FX and Radeon 9x00 32 32 MULTITEXTURE, /// Hardware support for using multiple textures in a single rendering pass; first available on Voodoo2? 33 TEXTURE_COMPRESSION, 33 34 NON_2_TEXTURE, /// Hardware support for textures of arbitrary size; first available in GeForce FX and Radeon 9500 34 35 SHADER, /// Hardware support for openGl vertex and fragment shaders; first available in GeForce FX and Radeon 9x00 … … 82 83 mt = cast(int)checkExtension("GL_ARB_multitexture"); 83 84 return mt; 85 case Feature.TEXTURE_COMPRESSION: 86 if (textureCompression==-1) 87 textureCompression = cast(int)checkExtension("GL_ARB_texture_compression"); 88 return textureCompression; 84 89 case Feature.NON_2_TEXTURE: 85 90 if (np2==-1) trunk/src/yage/system/window.d
r187 r190 153 153 SDL_EnableUNICODE(1); 154 154 SDL_EnableKeyRepeat(1, 100); 155 155 156 156 // Attempt to load multitexturing 157 157 if (Probe.feature(Probe.Feature.MULTITEXTURE)) … … 159 159 throw new YageException("GL_ARB_multitexture extension detected but it could not be loaded."); 160 160 Log.info("GL_ARB_multitexture support enabled."); 161 }else 162 Log.info("GL_ARB_multitexture not supported. This is ok, but graphical quality may be limited."); 163 164 // Texture Compression 165 if (Probe.feature(Probe.Feature.TEXTURE_COMPRESSION)) 166 { if (!ARBTextureCompression.load("GL_ARB_texture_compression")) 167 throw new YageException("GL_ARB_texture_compression extension detected but it could not be loaded."); 168 Log.info("GL_ARB_texture_compression support enabled."); 161 169 }else 162 170 Log.info("GL_ARB_multitexture not supported. This is ok, but graphical quality may be limited.");
