Как получить правильную текстуру с помощью индексации в opengl - PullRequest
0 голосов
/ 21 июня 2020

Я хочу создать пирамиду с разной текстурой с каждой стороны. Пирамида с текстурами верна без использования массива данных индекса. Когда я использую indexdata, текстуры смешиваются друг с другом. Мне нужно исправить AttribPointer? (Моя текстура представляет собой коллаж из 5 разных изображений)

* Я хочу сохранить массив indexData

Вот часть кода

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import numpy as np
from framework import *
from PIL import Image
from math import tan, cos, sin

# A 1-D array of 3 4-D vertices (X,Y,Z,W)
# Note that this must be a numpy array, since as of 
# 170111 support for lists has not been implemented.
vertexData = np.array(
    [    0.0, 0.5, -1.3, 1.0, #0
         0.3, 0.0, -1.0, 1.0, #1
        -0.3, 0.0, -1.0, 1.0, #2
        -0.3, 0.0, -1.6, 1.0, #3
         0.3, 0.0, -1.6, 1.0, #4
         0.0, 0.0, -1.3, 1.0, #5
       
   #texture

    0.8, 0.0, 
    1.0, 0.0,
    0.8, 0.4,

    0.0, 0.3,
    0.3, 0.3, 
    0.3, 0.0,

    0.5, 1.0,
    0.5, 0.5, 
    0.6, 1.0,

    0.1, 1.0,
    0.4, 1.0,
    0.0, 0.4, 

    0.0, 0.0,
    0.0, 0.3, 
    0.3, 0.0,

    0.0, 0.0,
    0.0, 0.3,
    0.3, 0.0,

    0.0, 0.0,
    0.0, 0.3, #leukos toixos
    0.3, 0.0,

    0.0, 0.0,
    0.0, 0.3,
    0.3, 0.0,

],
     dtype='float32'
)
indexData = np.array(
    [0,1,2,
     0,2,3,
     0,3,4,
     0,4,1,
     5,2,1,
     5,1,4,
     5,4,3,
     5,3,2],)
    

vertexDim = 4
texcoordDim = 2
nVertices = 8*3

# Global variable to represent the compiled shader program, written in GLSL
theProgram = None

# Global variable to represent the buffer that will hold the position vectors
vertexBufferObject = None

sampleTexture = None
texUnitUniform = None

# Global variables to store the location of the shader's uniform variables
perspectiveMatrixUnif = None
WorldtoCameraMatrixUnif = None

# Global display variables
perspectiveMatrix = None
CameraMatrix = None
fFrustumScale = 1.0

def loadTexture(path):
    img = Image.open(path).transpose(Image.FLIP_TOP_BOTTOM) #anoigoume tin eikona
    #img.show()
    img_data = np.frombuffer(img.tobytes(), np.uint8)
    width, height = img.size

    # glTexImage2D expects the first element of the image data to be the
    # bottom-left corner of the image.  Subsequent elements go left to right,
    # with subsequent lines going from bottom to top.

    # However, the image data was created with PIL Image tostring and numpy's
    # fromstring, which means we have to do a bit of reorganization. The first
    # element in the data output by tostring() will be the top-left corner of
    # the image, with following values going left-to-right and lines going
    # top-to-bottom.  So, we need to flip the vertical coordinate (y). 
    texture = glGenTextures(1)
    #glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glBindTexture(GL_TEXTURE_2D, texture)#ginetai sundesi me to antikeimeno pou ftiaxtike
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)#parametroi gia tin ufi
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)#gia na exw digrammiko filtrarisma
    #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,  GL_RGB, GL_UNSIGNED_BYTE, img_data)#sundesi twn dedomenwn
    #glGenerateMipmap(GL_TEXTURE_2D)
    return texture

# Set up the list of shaders, and call functions to compile them
def initializeProgram():
    shaderList = []
    
    shaderList.append(loadShader(GL_VERTEX_SHADER, "Texture.vert"))
    shaderList.append(loadShader(GL_FRAGMENT_SHADER, "Texture.frag"))
    
    global theProgram 
    theProgram = createProgram(shaderList)
    
    for shader in shaderList:
        glDeleteShader(shader)
    
      
    global perspectiveMatrixUnif
    perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix")

    global WorldtoCameraMatrixUnif
    WorldtoCameraMatrixUnif = glGetUniformLocation(theProgram, "cameraMatrix")

    global sampleTexture
    global texUnitUniform
    
    sampleTexture = loadTexture('pic.jpg')  #i eikona
    texUnitUniform = glGetUniformLocation(theProgram, "texUnit")#gia na vrethei apo ton fragment shader
    
    fzNear = 0.5
    fzFar = 3.0

    global CameraMatrix
    CameraPos=np.array([0.8, 0.8, -1.0])
    CameraTarget=np.array([1.0, 1.0, 0.0])
    CameraUp=np.array([-1.0, 1.0, 0.0])
    
    CameraTarget=CameraTarget/np.linalg.norm(CameraTarget)
    CameraRight=np.cross(CameraUp, CameraTarget)
    CameraRight=CameraRight/np.linalg.norm(CameraRight)
    CameraUp=np.cross(CameraTarget, CameraRight)
    
        
    CameraRotMatrix=np.vstack((CameraRight, CameraUp, CameraTarget,[0.0, 0.0, 0.0]))
    CameraRotMatrix=np.hstack((CameraRotMatrix, [[0.0], [0.0], [0.0], [1.0]]))
    
    CameraTranMatrix=np.eye(4)
    CameraTranMatrix[0][3]=-CameraPos[0]
    CameraTranMatrix[1][3]=-CameraPos[1]
    CameraTranMatrix[2][3]=-CameraPos[2]
    
    CameraMatrix=np.matmul(CameraRotMatrix,CameraTranMatrix)
    
    global perspectiveMatrix
    perspectiveMatrix = np.zeros(16, dtype='float32') 
    perspectiveMatrix[0] = fFrustumScale
    perspectiveMatrix[5] = fFrustumScale
    perspectiveMatrix[10] = (fzFar + fzNear) / (fzNear - fzFar)
    perspectiveMatrix[14] = (2 * fzFar * fzNear) / (fzNear - fzFar)
    perspectiveMatrix[11] = -1.0
    
    glUseProgram(theProgram)
    glActiveTexture(GL_TEXTURE0)#energi tin monada ufis pou me endiaferei
    glBindTexture(GL_TEXTURE_2D, sampleTexture)#sundesi tis ufis me ton stoxo
    glUniform1i(texUnitUniform, 0)#sundesi tis metavlitis me tin monada 0
    
    glUniformMatrix4fv(perspectiveMatrixUnif, 1, GL_FALSE, perspectiveMatrix)
    glUniformMatrix4fv(WorldtoCameraMatrixUnif, 1, GL_TRUE, CameraMatrix)
    glUseProgram(0)

# Set up the vertex buffer that will store our vertex coordinates for OpenGL's access
def initializeVertexBuffer():
    global vertexBufferObject
    vertexBufferObject = glGenBuffers(1)
    
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject)
    glBufferData( # PyOpenGL allows for the omission of the size parameter
        GL_ARRAY_BUFFER,
        vertexData,
        GL_STREAM_DRAW
    )
    glBindBuffer(GL_ARRAY_BUFFER, 0)

    


    indexBufferObject = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject)
    glBufferData(
        GL_ELEMENT_ARRAY_BUFFER,
        indexData,
        GL_STATIC_DRAW
    )
    
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

def computeAngleRad(fElapsedTime, fLoopDuration):
    fScale = 3.14159 * 2.0 / fLoopDuration
    fCurrTimeThroughLoop = fElapsedTime % fLoopDuration
    return fCurrTimeThroughLoop * fScale

def rotateZ(fElapsedTime):
    fAngRad = computeAngleRad(fElapsedTime, 4.0)
    fCos = cos(fAngRad)
    fSin = sin(fAngRad)
    
 









# Initialize the OpenGL environment
def init():
    initializeProgram()
    initializeVertexBuffer()
    glBindVertexArray(glGenVertexArrays(1))
    
    glEnable(GL_CULL_FACE)
    glCullFace(GL_BACK)
    glFrontFace(GL_CW)
    glEnable(GL_DEPTH_TEST)
# Called to update the display. 
# Because we are using double-buffering, glutSwapBuffers is called at the end
# to write the rendered buffer to the display.
def display():
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glUseProgram(theProgram)
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject)
    glEnableVertexAttribArray(0)
    glEnableVertexAttribArray(1)
    glVertexAttribPointer(0, vertexDim, GL_FLOAT, GL_FALSE, 0, None)
    # a ctype void pointer must be used to pass in the offset into the bound GL_ARRAY_BUFFER
    # also note that python's underlying float type is usally 64-bit, but
    # we have specified that our vertex array contains float32 data.
    texcoordOffset = c_void_p(vertexDim*nVertices*4)
    glVertexAttribPointer(1, texcoordDim, GL_FLOAT, GL_FALSE, 0, texcoordOffset)


    fElapsedTime = glutGet(GLUT_ELAPSED_TIME) / 2000.0
    
    
    AngRad = computeAngleRad(fElapsedTime, 2.0)
    
    worldMatrix = np.identity(4, dtype='float32')
    worldMatrix[0][0] = cos(AngRad)
    worldMatrix[0][2] = sin(AngRad)
    worldMatrix[2][0] = -sin(AngRad)
    worldMatrix[2][2] = cos(AngRad)

    matTrans1 = np.identity(4, dtype='float32')
    matTrans1[2][3] = 1.3
    matTrans2 = np.identity(4, dtype='float32')
    matTrans2[2][3] = -1.3
    newTransformA= np.matmul(worldMatrix,matTrans1)
    newTransformB = np.matmul (matTrans2,newTransformA)
    transformMatrix = newTransformB
    glUniformMatrix4fv(WorldtoCameraMatrixUnif, 1, GL_FALSE, transformMatrix.transpose())
    
    
    glDrawArrays(GL_TRIANGLES, 0, nVertices)
    
    glDisableVertexAttribArray(0)
    glDisableVertexAttribArray(1)
    glUseProgram(0)
    
    glutSwapBuffers()
    glutPostRedisplay()

# keyboard input handler: exits the program if 'esc' is pressed
def keyboard(key, x, y):
    if ord(key) == 27: # ord() is needed to get the keycode
        glutLeaveMainLoop()
        return    
    
# Called whenever the window's size changes (including once when the program starts)
def reshape(w, h):
    global perspectiveMatrix
    perspectiveMatrix[0] = fFrustumScale / (w / float(h))
    perspectiveMatrix[5] = fFrustumScale
    
    glUseProgram(theProgram)
    glUniformMatrix4fv(perspectiveMatrixUnif, 1, GL_FALSE, perspectiveMatrix)
    glUseProgram(0)
    
    glViewport(0, 0, w, h)
    
# The main function
def main():
    glutInit()
    displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
    glutInitDisplayMode (displayMode)
    
    width = 500;
    height = 500;
    glutInitWindowSize (width, height)
    
    glutInitWindowPosition (300, 200)
    
    window = glutCreateWindow(b"Tutorial Window")
    
    init()
    glutDisplayFunc(display) 
    glutReshapeFunc(reshape)
    glutKeyboardFunc(keyboard)
    
    glutMainLoop();

if __name__ == '__main__':
    main()
...