我尝试做一个简单的渲染,从TIFF图像加载数据到numpy矩阵,并制作一个3D纹理。TIFF图像是强度图像,我希望将这个强度图像重新Map为亮度或alpha颜色图像。
虽然我认为我理解GL_Texture_3D的过程,但运行代码时没有任何错误,我仍然没有获得任何视觉结果。我肯定是做了一些简单的非常错误的事情。有人能帮助我理解我的错误吗?
这是代码的简短版本[corrected]:
**编辑2:尝试正确的类型转换:**正如Reto Koradi所建议的,我可能面临着一个类型转换问题。所以我将numpy数组转换为uint8,确保值不全为零,并将其传递给channel_RGBA_buffer uint8数组。仍然会产生一个黑色窗口。
**编辑3:使用Glumpy方法:**阅读Glumpy(https://code.google.com/p/glumpy/source/browse/glumpy/image/texture.py?r=8cbc2aa2b277c07b59fba964edd327370a8e8091)的函数“textures”我将目标GL格式GL_RGBA更改为GL_RGBA16,并在调用glTexImage3D后添加了glBindTexture(GL_TEXTURE_3D,0)。仍然不确定为什么是0而不是纹理。
编辑4:修复了2行的缩进,使示例可执行
结果仍然是一个黑色的窗口,但当关闭这个窗口,一瞬间,我看到的数据出现。似乎我把一个额外的层。
import sys
import numpy
from OpenGL.GL import *
from OpenGL.GL.shaders import *
from OpenGL.arrays import vbo
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GLUT.freeglut import *
class test_TIFF_render:
def __init__(self):
self.something = True
def load_texture(self):
global texture
#read file as array, for simplicity I will just make a random numpy 3D matrix
tiff_mean = numpy.random.rand(3,300,300)
tiff_mean = tiff_mean*1000
tiff_mean = tiff_mean.astype('uint8')
shape_array = tiff_mean.shape
shape_array = tiff_mean.shape
#we have the data now, let's set the texture
tiff_mean = tiff_mean.reshape(tiff_mean.shape[1]*tiff_mean.shape[2]*tiff_mean.shape[0])
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_3D,texture)
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,GL_CLAMP_TO_BORDER)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
#now we need to convert the intensity data organized in 3D matrix into an RGBA buffer array (pixel1R, pixel1G, pixel1B, pixel1A, pixel2R....)
channel_RGBA_buffer = numpy.zeros(tiff_mean.shape[0]*4, numpy.uint8)
for i in range(0,tiff_mean.shape[0]):
channel_RGBA_buffer[i*4] = tiff_mean[i] #R
channel_RGBA_buffer[i*4+1] = tiff_mean[i] #G
channel_RGBA_buffer[i*4+2] = tiff_mean[i] #B
channel_RGBA_buffer[i*4+3] = tiff_mean[i] #A
if numpy.mod(i,100000)==0:
print('count %d',i)
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16, shape_array[1], shape_array[2], shape_array[0], 0, GL_RGBA, GL_UNSIGNED_BYTE, channel_RGBA_buffer)
glBindTexture( GL_TEXTURE_3D, 0 )
def display(self):
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glEnable( GL_ALPHA_TEST )
glAlphaFunc( GL_GREATER, 0.03)
glEnable(GL_BLEND)
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
glMatrixMode( GL_TEXTURE )
glLoadIdentity()
glEnable(GL_TEXTURE_3D);
glBindTexture( GL_TEXTURE_3D, texture);
dOrthoSize = 1
for Indx in self.my_range(-1,1,0.01):
TexIndex = round(Indx,2)
glBegin(GL_QUADS)
glTexCoord3f(0.0, 0.0, (TexIndex+1.0)/2.0)
glVertex3f(-dOrthoSize,-dOrthoSize,TexIndex)
glTexCoord3f(1.0, 0.0, (TexIndex+1.0)/2.0)
glVertex3f(dOrthoSize,-dOrthoSize,TexIndex)
glTexCoord3f(1.0, 1.0, (TexIndex+1.0)/2.0)
glVertex3f(dOrthoSize,dOrthoSize,TexIndex)
glTexCoord3f(0.0, 1.0, (TexIndex+1.0)/2.0)
glVertex3f(-dOrthoSize,dOrthoSize,TexIndex);
glEnd()
glBindTexture( GL_TEXTURE_3D, texture )
def my_range(self,start, end, step):
while start <= end:
yield start
start += step
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(300,300)
window = glutCreateWindow(b"I really hope this works")
test111 = test_TIFF_render()
test111.load_texture()
glutDisplayFunc(test111.display)
glutMainLoop()
我运行的是64位Win7和Python3.3。
1条答案
按热度按时间kjthegm61#
我没有使用过numpy,但是我读过文档(http://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html),默认情况下
numpy.zeros()
生成一个float64
值的数组,然后将GL_INT
作为glTexImage3D()
的类型参数传递,看起来这里有一个类型不匹配。用于纹理数据的典型数据类型是unsigned bytes。所以我认为它应该看起来像这样:
编辑,更新新版本代码:它看起来像是生成0.0到1.0之间的随机浮点值,并将它们转换为字节(
uint8
)值,然后将其用于纹理数据。我相信这将导致所有字节值为0,或者可能部分为1,这取决于舍入的工作方式。但是字节范围的值是0-255。您可能希望乘以255。将随机浮点转换为纹理数据时为0: