in initializeGL
in QGLWidget
:
I'm loading a .exr
image (128mb) 4000x2000 with imageio.imread
from imageio import imread
img_array = imread("c:/sample.exr")
self.textureID = glGenTextures(1)
in paintGL
in QGLWidget
:
I draw my single quad with glBegin(GL_QUADS)
and glEnd()
then feed the texture into glTexImage2D
and bind it to the quad I created earlier.
glBindTexture(GL_TEXTURE_2D, self.textureID)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 1920, 1080, 0, GL_RGBA, GL_FLOAT, img_array)
I don't have any problem with loading the image or code itself, everything works perfectly, but I'm facing performance issue and navigating the scene starts to lag, I assume is because of the huge size of image.
Is there any way that I can reduce the size? or increase the performance of it?
Note: Even the image is numpy.float32
I only display it as GL_RGBA
which means there is 0.4545 gamma multiplication, I don't know if that affects the performance but thought to point it out.
Thanks in advance.
Update:
here is the code:
import os
from PySide.QtGui import QColor
from PySide.QtOpenGL import QGLWidget
from imageio import imread
from OpenGL.GL import *
from OpenGL.GLU import *
from engine.nodes import (ImageNode, NodeType, CubeNode, Vector3)
class QImageProcessor(QGLWidget):
def __init__(self, parent=None):
super(QImageProcessor, self).__init__(parent)
self.model = list()
self.zoomVal = 1.2
self.local_translate = (0.0, 0.0, 0.0)
self.local_scale = (1.0, 1.0, 1.0)
self.xRot = 0
self.yRot = 0
self.zRot = 0
def initializeGL(self):
self.qglClearColor(QColor.fromCmykF(0.0, 0.1, 0.0, 0.882))
glViewport( 0, 0, self.width(), self.height())
glEnable(GL_TEXTURE_2D)
glEnable(GL_CULL_FACE)
glEnable(GL_MULTISAMPLE)
glEnable(GL_LINE_SMOOTH, GL_LINE_WIDTH, GL_ALIASED_LINE_WIDTH_RANGE)
glShadeModel(GL_FLAT)
glEnable(GL_DEPTH_TEST)
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
glDepthRange (0.1, 1.0)
# adding images
image1 = "c:/sample.exr"
new_image1 = ImageNode(image1)
new_image1.TextureID = glGenTextures(1)
new_image1.Data = imread(image1, format='.exr')
self.model.append(new_image1)
image2 = "c:/sample2.jpg"
new_image2 = ImageNode(image2)
new_image2.TextureID = glGenTextures(1)
new_image2.Data = imread(image2, format='.jpg')
self.model.append(new_image2)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluOrtho2D(-self.zoomVal, +self.zoomVal, -self.zoomVal, +self.zoomVal)
glLoadIdentity()
glTranslated(*self.local_translate)
glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
glScalef(*self.local_scale)
genList = glGenLists(1)
glNewList(genList, GL_COMPILE)
for node in self.model:
vertices = node.Vertices # list of vertices
edges = node.Edges # list of edges
face = node.Face # list of faces
texcoords = node.TextureCoordinates # list of texture coordinates
glPushAttrib(GL_ALL_ATTRIB_BITS)
glPolygonMode(GL_FRONT, GL_FILL)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D, node.TextureID)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, node.InternalFormat, node.Width, node.Height, 0, node.Format, node.Type, node.Data)
# face and UV
glBegin(GL_QUADS)
self.qglColor(QColor(255,255,255))
for vertex in face:
glVertex3fv(vertices[vertex])
glTexCoord2f(texcoords[vertex][0], texcoords[vertex][1])
glEnd()
glPopAttrib()
glEndList()
glCallList(genList)
I tried this:
I moved glTexCoord2f
to initializeGL
function, bind it once and then bind it to 0:
image2 = "c:/sample2.jpg"
new_image2 = ImageNode(image2)
new_image2.TextureID = glGenTextures(1)
new_image2.Data = imread(image2, format='.jpg')
glTexImage2D(GL_TEXTURE_2D, 0, new_image2.InternalFormat, new_image2.Width, new_image2.Height, 0, new_image2.Format, new_image2.Type, new_image2.Data)
glBindTexture(GL_TEXTURE_2D, new_image2.TextureID)
glBindTexture(GL_TEXTURE_2D, 0)
self.model.append(new_image2)
and then in paintGL
bind it again,
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
gluOrtho2D(-self.zoomVal, +self.zoomVal, -self.zoomVal, +self.zoomVal)
glLoadIdentity()
glTranslated(*self.local_translate)
glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
glScalef(*self.local_scale)
genList = glGenLists(1)
glNewList(genList, GL_COMPILE)
for node in self.model:
vertices = node.Vertices # list of vertices
edges = node.Edges # list of edges
face = node.Face # list of faces
texcoords = node.TextureCoordinates # list of texture coordinates
glPushAttrib(GL_ALL_ATTRIB_BITS)
glPolygonMode(GL_FRONT, GL_FILL)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D, node.TextureID)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
# face and UV
glBegin(GL_QUADS)
self.qglColor(QColor(255,255,255))
for vertex in face:
glVertex3fv(vertices[vertex])
glTexCoord2f(texcoords[vertex][0], texcoords[vertex][1])
glEnd()
glPopAttrib()
glEndList()
glCallList(genList)
but it didn't show the texture, not sure if I'm missing something.