问题
In part 1 we read the SBM file format successfully, this is part 2 on how to read the KTX file format.
Update: June 25, 2019, the below code to read the ktx file format does work. The file is ktxloader.py Though the code is still a work in progress. Any comments on it would be appreciated.
The code below is a working example to create and modify ktxloader.py
Files required: pattern1.ktx is our KTX file, to be read this program torus_nrms_tc.sbm is our SBM file solved in part1 in a folder called 'shared' in the same directory as the program sbmath.py and from part1 the sbmloader.py from part2, this post: ktxloader.py this is our KTX file format loader.
The source code for the program, sbmktx.py is:
import sys
import time
import os
import math
import ctypes
currentWDir = os.getcwd()
print( 'current working directory: {}'.format( str(currentWDir) ) )
fileDir = os.path.dirname(os.path.abspath(__file__)) # det the directory of this file
print( 'current location of self: {}'.format( str(fileDir) ) )
parentDir = os.path.abspath(os.path.join(fileDir, os.pardir)) # get the parent directory of this file
sys.path.insert(0, parentDir)
print( 'insert system directory: {}'.format( str(parentDir) ) )
os.chdir( fileDir )
baseWDir = os.getcwd()
print( 'changed current working directory: {}'.format( str(baseWDir) ) )
print ( '' )
sys.path.append("./shared")
from sbmloader import SBMObject # location of sbm file format loader
from ktxloader import KTXObject # location of ktx file format loader
from sbmath import m3dDegToRad, m3dRadToDeg, m3dTranslateMatrix44, m3dRotationMatrix44, m3dMultiply, m3dOrtho, m3dPerspective, rotation_matrix, translate
fullscreen = True
import numpy.matlib
import numpy as np
try:
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
#from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
except:
print ('''
ERROR: PyOpenGL not installed properly.
''')
sys.exit()
# Vertex program
vs_source = '''
#version 420 core
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
layout (location = 0) in vec4 position;
layout (location = 4) in vec2 tc;
out VS_OUT
{
vec2 tc;
} vs_out;
void main(void)
{
vec4 pos_vs = mv_matrix * position;
vs_out.tc = tc;
gl_Position = proj_matrix * pos_vs;
}
'''
# Fragment program
fs_source = '''
#version 420 core
layout (binding = 0) uniform sampler2D tex_object;
in VS_OUT
{
vec2 tc;
} fs_in;
out vec4 color;
void main(void)
{
color = texture(tex_object, fs_in.tc * vec2(3.0, 1.0));
}
'''
identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
render_prog = GLuint(0)
uniforms_mv_matrix = (GLfloat * 16)(*identityMatrix)
uniforms_proj_matrix = (GLfloat * 16)(*identityMatrix)
tex_index = 0
tex_object = []
def load_shaders():
global render_prog
global uniforms_mv_matrix
global uniforms_proj_matrix
if (render_prog):
glDeleteProgram(render_prog);
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, fs_source);
glCompileShader(fs);
vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, vs_source);
glCompileShader(vs);
render_prog = glCreateProgram();
glAttachShader(render_prog, vs);
glAttachShader(render_prog, fs);
glLinkProgram(render_prog);
glDeleteShader(vs);
glDeleteShader(fs);
uniforms_mv_matrix = glGetUniformLocation(render_prog, "mv_matrix");
uniforms_proj_matrix = glGetUniformLocation(render_prog, "proj_matrix");
class Scene:
def __init__(self, width, height):
self.width = width
self.height = height
B = (0x00, 0x00, 0x00, 0x00)
W = (0xFF, 0xFF, 0xFF, 0xFF)
tex_data = [
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
B, W, B, W, B, W, B, W, B, W, B, W, B, W, B, W,
W, B, W, B, W, B, W, B, W, B, W, B, W, B, W, B,
]
tex_object.append( glGenTextures(1) )
#glGenTextures(1, tex_object[0]);
glBindTexture(GL_TEXTURE_2D, tex_object[0]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
tex_object.append ( glGenTextures(1) )
ktxobj = KTXObject()
tex_object[1] = ktxobj.ktx_load("pattern1.ktx")
#tex_object[1] = sb7::ktx::file::load("pattern1.ktx");
myobject.load("torus_nrms_tc.sbm");
load_shaders();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
def display(self):
global uniforms_mv_matrix
global uniforms_proj_matrix
currentTime = time.time()
gray = [ 0.2, 0.2, 0.2, 1.0 ];
ones = [ 1.0 ];
glClearBufferfv(GL_COLOR, 0, gray);
glClearBufferfv(GL_DEPTH, 0, ones);
glViewport(0, 0, self.width, self.height);
glBindTexture(GL_TEXTURE_2D, tex_object[tex_index]);
glUseProgram(render_prog);
T = (GLfloat * 16)(*identityMatrix)
RX = (GLfloat * 16)(*identityMatrix)
RY = (GLfloat * 16)(*identityMatrix)
R = (GLfloat * 16)(*identityMatrix)
# other ways to matrix multiply can be found at https://stackoverflow.com/questions/56711138/how-to-read-parse-the-sbm-file-format-from-superbible-opengl
# Matrix multiplication is not commutative, order matters when multiplying matrices
T = np.matrix(translate(0.0, 0.0, -4.0)).reshape(4,4)
RX = np.matrix(rotation_matrix( [1.0, 0.0, 0.0], currentTime * m3dDegToRad(17.0)))
RY = np.matrix(rotation_matrix( [0.0, 1.0, 0.0], currentTime * m3dDegToRad(13.0)))
mv_matrix = RX * RY * T
proj_matrix = (GLfloat * 16)(*identityMatrix)
proj_matrix = m3dPerspective(m3dDegToRad(60.0), float(self.width) / float(self.height), 0.1, 100.0);
glUniformMatrix4fv(uniforms_mv_matrix, 1, GL_FALSE, mv_matrix);
glUniformMatrix4fv(uniforms_proj_matrix, 1, GL_FALSE, proj_matrix);
myobject.render() # renders the torus
glutSwapBuffers()
def reshape(self, width, height):
self.width = width
self.height = height
def keyboard(self, key, x, y ):
global fullscreen
global tex_index
print ('key:' , key)
if key == b'\x1b': # ESC
sys.exit()
elif key == b'f' or key == b'F': #fullscreen toggle
if (fullscreen == True):
glutReshapeWindow(self.width, self.height)
glutPositionWindow(int((1360/2)-(512/2)), int((768/2)-(512/2)))
fullscreen = False
else:
glutFullScreen()
fullscreen = True
elif key == b'r' or key == b'R':
load_shaders()
elif key == b't' or key == b'T':
tex_index+=1
if (tex_index > 1):
tex_index = 0
print('done')
def init(self):
pass
def timer(self, blah):
glutPostRedisplay()
glutTimerFunc( int(1/60), self.timer, 0)
time.sleep(1/20.0)
myobject = SBMObject()
if __name__ == '__main__':
start = time.time()
glutInit()
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(512, 512)
w1 = glutCreateWindow('OpenGL SuperBible - Texture Coordinates')
fullscreen = False
#glutFullScreen()
scene = Scene(512, 512)
glutReshapeFunc(scene.reshape)
glutDisplayFunc(scene.display)
glutKeyboardFunc(scene.keyboard)
glutIdleFunc(scene.display)
#glutTimerFunc( int(1/60), scene.timer, 0)
scene.init()
glutMainLoop()
At this point the program should run, and you should see a torus or donut like the gif here, it rotates and spins and has a checkboard pattern.
When the ktx file complete the result looks like (by pressing 't' on the keyboard to switch textures): it will have a lion spotted like drops pattern.
The KTX File Format Specification are here.
Though I am porting to python the c++ code from here and am following that mostly: sb7ktx.cpp and its header here sb7ktx.h
Here is an example of a ktx file contents:
My question is that by using numpy how can I read the ktx texture file in a similar way to part1 how the sbm file was read, parsed? Any help would be greatly appreciated. Thank You.
来源:https://stackoverflow.com/questions/56749815/how-to-read-in-python-the-ktx-file-format-used-in-the-book-superbible-opengl-pa