Wenn Sie ein Add-On für Blender schreiben, möchten Sie hier häufig Bilder verwenden. Ich denke, dort ist. Wenn Sie OpenGL (bgl) von Blender verwenden, können Sie es anzeigen. Probieren Sie es also aus.
Es gibt zwei Möglichkeiten, das Bild zu lesen, also werde ich jede schreiben.
bpy.data.images.load ()gl_texture_test.py
# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# Blender2.77a
import bpy
import bgl
image_file_path = "C:/Works/blender_rogo.png "
class GL_Texture():
    def __init__(self, file_path):
        self.image = None
        self.width = 0
        self.height = 0
        
        self.load_image(file_path)
    
    def load_image(self, file_path):
        try:
            self.image = bpy.data.images.load(file_path)
        except Exception as e:
            print(e)
        
        if self.image:
            self.width, self.height = self.image.size
            self.image.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
    
    def remove(self):
        if self.image:
            try:
                self.image.user_clear()
                self.image.gl_free()
                #self.image.buffers_free()
                bpy.data.images.remove(self.image)
            except Exception as e:
                print(e)
    
    def bind(self):
        if self.image.bindcode[0]:
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.image.bindcode[0])
        else:
            self.image.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
            print("reload gl texture")
class GL_Texture_test_Operator(bpy.types.Operator):
    bl_idname = "view3d.gl_texture_test_operator"
    bl_label = "View3D GL_Texture draw test"
    
    _handle_draw = None
    is_enabled = False
    _my_texture = None
    
    @staticmethod
    def draw_callback_px(self, context):
        bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
        bgl.glEnable(bgl.GL_BLEND)
        bgl.glEnable(bgl.GL_TEXTURE_2D)
        
        tex = GL_Texture_test_Operator._my_texture
        w = tex.width
        h =tex.height
        tex.bind()
        bgl.glBegin(bgl.GL_QUADS)
        bgl.glTexCoord2f(0.0, 0.0)
        bgl.glVertex2f(0.0, 0.0)
        bgl.glTexCoord2f(1.0, 0.0)
        bgl.glVertex2f(0.0+w, 0.0)
        bgl.glTexCoord2f(1.0, 1.0)
        bgl.glVertex2f(0.0+w, 0.0+h)
        bgl.glTexCoord2f(0.0, 1.0)
        bgl.glVertex2f(0.0, 0.0+h)
        bgl.glEnd()
        
        bgl.glDisable(bgl.GL_TEXTURE_2D)
        bgl.glDisable(bgl.GL_BLEND)
    
    @staticmethod
    def handle_add(self, context):
        GL_Texture_test_Operator._handle_draw = bpy.types.SpaceView3D.draw_handler_add(
                self.draw_callback_px, (self, context), 'WINDOW', 'POST_PIXEL')
    
    @staticmethod
    def handle_remove():
        if GL_Texture_test_Operator._handle_draw is not None:
            bpy.types.SpaceView3D.draw_handler_remove(GL_Texture_test_Operator._handle_draw, 'WINDOW')
            GL_Texture_test_Operator._handle_draw = None
            GL_Texture_test_Operator.is_enabled = False
    
    @classmethod
    def poll(cls, context):
        return context.area.type == 'VIEW_3D'
    
    def modal(self, context, event):
        if context.area:
            context.area.tag_redraw()
        return {'PASS_THROUGH'}
    
    def invoke(self, context, event):
        if context.area.type == 'VIEW_3D':
            if GL_Texture_test_Operator.is_enabled:
                self.cancel(context)
                return {'FINISHED'}
            else:
                GL_Texture_test_Operator._my_texture = GL_Texture(image_file_path)
                GL_Texture_test_Operator.handle_add(self, context)
                GL_Texture_test_Operator.is_enabled = True
                
                context.area.tag_redraw()
                context.window_manager.modal_handler_add(self)
                return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}
    
    def cancel(self, context):
        GL_Texture_test_Operator.handle_remove()
        
        if GL_Texture_test_Operator._my_texture is not None:
            GL_Texture_test_Operator._my_texture.remove()
            GL_Texture_test_Operator._my_texture = None
class GL_Texture_test_panel(bpy.types.Panel):
    bl_label = "GL Texture test"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    
    def draw(self, context):
        layout = self.layout
        if GL_Texture_test_Operator.is_enabled:
            layout.operator("view3d.gl_texture_test_operator", "Stop", icon="PAUSE")
        else:
            layout.operator("view3d.gl_texture_test_operator", "Start", icon="PLAY")
def register():
    bpy.utils.register_class(GL_Texture_test_Operator)
    bpy.utils.register_class(GL_Texture_test_panel)
def unregister():
    bpy.utils.unregister_class(GL_Texture_test_panel)
    bpy.utils.unregister_class(GL_Texture_test_Operator)
if __name__ == "__main__":
    register()
Kopieren Sie es, fügen Sie es in den Texteditor von Blender ein und führen Sie es aus. Geben Sie oben für image_file_path den Pfad des tatsächlich verwendeten Bildes ein.
Ich habe das Blender-Logo entsprechend gezeichnet.
Verwenden Sie diese Option, damit das Bild angezeigt wird. Wenn Sie kein passendes Bild haben, verwenden Sie es bitte.
Wenn Sie es ausführen, wird zuerst eine Schaltfläche im Eigenschaftenfenster angezeigt. Drücken Sie also darauf.

Dann

Die Pfadprüfung der zu verwendenden Bilddatei entfällt. Sie sollten es überprüfen, wenn Sie es tatsächlich verwenden.
self.image.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
Ich denke, dass die Bilddaten in den Speicher von OpenGL gesendet werden.
Ich denke, die beiden Argumente rechts sind die Speichermethode beim Skalieren.
self.image.bindcode[0]
Die Textur-ID wird hier nach gl_load () eingegeben.
Es war vorher keine Liste, aber aus irgendeinem Grund wurde sie in eine Liste geändert.
Ich weiß nicht, welche Daten außer 0 enthalten sind.
def bind(self):
    if self.image.bindcode[0]:
        bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.image.bindcode[0])
    else:
        self.image.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
        print("reload gl texture")
Für diesen Teil wird der Texturspeicher einige Minuten nach seiner Ausführung automatisch freigegeben, sodass die Textur erneut geladen wird. Blender scheint den Speicher von selbst freizugeben.
Der Zeichnungsteil ist derselbe wie OpenGL.
»Es ist sowieso einfach.

gl_load () ausführen.Schreiben Sie die GL_Texture-Klasse aus dem obigen Beispiel neu und führen Sie sie aus.
GL_Texturklasse
class GL_Texture():
    def __init__(self, file_path):
        self.texture_id = 0
        self.width = 0
        self.height = 0
        
        self.load_8bit_bitmap(file_path)
    
    def load_8bit_bitmap(self, file_path):
        f = None
        bitmap_data = None
        gl_buffer = None
        
        try:
            f = open(file_path, 'rb')
            file_header = f.read(14)
            info_header = f.read(40)
            self.width = struct.unpack("<i", info_header[4:8])[0]
            self.height = struct.unpack("<i", info_header[8:12])[0]
            
            palette = []
            for i in range(256):
                rgbr = f.read(4)
                palette.append(struct.unpack("BBBB", rgbr)[0:3])
            
            gl_buffer = bgl.Buffer(bgl.GL_BYTE, self.width*self.height*4)
            for i in range(self.width*self.height):
                data = f.read(1)
                index = struct.unpack("B", data)[0]
                bgr = palette[index]
                gl_buffer[i*4] = bgr[2]
                gl_buffer[i*4+1] = bgr[1]
                gl_buffer[i*4+2] = bgr[0]
                
                if index == 0:
                    gl_buffer[i*4+3] = 0
                else:
                    gl_buffer[i*4+3] = 255
            
            f.close()
        except Exception as e:
            if f is not None:
                f.close()
            print(e)
            return False
            
        # set opengl
        textures = bgl.Buffer(bgl.GL_INT, 1)
        bgl.glGenTextures(1, textures)
        self.texture_id = textures[0]
        
        bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture_id)
        
        bgl.glPixelStorei(bgl.GL_UNPACK_ALIGNMENT, 4)
        bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA,
                self.width, self.height, 0, bgl.GL_RGBA,
                bgl.GL_UNSIGNED_BYTE, gl_buffer)
        
        bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST)
        bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST)
        
    def remove(self):
        if self.texture_id:
            textures = bgl.Buffer(bgl.GL_INT, 1)
            textures[0] = self.texture_id
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
            bgl.glDeleteTextures(1, textures)
            self.texture_id = 0
    
    def bind(self):
        bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture_id)
Hinweis. Es können nur Bitmap-Dateien im 8-Bit-Format geladen werden. Index 0 ist transparent. Es scheint, dass Sie die Bitmap-Datei nicht hochladen können. Bereiten Sie sie daher bitte selbst vor.
Es geht darum, eine Datei zu öffnen, in einem Puffer zu erweitern und in OpenGL zu registrieren.
Wenn Sie in bgl einen Puffer als Argument übergeben möchten, müssen Sie die Buffer-Klasse verwenden. Ich denke, das ist der Unterschied zu gewöhnlichem OpenGL.
Da der Dateiprüfungsprozess weggelassen wird, überprüfen Sie bitte verschiedene Dinge, wenn Sie ihn tatsächlich verwenden.
Persönlich empfehle ich die Verwendung von "bpy.data.images.load ()", da dies immer einfacher ist. Es wird schnell geladen. Die Bilddatei wird auch während der Ausführung in Blender geladen. Selbst wenn Sie sie so speichern, wie sie ist, wird sie nicht gespeichert, wenn die Anzahl der Benutzer 0 beträgt, sodass Sie sich keine Sorgen machen müssen.
Recommended Posts