如何在IOS Swift OpenglES 1.0/1.1/2.0上绘制文本和图像作为纹理

如何在IOS Swift OpenglES 1.0/1.1/2.0上绘制文本和图像作为纹理,ios,swift,opengl-es,swift2,opengl-es-2.0,Ios,Swift,Opengl Es,Swift2,Opengl Es 2.0,我正在尝试渲染png图像的纹理,并使用OpenglES 1.0在Swift上绘制字符串作为纹理。但我在谷歌上搜索到的所有例子都不起作用。我花了足够多的时间,我需要弄清楚这一点 在屏幕上只显示非纹理的抽屉,我删除了所有基于三角形的抽屉,没有关于相机角度或视图的问题,问题是关于纹理渲染 感谢所有能帮助我的人,这里是我的简化代码,用于将png绘制为纹理,但没有显示任何内容,甚至没有显示白色框 这是渲染器类 import GLKit import SWXMLHash class MapViewContr

我正在尝试渲染png图像的纹理,并使用OpenglES 1.0在Swift上绘制字符串作为纹理。但我在谷歌上搜索到的所有例子都不起作用。我花了足够多的时间,我需要弄清楚这一点

在屏幕上只显示非纹理的抽屉,我删除了所有基于三角形的抽屉,没有关于相机角度或视图的问题,问题是关于纹理渲染

感谢所有能帮助我的人,这里是我的简化代码,用于将png绘制为纹理,但没有显示任何内容,甚至没有显示白色框

这是渲染器类

import GLKit
import SWXMLHash
class MapViewController: GLKViewController {
    @IBOutlet var glView: GLKView!
    var rViewController : UIViewController? = nil
    var context : EAGLContext!
    var ratio : Float!
    var size : Float!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.context = EAGLContext.init(API: EAGLRenderingAPI.OpenGLES1)
        if self.context == nil {
            Util.log("failed to create context for self")
        }
        glView.context = self.context
        EAGLContext.setCurrentContext(self.context)

        glClearColor(0.95, 0.95, 0.95, 0.5)
        glDisable(GLenum(GL_CULL_FACE))
        glEnable(GLenum(GL_DEPTH_TEST))
        glEnable(GLenum(GL_BLEND))
        glBlendFunc(GLenum(GL_SRC_ALPHA), GLenum(GL_ONE_MINUS_SRC_ALPHA))

    }

    override func viewWillLayoutSubviews() {
        if firstInit {
            let width = glView.frame.size.width
            let height = glView.frame.size.height
            glViewport(0, 0, Int32(width), Int32(height))
            let fieldOfView = GLKMathDegreesToRadians(60)
            glEnable(GLenum(GL_NORMALIZE))
            self.ratio = Float(width)/Float(height)
            glMatrixMode(GLenum(GL_PROJECTION))
            glLoadIdentity()
            size = zNear * Float(tan(Double(fieldOfView/2.0)))
            glFrustumf(-size, size, -size / (ratio), size / (ratio), zNear, zFar)
            glMatrixMode(GLenum(GL_MODELVIEW))
            glLoadIdentity()
        }
    }

    override func glkView(view: GLKView, drawInRect rect: CGRect) {
        glPushMatrix()
        glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
        glClear(GLbitfield(GL_DEPTH_BUFFER_BIT))
        glMatrixMode(GLenum(GL_MODELVIEW))
        glLoadIdentity()
        glEnableClientState(GLenum(GL_VERTEX_ARRAY))
        glEnableClientState(GLenum(GL_COLOR_ARRAY))

            glEnable(GLenum(GL_TEXTURE_2D))
            //     glEnable(GLenum(GL_BLEND))
            //     glEnableClientState(GLenum(GL_NORMAL_ARRAY))
            glEnableClientState(GLenum(GL_TEXTURE_COORD_ARRAY))

            let fl = CGPoint(x: 0, y: 0)
            let drawer = IconDrawer(x: 0, y: 0, z: 0, size:150, roomCoords: fl, exampleimage)
            drawer.draw()

            glDisable(GLenum(GL_TEXTURE_2D))
            glDisableClientState(GLenum(GL_TEXTURE_COORD_ARRAY))    

        glDisableClientState(GLenum(GL_VERTEX_ARRAY));
        glDisableClientState(GLenum(GL_COLOR_ARRAY));
        glPopMatrix();
    }
}
这是抽屉类

import Foundation
class IconDrawer : Mesh {
    let normals : [GLfloat] =  [
        0.0, 0.0, 1.0,
        0.0, 0.0, 1.0,
        0.0, 0.0, 1.0,
        0.0, 0.0, 1.0 ]
    let textureCoordinates : [Float] = [0.0, 1.0,
        1.0, 1.0,
        1.0, 0.0,
        0.0, 0.0]
    let indices = [0, 1, 2, 0, 2, 3]

    var coordinates : CGPoint? = nil
    var texture:GLuint=0
    static var currentScreenMid = CGPoint(x: 0, y: 0)

    init(x : Float, y : Float, z : Float, size : Int, roomCoords : CGPoint, imageName : String) {
        super.init()
        // Mapping coordinates for the vertices

        self.coordinates = roomCoords

        let w = Float((size)/1000);
        let h = Float((size)/1000);
        let vertices : [Float] = [-w+x, -h+y, z+Zunit,
            w+x, -h+y, z+Zunit,
            w+x, h+y, z+Zunit,
            -w+x, h+y, z+Zunit]
        setIndices(indices);
        setVertices(vertices);
        setTextureCoordinates(textureCoordinates);

        //PART 1 LOAD PNG

    let image = UIImage(named : imageName)
    let iwidth = CGImageGetWidth(image?.CGImage)
    let iheight = CGImageGetHeight(image?.CGImage)

    let imageData  = malloc(iwidth * iheight * 4)

    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
    let imageContext : CGContextRef = CGBitmapContextCreate(imageData, iwidth, iheight, 8, iwidth * 4, CGColorSpaceCreateDeviceRGB(), bitmapInfo.rawValue)!
    CGContextClearRect(imageContext, CGRectMake(0, 0, CGFloat(iwidth), CGFloat(iheight)))
    CGContextTranslateCTM(imageContext, 0, CGFloat((iheight - iheight)))
    CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, CGFloat(iwidth), CGFloat(iheight)), image?.CGImage)
    glTexImage2D(GLenum(GL_TEXTURE_2D), GLint(0), GL_RGBA, Int32(iwidth), Int32(iheight), GLint(0), GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), imageData)

    self.w = GLsizei(Int(image!.size.width))
    self.h = GLsizei(Int(image!.size.height))

    loadBitmap(imageData)
    fl.bitmaps.append(imageData)

    //PART 2 CREATE TEXTURE WITH THE IMAGE DATA
    glGenTextures(1, &texture)
    glBindTexture(GLenum(GL_TEXTURE_2D), texture)
    glTexImage2D(GLenum(GL_TEXTURE_2D), Int32(0), GL_RGBA, GLsizei(Int(image!.size.width)), GLsizei(Int(image!.size.height)), Int32(0), GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), imageData)

    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GLint(GL_LINEAR))

    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GLint(GL_LINEAR))

    if image != nil {
        let imageRect = CGRectMake(0.0, 0.0, image!.size.width, image!.size.height);
        UIGraphicsBeginImageContextWithOptions(image!.size, false, UIScreen.mainScreen().scale)
        image?.drawInRect(imageRect)
        UIGraphicsEndImageContext();
    }


}

override func draw() {

    //PART 3 RENDER
    glEnableClientState(GLenum(GL_VERTEX_ARRAY));
    glEnableClientState(GLenum(GL_NORMAL_ARRAY));
    glEnableClientState(GLenum(GL_TEXTURE_COORD_ARRAY));
    glEnable(UInt32(GL_TEXTURE_2D));
    glEnable(UInt32(GL_BLEND));
    glBlendFunc(UInt32(GL_SRC_ALPHA), UInt32(GL_ONE_MINUS_SRC_ALPHA));

    Drawer.printGLErrors()
    glBindTexture(GLenum(GL_TEXTURE_2D), texture)
    Drawer.printGLErrors()
    glVertexPointer(Int32(2), GLenum(GL_FLOAT), GLsizei(0), self.mVerticesBuffer!)
    Drawer.printGLErrors()
    glNormalPointer(GLenum(GL_FLOAT), GLsizei(0), normals)
    Drawer.printGLErrors()
    glTexCoordPointer(Int32(2), GLenum(GL_FLOAT), GLsizei(0), textureCoordinates)
    Drawer.printGLErrors()
    glDrawArrays(GLenum(GL_TRIANGLE_STRIP), 0, 4)
    Drawer.printGLErrors()

}

}

您面临的问题是,不支持开箱即用的非POT(二次幂)纹理。我相信有一些扩展,但我不会为此烦恼

无论如何,纹理尺寸必须是POT(2、4、8、16…),因此您有两个选项可以选择。您可以在获取原始图像数据指针时创建一个POT上下文,并将图像调整为所需的POT大小,从而在过程中缩放图像。更常见的方法是使用空数据指针创建足够大的纹理,然后使用带有原始图像大小参数的
glTexSubImage
将数据发送到纹理。此过程还要求您更改纹理坐标,以便使用与高度相同的
imageWidth/textureWidth
,而不是1.0。第二个过程需要更多的努力,但通常用于升级到纹理图集过程(将多个图像放在同一纹理上)


同样,最快的程序是简单地在Photoshop中调整图像大小,例如128x128。注:罐尺寸不必相同,128x64也应有效。

如果不使用图像名称,图像名称是什么?你到底看到了什么?你能看到清晰的颜色吗?如果禁用纹理,你能看到基本体吗?很抱歉,当我试图删除不相关的线时,由于一个错误,我删除了它,现在编辑。是的,基于三角形的渲染器工作得非常完美,我甚至使用了缩放、拖动、旋转等等。除了纹理,一切都正常。好的,但是当你画纹理的时候,你看不到任何东西,甚至没有一些黑色区域?如果是,请尝试禁用混合。如果这将生成黑色形状,则由于某种原因,纹理数据为空(0,0,0,0)将生成透明像素,因为当前混合模式设置中没有可见的内容。因此,如果是这种情况,首先检查图像是否存在,是否正确,原始图像数据是否有意义。我尝试了,但仍然没有,我可能错过了一些东西,我在android上使用了类似的方法,但在IOS参考上提到了帧缓冲区的使用,但这是一个OpenGLES 2.0参考。我的Android和IOS代码都在1.0上,它是在Android上完成的,除了纹理,所有东西都在IOS上工作(如果你愿意给我发送项目,你可以在我的个人资料页面上找到我的电子邮件,我会查看一下。从你在这里提供的数据和你得到的结果来看,除了继续在黑暗中拍摄并希望解决问题外,很难做任何事情。谢谢你,我刚刚呈现了我的第一个iOS纹理,多亏了你,还有很长的路要走。)选择应用程序。:)