Changeset 8411:864984bbafc2 in orange


Ignore:
Timestamp:
07/21/11 17:14:52 (3 years ago)
Author:
matejd <matejd@…>
Branch:
default
Convert:
920613d268d4c3af94458ab65bba3fc5b3e80e68
Message:

owplot3d: ported to windows, a few optimizations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/owplot3d.py

    r8404 r8411  
    1 """ 
     1""" 
    22    .. class:: OWPlot3D 
    33        Base class for 3D plots. 
     
    4646 
    4747import OpenGL 
    48 #OpenGL.ERROR_CHECKING = True 
    49 #OpenGL.ERROR_LOGGING = True 
    50 #OpenGL.FULL_LOGGING = True 
     48OpenGL.ERROR_CHECKING = False # Turned off for performance improvement. 
     49OpenGL.ERROR_LOGGING = False 
     50OpenGL.FULL_LOGGING = False 
    5151from OpenGL.GL import * 
    5252from OpenGL.GLU import * 
    5353from OpenGL.arrays import ArrayDatatype 
    54 from ctypes import byref, c_char_p, c_int, create_string_buffer, c_ubyte 
     54from OpenGL.GL.ARB.vertex_array_object import * 
     55from OpenGL.GL.ARB.vertex_buffer_object import * 
     56from ctypes import c_void_p 
     57#OpenGL.ERROR_ON_COPY = True  # TODO: enable this to check for unwanted copying (wrappers) 
     58 
    5559import sys 
     60from math import sin, cos, pi 
     61import struct 
    5662import numpy 
    57 from math import sin, cos, pi 
    5863 
    5964try: 
     
    6166except: 
    6267    pass 
    63  
    64 # Import undefined functions, override some wrappers. 
    65 try: 
    66     from OpenGL import platform 
    67     gl = platform.OpenGL 
    68 except ImportError: 
    69     try: 
    70         gl = cdll.LoadLibrary('libGL.so') 
    71     except OSError: 
    72         from ctypes.util import find_library 
    73         path = find_library('OpenGL') 
    74         gl = cdll.LoadLibrary(path) 
    75  
    76 glCreateProgram = gl.glCreateProgram 
    77 glCreateShader = gl.glCreateShader 
    78 glShaderSource = gl.glShaderSource 
    79 glCompileShader = gl.glCompileShader 
    80 glGetShaderiv = gl.glGetShaderiv 
    81 glDeleteShader = gl.glDeleteShader 
    82 glDeleteProgram = gl.glDeleteProgram 
    83 glGetShaderInfoLog = gl.glGetShaderInfoLog 
    84 glGenVertexArrays = gl.glGenVertexArrays 
    85 glBindVertexArray = gl.glBindVertexArray 
    86 glGenBuffers = gl.glGenBuffers 
    87 glDeleteBuffers = gl.glDeleteBuffers 
    88 glVertexAttribPointer = gl.glVertexAttribPointer 
    89 glEnableVertexAttribArray = gl.glEnableVertexAttribArray 
    90 glVertexAttribPointer = gl.glVertexAttribPointer 
    91 glEnableVertexAttribArray = gl.glEnableVertexAttribArray 
    92 glGetProgramiv = gl.glGetProgramiv 
    93 glDrawElements = gl.glDrawElements 
    94 glDrawArrays = gl.glDrawArrays 
    95 glBindBuffer = gl.glBindBuffer 
    96 glBufferData = gl.glBufferData 
    97 glReadPixels = gl.glReadPixels 
    9868 
    9969def normalize(vec): 
     
    310280        QtOpenGL.QGLWidget.__init__(self, QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers), parent) 
    311281 
     282        self.activateZooming = lambda: None 
     283 
    312284        self.commands = [] 
    313285        self.minx = self.miny = self.minz = 0 
     
    353325        self.face_symbols = True 
    354326        self.filled_symbols = True 
    355         self.symbol_scale = 1 
     327        self.symbol_scale = 1. 
    356328        self.transparency = 255 
    357329        self.grid = True 
     
    378350 
    379351    def __del__(self): 
    380         # TODO: delete shaders and vertex buffer 
    381         glDeleteProgram(self.symbol_shader) 
     352        # TODO: check if anything needs deleting 
     353        pass 
    382354 
    383355    def initializeGL(self): 
     
    389361        glDisable(GL_CULL_FACE) 
    390362 
    391         self.symbol_shader = glCreateProgram() 
    392         vertex_shader = glCreateShader(GL_VERTEX_SHADER) 
    393         fragment_shader = glCreateShader(GL_FRAGMENT_SHADER) 
    394         self.shaders = [vertex_shader, fragment_shader] 
    395  
     363        self.symbol_shader = QtOpenGL.QGLShaderProgram() 
    396364        vertex_shader_source = ''' 
    397365            attribute vec4 position; 
     
    466434            ''' 
    467435 
    468         vertex_shader_source = c_char_p(vertex_shader_source) 
    469         fragment_shader_source = c_char_p(fragment_shader_source) 
    470  
    471         def print_log(shader): 
    472             length = c_int() 
    473             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length)) 
    474  
    475             if length.value > 0: 
    476                 log = create_string_buffer(length.value) 
    477                 glGetShaderInfoLog(shader, length, byref(length), log) 
    478                 print(log.value) 
    479  
    480         length = c_int(-1) 
    481         for shader, source in zip([vertex_shader, fragment_shader], 
    482                                   [vertex_shader_source, fragment_shader_source]): 
    483             glShaderSource(shader, 1, byref(source), byref(length)) 
    484             glCompileShader(shader) 
    485             status = c_int() 
    486             glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status)) 
    487             if not status.value: 
    488                 print_log(shader) 
    489                 glDeleteShader(shader) 
    490                 return 
    491             else: 
    492                 glAttachShader(self.symbol_shader, shader) 
    493  
    494         glBindAttribLocation(self.symbol_shader, 0, 'position') 
    495         glBindAttribLocation(self.symbol_shader, 1, 'offset') 
    496         glBindAttribLocation(self.symbol_shader, 2, 'color') 
    497         glLinkProgram(self.symbol_shader) 
    498         self.symbol_shader_face_symbols = glGetUniformLocation(self.symbol_shader, 'face_symbols') 
    499         self.symbol_shader_symbol_scale = glGetUniformLocation(self.symbol_shader, 'symbol_scale') 
    500         self.symbol_shader_transparency = glGetUniformLocation(self.symbol_shader, 'transparency') 
    501         self.symbol_shader_scale        = glGetUniformLocation(self.symbol_shader, 'scale') 
    502         self.symbol_shader_translation  = glGetUniformLocation(self.symbol_shader, 'translation') 
    503         self.symbol_shader_tooltip_mode = glGetUniformLocation(self.symbol_shader, 'tooltip_mode') 
    504         linked = c_int() 
    505         glGetProgramiv(self.symbol_shader, GL_LINK_STATUS, byref(linked)) 
    506         if not linked.value: 
    507             print('Failed to link shader!') 
     436        self.symbol_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Vertex, vertex_shader_source) 
     437        self.symbol_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Fragment, fragment_shader_source) 
     438 
     439        self.symbol_shader.bindAttributeLocation('position', 0) 
     440        self.symbol_shader.bindAttributeLocation('offset',   1) 
     441        self.symbol_shader.bindAttributeLocation('color',    2) 
     442 
     443        if not self.symbol_shader.link(): 
     444            print('Failed to link symbol shader!') 
    508445        else: 
    509             print('Shaders compiled and linked.') 
    510  
    511         self.tooltip_fbo = QtOpenGL.QGLFramebufferObject(512, 512) 
     446            print('Symbol shader linked.') 
     447        self.symbol_shader_face_symbols = self.symbol_shader.uniformLocation('face_symbols') 
     448        self.symbol_shader_symbol_scale = self.symbol_shader.uniformLocation('symbol_scale') 
     449        self.symbol_shader_transparency = self.symbol_shader.uniformLocation('transparency') 
     450        self.symbol_shader_scale        = self.symbol_shader.uniformLocation('scale') 
     451        self.symbol_shader_translation  = self.symbol_shader.uniformLocation('translation') 
     452        self.symbol_shader_tooltip_mode = self.symbol_shader.uniformLocation('tooltip_mode') 
     453 
     454        # TODO: map mouse coordinates properly (instead of using larger FBO) 
     455        self.tooltip_fbo = QtOpenGL.QGLFramebufferObject(1024, 1024) 
    512456        if self.tooltip_fbo.isValid(): 
    513457            print('Tooltip FBO created.') 
     
    550494        for (cmd, params) in self.commands: 
    551495            if cmd == 'scatter': 
    552                 vao, vao_outline, (X, Y, Z), labels = params 
    553                 glUseProgram(self.symbol_shader) 
    554                 glUniform1i(self.symbol_shader_tooltip_mode, False) 
    555                 glUniform1i(self.symbol_shader_face_symbols, self.face_symbols) 
    556                 glUniform1f(self.symbol_shader_symbol_scale, self.symbol_scale) 
    557                 glUniform1f(self.symbol_shader_transparency, self.transparency) 
     496                vao_id, outline_vao_id, (X, Y, Z), labels = params 
    558497                scale = numpy.maximum([0, 0, 0], self.scale + self.additional_scale) 
    559                 glUniform3f(self.symbol_shader_scale,        *scale) 
     498 
     499                self.symbol_shader.bind() 
     500                self.symbol_shader.setUniformValue(self.symbol_shader_tooltip_mode, False) 
     501                self.symbol_shader.setUniformValue(self.symbol_shader_face_symbols, self.face_symbols) 
     502                # TODO: line below crashes this thing on windows (weird stuff!) 
     503                self.symbol_shader.setUniformValue(self.symbol_shader_symbol_scale, self.symbol_scale) 
     504                self.symbol_shader.setUniformValue(self.symbol_shader_transparency, self.transparency) 
     505                self.symbol_shader.setUniformValue(self.symbol_shader_scale,        *scale) 
    560506 
    561507                if self.filled_symbols: 
    562                     glBindVertexArray(vao.value) 
    563                     glDrawArrays(GL_TRIANGLES, 0, vao.num_vertices) 
     508                    glBindVertexArray(vao_id) 
     509                    glDrawArrays(GL_TRIANGLES, 0, vao_id.num_vertices) 
    564510 
    565511                    self.tooltip_fbo.bind() 
     
    567513                    glClear(GL_COLOR_BUFFER_BIT) 
    568514                    glDisable(GL_BLEND) 
    569                     glUniform1i(self.symbol_shader_tooltip_mode, True) 
    570                     glDrawArrays(GL_TRIANGLES, 0, vao.num_vertices) 
     515                    self.symbol_shader.setUniformValue(self.symbol_shader_tooltip_mode, True) 
     516                    glDrawArrays(GL_TRIANGLES, 0, vao_id.num_vertices) 
    571517                    self.tooltip_fbo.release() 
    572518 
    573519                    glBindVertexArray(0) 
    574520                else: 
    575                     glBindVertexArray(vao_outline.value) 
    576                     glDrawElements(GL_LINES, vao_outline.num_indices, GL_UNSIGNED_INT, 0) 
     521                    glBindVertexArray(outline_vao_id) 
     522                    glDrawElements(GL_LINES, outline_vao_id.num_indices, GL_UNSIGNED_INT, 0) 
    577523                    glBindVertexArray(0) 
    578                 glUseProgram(0) 
     524                self.symbol_shader.release() 
    579525 
    580526                if labels != None: 
     
    895841 
    896842        # Build Vertex Buffer + Vertex Array Object. 
    897         vao = c_int() 
    898         glGenVertexArrays(1, byref(vao)) 
    899         glBindVertexArray(vao.value) 
    900  
    901         vertex_buffer = c_int() 
    902         glGenBuffers(1, byref(vertex_buffer)) 
    903         glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.value) 
     843        vao_id = GLuint(0) 
     844        glGenVertexArrays(1, vao_id) 
     845        glBindVertexArray(vao_id) 
     846 
     847        vertex_buffer_id = glGenBuffers(1) 
     848        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id) 
    904849 
    905850        vertex_size = (4+3+4)*4 
    906         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertex_size, 0) 
    907         glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, 4*4) 
    908         glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, vertex_size, 7*4) 
     851        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(0)) 
     852        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(4*4)) 
     853        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(7*4)) 
    909854        glEnableVertexAttribArray(0) 
    910855        glEnableVertexAttribArray(1) 
     
    913858        # It's important to keep a reference to vertices around, 
    914859        # data uploaded to GPU seem to get corrupted otherwise. 
    915         vertex_buffer.vertices = numpy.array(vertices, 'f') 
    916         glBufferData(GL_ARRAY_BUFFER, 
    917             ArrayDatatype.arrayByteCount(vertex_buffer.vertices), 
    918             ArrayDatatype.voidDataPointer(vertex_buffer.vertices), GL_STATIC_DRAW) 
     860        #vertex_buffer_id.vertices = numpy.array(vertices, 'f') 
     861        glBufferData(GL_ARRAY_BUFFER, numpy.array(vertices, 'f'), GL_STATIC_DRAW) 
     862            #ArrayDatatype.arrayByteCount(vertex_buffer.vertices), 
     863            #ArrayDatatype.voidDataPointer(vertex_buffer.vertices), GL_STATIC_DRAW) 
    919864 
    920865        glBindVertexArray(0) 
     
    924869        # generate another VAO, keep the same vertex buffer, but use an index buffer 
    925870        # this time. 
    926         index_buffer = c_int() 
    927         glGenBuffers(1, byref(index_buffer)) 
    928         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.value) 
    929         index_buffer.indices = numpy.array(outline_indices, 'I') 
    930         glBufferData(GL_ELEMENT_ARRAY_BUFFER, 
    931             ArrayDatatype.arrayByteCount(index_buffer.indices), 
    932             ArrayDatatype.voidDataPointer(index_buffer.indices), GL_STATIC_DRAW) 
    933  
    934         vao_outline = c_int() 
    935         glGenVertexArrays(1, byref(vao_outline)) 
    936         glBindVertexArray(vao_outline.value) 
    937  
    938         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.value) 
    939         glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.value) 
    940         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertex_size, 0) 
    941         glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, 4*4) 
    942         glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, vertex_size, 7*4) 
     871        index_buffer_id = glGenBuffers(1) 
     872        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id) 
     873        #index_buffer.indices = numpy.array(outline_indices, 'I') 
     874        glBufferData(GL_ELEMENT_ARRAY_BUFFER, numpy.array(outline_indices, 'I'), GL_STATIC_DRAW) 
     875            #ArrayDatatype.arrayByteCount(index_buffer.indices), 
     876            #ArrayDatatype.voidDataPointer(index_buffer.indices), GL_STATIC_DRAW) 
     877 
     878        outline_vao_id = GLuint(0) 
     879        glGenVertexArrays(1, outline_vao_id) 
     880        glBindVertexArray(outline_vao_id) 
     881 
     882        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id) 
     883        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id) 
     884        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(0)) 
     885        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(4*4)) 
     886        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(7*4)) 
    943887        glEnableVertexAttribArray(0) 
    944888        glEnableVertexAttribArray(1) 
     
    948892        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) 
    949893        glBindBuffer(GL_ARRAY_BUFFER, 0) 
    950  
    951         vao.num_vertices = len(vertices) / (vertex_size / 4) 
    952         vao_outline.num_indices = vao.num_vertices * 2 / 3 
    953         self.vertex_buffers.append(vertex_buffer) 
    954         self.index_buffers.append(index_buffer) 
    955         self.vaos.append(vao) 
    956         self.vaos.append(vao_outline) 
    957         self.commands.append(("scatter", [vao, vao_outline, (X,Y,Z), labels])) 
     894         
     895        vao_id.num_vertices = len(vertices) / (vertex_size / 4) 
     896        outline_vao_id.num_indices = vao_id.num_vertices * 2 / 3 
     897        #self.vertex_buffers.append(vertex_buffer) 
     898        #self.index_buffers.append(index_buffer) 
     899        #self.vaos.append(vao) 
     900        #self.vaos.append(vao_outline) 
     901        self.commands.append(("scatter", [vao_id, outline_vao_id, (X,Y,Z), labels])) 
    958902        self.updateGL() 
    959903 
     
    1055999        if self.mouseover_callback != None: 
    10561000            # Use pixel-color-picking to read example index under mouse cursor. 
    1057             value = c_int(-1) 
    10581001            self.tooltip_fbo.bind() 
    1059             glReadPixels(pos.x(), self.height() - pos.y(), 
    1060                          1, 1, 
    1061                          GL_RGBA, 
    1062                          GL_UNSIGNED_BYTE, 
    1063                          byref(value)) 
     1002            value = glReadPixels(pos.x(), self.height() - pos.y(), 
     1003                                 1, 1, 
     1004                                 GL_RGBA, 
     1005                                 GL_UNSIGNED_BYTE) 
    10641006            self.tooltip_fbo.release() 
    1065             if value.value != -1: 
    1066                 self.mouseover_callback(value.value) 
     1007            value = struct.unpack('i', value)[0] 
     1008            if value != -1: 
     1009                self.mouseover_callback(value) 
    10671010 
    10681011        if self.state == PlotState.IDLE: 
Note: See TracChangeset for help on using the changeset viewer.