Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有人能一步一步地解释这个代码吗?_Java_2d_Textures_Symbols - Fatal编程技术网

Java 有人能一步一步地解释这个代码吗?

Java 有人能一步一步地解释这个代码吗?,java,2d,textures,symbols,Java,2d,Textures,Symbols,我有点理解它在做什么,但是下面提供的代码中的步骤背后的逻辑是什么?这是在LWJGL中加载纹理的一种方法。但是for循环中发生了什么?难道你不把x和y相乘得到一个像素的位置吗?任何关于从for循环到代码结尾的解释都是有帮助的,因为当它到达for循环时,注释是模糊的。当把像素信息放入缓冲区时,我不理解奇怪的符号 public class TextureLoader { private static final int BYTES_PER_PIXEL = 4;//3 for RGB, 4 for R

我有点理解它在做什么,但是下面提供的代码中的步骤背后的逻辑是什么?这是在LWJGL中加载纹理的一种方法。但是for循环中发生了什么?难道你不把x和y相乘得到一个像素的位置吗?任何关于从for循环到代码结尾的解释都是有帮助的,因为当它到达for循环时,注释是模糊的。当把像素信息放入缓冲区时,我不理解奇怪的符号

public class TextureLoader { 
private static final int BYTES_PER_PIXEL = 4;//3 for RGB, 4 for RGBA 
   public static int loadTexture(BufferedImage image){ 

      int[] pixels = new int[image.getWidth() * image.getHeight()]; 
        image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); 

        ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB 

        for(int y = 0; y < image.getHeight(); y++){ 
            for(int x = 0; x < image.getWidth(); x++){ 
                int pixel = pixels[y * image.getWidth() + x]; 
                buffer.put((byte) ((pixel >> 16) & 0xFF));     // Red component 
                buffer.put((byte) ((pixel >> 8) & 0xFF));      // Green component 
                buffer.put((byte) (pixel & 0xFF));               // Blue component 
                buffer.put((byte) ((pixel >> 24) & 0xFF));    // Alpha component. Only for RGBA 
            } 
        } 

        buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS 

        // You now have a ByteBuffer filled with the color data of each pixel. 
        // Now just create a texture ID and bind it. Then you can load it using  
        // whatever OpenGL method you want, for example: 

      int textureID = glGenTextures(); //Generate texture ID 
        glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID 

        //Setup wrap mode 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); 

        //Setup texture scaling filtering 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

        //Send texel data to OpenGL 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 

        //Return the texture ID so we can bind it later again 
      return textureID; 
   } 

   public static BufferedImage loadImage(String loc) 
   { 
        try { 
           return ImageIO.read(DefenseStep.class.getResource(loc)); 
        } catch (IOException e) { 
            //Error Handling Here 
        } 
       return null; 
   } 
公共类TextureLoader{
私有静态最终整数字节每像素=4;//3表示RGB,4表示RGBA
公共静态int loadTexture(BuffereImage图像){
int[]像素=新的int[image.getWidth()*image.getHeight()];
getRGB(0,0,image.getWidth(),image.getHeight(),pixels,0,image.getWidth());
ByteBuffer buffer=BufferUtils.createByteBuffer(image.getWidth()*image.getHeight()*字节/像素);//4表示RGBA,3表示RGB
对于(int y=0;y>16)&0xFF));//红色分量
buffer.put((字节)((像素>>8)&0xFF));//绿色组件
buffer.put((字节)(pixel&0xFF));//蓝色组件
buffer.put((字节)((像素>>24)&0xFF));//Alpha组件。仅适用于RGBA
} 
} 
buffer.flip();//看在上帝的份上,别忘了这一点
//现在您有了一个ByteBuffer,其中填充了每个像素的颜色数据。
//现在只需创建一个纹理ID并绑定它,然后就可以使用
//您想要的任何OpenGL方法,例如:
int textureID=glGenTextures();//生成纹理ID
glBindTexture(GL_TEXTURE_2D,textureID);//绑定纹理ID
//设置换行模式
glTexParameteri(GL_纹理2D、GL_纹理包裹S、GL12.GL_夹紧到边);
glTexParameteri(GL_纹理2D、GL_纹理包裹T、GL12.GL_夹紧到边);
//设置纹理缩放过滤
glTexParameteri(GL\u纹理\u 2D,GL\u纹理\u最小\u过滤器,GL\u最近);
glTexParameteri(GL_纹理2D,GL_纹理MAG_过滤器,GL_最近);
//将texel数据发送到OpenGL
GLTEXAGE2D(GL_纹理_2D,0,GL_RGBA8,image.getWidth(),image.getHeight(),0,GL_RGBA,GL_无符号字节,缓冲区);
//返回纹理ID,以便稍后再次绑定
返回纹理ID;
} 
公共静态缓冲区映像加载映像(字符串位置)
{ 
试试{
返回ImageIO.read(DefenseStep.class.getResource(loc));
}捕获(IOE){
//这里的错误处理
} 
返回null;
} 

}每个像素由一个32位整数表示。该整数最左边的八位是它的alpha分量,后跟红色、绿色和蓝色

(pixel>>16)&0xFF
将整数16位向右移位,因此其中最右边的8位现在是红色分量。然后,它使用位掩码将所有其他位设置为零,因此只剩下红色分量。同样的逻辑也适用于其他组件


它所做的只是将图像中的颜色逐像素加载到缓冲区中

这段代码使用Java中的按位运算符来实现。看这个

当您看到
>
时,这意味着“将该数字的二进制向右移位”,当您看到
num>>n
时,这意味着“将
num
的二进制值
n
位向右移位。例如:

System.out.println(4 >> 2); // Prints "1"
这将打印
1
,因为二进制中的4是
0100
,当右移2位时,将得到
0001
,即十进制中的1

现在,也就是说,图像中的颜色是用ARGB表示的。这意味着图像中每32位有8位专用于A、R、G和B(alpha、红色、绿色和蓝色),因此其十六进制形式如下所示:

0xAARRGGBB
0 1 2
3 4 5
6 7 8
其中每个字母都是十六进制数字

您发布的代码使用二进制逻辑检索
AA
RR
等的每组。每组正好是一个字节或8位,因此这就是8、16和24的来源。
&
对这两个数字执行逐位逻辑
,其中两个数字中只有1位的位置保持为1,并且每一个o位置变为0

作为一个具体的例子,让我们从ARGB中的purple中检索
RR
字节

在ARGB中,黄色是
A=255
R=127
G=0
,和
B=127
,因此我们的十六进制版本是:

0xAARRGGBB
0xFF7F007F
查看十六进制值,我们看到
RR
是从末尾算起的第三个字节。要在ARGB值位于变量中时获取
RR
,首先将其放入
int pixel

int pixel = 0xFF7F007F;
注意与代码的相似性。像素矩阵中的每个
int
都是ARGB颜色

接下来,我们将数字右移2个字节,因此
RR
是最低的字节,这给了我们:

0x0000AARR
0x0000FF7F
这是通过以下代码完成的:

int intermediate = pixel >> 16;
这里的
16
来自这样一个事实,我们想右移2个字节,每个字节包含8位。
运算符需要位,所以我们必须给它16位,而不是2位

接下来,我们想去掉
AA
,但保留
RR
。要做到这一点,我们使用所谓的位掩码和
&
运算符。位掩码用于挑出二进制数的特定位。这里,我们想要
0xFF
。这正是二进制中的八个1。(十六进制的每个
F
都是二进制的
1111
。)

请容忍我,因为这看起来很难看。当我们执行
int red=intermediate&0xFF
时,它所做的(二进制)是:

0 1 2
3 4 5
6 7 8
Coord. -> Index
---------------
(0, 0) -> 0
(1, 0) -> 1
(2, 0) -> 2
(0, 1) -> 3
(1, 1) -> 4
(2, 1) -> 5
(0, 2) -> 6
(1, 2) -> 7
(2, 2) -> 8
Coord. -> Index
-------------------
(0, 0) -> 0 * 0 = 0
(1, 0) -> 1 * 0 = 0
(2, 0) -> 2 * 0 = 0
(0, 1) -> 0 * 1 = 0
(1, 1) -> 1 * 1 = 1
(2, 1) -> 2 * 1 = 2
(0, 2) -> 0 * 2 = 0
(1, 2) -> 1 * 2 = 2
(2, 2) -> 2 * 2 = 4
Coord. -> Index
-----------------------
(0, 0) -> 0 + 0 * 3 = 0
(1, 0) -> 1 + 0 * 3 = 1
(2, 0) -> 2 + 0 * 3 = 2
(0, 1) -> 0 + 1 * 3 = 3
(1, 1) -> 1 + 1 * 3 = 4
(2, 1) -> 2 + 1 * 3 = 5
(0, 2) -> 0 + 2 * 3 = 6
(1, 2) -> 1 + 2 * 3 = 7
(2, 2) -> 2 + 2 * 3 = 8