[PyQt] max texture size for QGLWidget.bindTexture?
Brian Parma
freecode at cox.net
Wed Sep 10 02:11:47 BST 2008
David Boddie wrote:
> On Tue Sep 9 00:28:49 BST 2008, Brian Parma wrote:
>
>
>> Thanks for the response, that's a good find, although I'm trying to
>> figure out how to interpret the result. On my laptop it returns 2048,
>> but how does that translate into resolution? I thought it was memory
>> size at first, but changing formats from RGB8 to RGB4 doesn't let me use
>> larger textures. Right now I take a screen cap which is 1024 x 768, and
>> I then scale it down with QPixmap.scaledToWidth. I've been playing with
>> the width to try and find the limit, and it seems to be between 650 and
>> 700 pixels wide.
>>
>
> OK, so it won't even show the full width of 1024 pixels? It sounds like it
> isn't just a problem with the texture not having dimensions that aren't a
> power of 2 because 1024 would obviously be fine.
>
> I would imagine that this is an OpenGL problem rather than a Qt problem, but
> you would have to try using native/Python arrays rather than a QPixmap to
> test that theory. It might be worth creating a small test program that
> illustrates this problem and posting on the PyOpenGL mailing list:
>
> http://sourceforge.net/mail/?group_id=5988
>
> It could be the case that your hardware/driver has problems with textures
> larger than a certain size, even though it claims to support them. Can you
> say what platform, hardware and driver you are using?
>
> David
> _______________________________________________
> PyQt mailing list PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
> ------------------------------------------------------------------------
Ok, so I stripped down the program a little to make it into something of
a demonstration of the problem.
I'm running this on an Asus s5n laptop with XP Pro (SP3). The graphics
controller is an "Intel 82852/82855 GM/GME" 6.14.10.3865. (yea it's a
little old)
PyQt 4.4.3, PyOpenGL 3.0.0b5
I haven't tried using OpenGL's texture loading functions, I'm not real
experienced with OpenGL programming (this is my first gl program) so I
have just been using PyQt4's QGLWidget's bindTexture, and passing it a
QPixmap.scaled.
In the program, I made it so pressing 'S' will prompt for a new width to
scale too, entering 640 works fine, but anything above that causes the
weird behavior (on this computer). What is really strange is that
scaling the image to 641 looks the same as scaling it to 1024, and it
doesn't change again until you scale over 1024.
-------------- next part --------------
from __future__ import division
from PyQt4.QtCore import QPointF, QRectF, SIGNAL, Qt, QTimer, QPoint
from PyQt4.QtGui import QWidget, QApplication, QPushButton, QPainter, QPixmap, QColor, QImage, QInputDialog
from PyQt4.QtOpenGL import QGLWidget
from OpenGL.GL import *
from OpenGL.GLU import gluPerspective
import sys
class testGL(QGLWidget):
DIR_RIGHT, DIR_UP, DIR_LEFT, DIR_DOWN = 0, 1, 2, 3
MODE_SLIDE, MODE_SPIN = 0, 1
coords = (( ( -1, +1, +1 ), ( -1, -1, +1 ), ( +1, -1, +1 ), ( +1, +1, +1 ) ),
( ( +1, +1, +1 ), ( +1, -1, +1 ), ( +1, -1, -1 ), ( +1, +1, -1 ) ),
( ( +1, +1, -1 ), ( +1, -1, -1 ), ( -1, -1, -1 ), ( -1, +1, -1 ) ),
( ( -1, +1, -1 ), ( -1, -1, -1 ), ( -1, -1, +1 ), ( -1, +1, +1 ) ),
( ( -1, +1, -1 ), ( -1, +1, +1 ), ( +1, +1, +1 ), ( +1, +1, -1 ) ),
( ( -1, -1, +1 ), ( -1, -1, -1 ), ( +1, -1, -1 ), ( +1, -1, +1 ) ),
( ( -1, +1, 0 ), ( -1, -1, 0 ), ( +1, -1, 0 ), ( +1, +1, 0) ),)
tcoords = ((0, 1), (0, 0), (1, 0), (1, 1))
def __init__(self, parent, shared, style, cb=None):
QGLWidget.__init__(self, parent, shared, style)
self.textures = [0, 0, 0, 0, 0, 0, 0]
self.RM = None
self.dx, self.dy, self.dz = 0, 0, 0
self.ang = 4 / 16.0
self.glists = []
self.mode = testGL.MODE_SPIN
self.h, self.w = 1, 1
self.sc = 1.0 # scale
self.ortho = False
self.callback = cb
def translate(self, dx, dy, dz=0):
self.dx = (self.dx + dx/self.w*2*self.sc)
self.dy = (self.dy + dy/self.h*2*self.sc)
self.dz = (self.dz + dz/self.h*2*self.sc)
self.updateGL()
def rotate(self, dx, dy):
dx = dx*self.ang
dy = dy*self.ang
glLoadIdentity()
glRotatef(dx, 0.0, 1.0, 0.0)
glRotatef(dy, 1.0, 0.0, 0.0)
glMultMatrixf(self.RM)
self.RM = glGetFloatv(GL_MODELVIEW_MATRIX)
self.updateGL()
def initializeGL(self):
glEnable(GL_TEXTURE_2D)
glEnable(GL_CULL_FACE)
glEnable(GL_DEPTH_TEST)
self.context().setTextureCacheLimit(131072) # 128 megs
print glGetIntegerv(GL_MAX_TEXTURE_SIZE)
sc = self.sc
glLoadIdentity()
self.RM = glGetFloatv(GL_MODELVIEW_MATRIX)
lst = glGenLists(2)
self.glist = [lst, lst+1]
# list 1
glNewList(self.glist[0], GL_COMPILE)
glBegin(GL_QUADS)
dz = ((0, 0), (-2, 0), (2, 0), (0, -2), (0, 2))
for i in range(5):
for j in range(4):
glTexCoord2d(self.tcoords[j][0], self.tcoords[j][1])
glVertex3d(sc*(self.coords[0][j][0] + dz[i][0]),
sc*(self.coords[0][j][1] + dz[i][1]), sc*self.coords[0][j][2])
glEnd()
glEndList()
# list 2
#sc = 1.0
glNewList(self.glist[1], GL_COMPILE)
glBegin(GL_QUADS)
for i in range(6):
for j in range(4):
glTexCoord2d(self.tcoords[j][0], self.tcoords[j][1])
glVertex3d(sc*self.coords[i][j][0],
sc*self.coords[i][j][1], sc*self.coords[i][j][2])
glEnd()
glEndList()
def paintGL(self):
# self.qglClearColor(QColor('white'))
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
# Object
glPushMatrix()
if self.textures[0]:
glBindTexture(GL_TEXTURE_2D, self.textures[0])
glTranslated(0.0, 0.0, -1.0 - 2.0*self.sc) # put into view
glTranslated(self.dx, self.dy,self.dz)
glMultMatrixf(self.RM) # Rotation
glCallList(self.glist[self.mode])
glPopMatrix()
def resizeGL(self, width, height):
self.w, self.h = width, height
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
sc = self.sc
r = width/height
if self.ortho:
glOrtho(-sc*r, +sc*r, -sc, +sc, -50, 50)
else:
gluPerspective(53.13, r, 1.0, 100.0)
glMatrixMode(GL_MODELVIEW)
def mousePressEvent(self, event):
self.cpos = QPointF(event.pos())
self.button = event.button()
def mouseMoveEvent(self, event):
dx = event.x() - self.cpos.x()
dy = event.y() - self.cpos.y()
if self.button == Qt.RightButton:
self.translate(dx, -dy)
elif self.button == Qt.MidButton:
self.translate(0, 0, -dy)
else:
self.rotate(dx, dy)
self.cpos = QPointF(event.pos())
def keyPressEvent(self, event):
if (event.key() == Qt.Key_Escape) or (event.key() == Qt.Key_Q):
self.close()
if event.key() == Qt.Key_T: # toggle mode
if self.mode == testGL.MODE_SLIDE:
self.mode = testGL.MODE_SPIN
else:
self.mode = testGL.MODE_SLIDE
self.updateGL()
if event.key() == Qt.Key_V: # toggle ortho
self.ortho = not self.ortho
self.resizeGL(self.w,self.h)
self.updateGL()
if event.key() == Qt.Key_R: # reset position
glLoadIdentity()
self.RM = glGetFloatv(GL_MODELVIEW_MATRIX)
self.dx,self.dy,self.dz = 0,0,0
self.updateGL()
if event.key() == Qt.Key_S: # rescale
sz,ok = QInputDialog.getInteger(self,"Input Width","Width:",640,10,5000,1)
if ok:
print 'resize to w: %d' % sz
self.callback(sz)
self.updateGL()
class test:
def __init__(self):
self.pix = testGL(None, None, Qt.FramelessWindowHint, self.getScreen)
self.pix.resize(600, 400)
self.pix.move(QPoint(0, 0))
self.pix.show()
self.getScreen()
def getScreen(self, sz=640):
self.pm = QPixmap.grabWindow(QApplication.desktop().winId())
if self.pix.textures[0]:
self.pix.deleteTexture(self.pix.textures[0])
self.pix.textures[0] = self.pix.bindTexture(self.pm.scaledToWidth(sz,Qt.FastTransformation),GL_TEXTURE_2D,GL_RGB8)
if __name__ == '__main__':
app = QApplication(sys.argv)
tc = test()
app.exec_()
More information about the PyQt
mailing list