繁体   English   中英

编程生成OpenGL纹理并将其应用到OpenGL视图

[英]Progmatically generating and applying an OpenGL texture to a OpenGL View

好的,所以我一直在尝试解决这个问题,我设法在OpenGLView上创建了子类,并绘制了一些形状(正方形,三角形),并让它们更改了颜色等。

现在,我正在尝试找出如何加载纹理数据并进行渲染的方法,但是我有点迷失了。

这是我尝试使用的代码,它似乎没有加载任何纹理,我最终得到一个白色框。 我应该相信可以创建黑白棋盘格效果,但是我似乎无法使其正常工作。

这是代码,不胜感激!

#import "MyOpenGLView.h"
#import <OpenGL/gl.h>

@implementation MyOpenGLView

static void drawAnObject ()


{
    glEnable(GL_TEXTURE_2D);

    GLuint tex;

    glGenTextures(1, &tex);

    glBindTexture(GL_TEXTURE_2D, tex);

    glPixelStorei(GL_UNPACK_ALIGNMENT, tex);


    // Black/white checkerboard
    float pixels[] = {
        0.0f, 0.0f, 0.0f,   1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,   0.0f, 0.0f, 0.0f
    };

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    float color[] = { 1.0f, 0.0f, 0.0f, 1.0f };

    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0.1, 0.1, 0, GL_RGB, GL_FLOAT, pixels);


    glBindTexture (GL_TEXTURE_2D, tex);

    glBegin (GL_QUADS);
    glTexCoord2f (0.0, 0.0);
    glVertex3f (0.0, 0.0, 0.0);
    glTexCoord2f (1.0, 0.0);
    glVertex3f (10.0, 0.0, 0.0);
    glTexCoord2f (1.0, 1.0);
    glVertex3f (10.0, 10.0, 0.0);
    glTexCoord2f (0.0, 1.0);
    glVertex3f (0.0, 10.0, 0.0);
    glEnd ();



}

-(void)awakeFromNib
{
    renderTimer = [NSTimer timerWithTimeInterval:0.001   //a 1ms time interval
                                      target:self
                                    selector:@selector(timerFired:)
                                    userInfo:nil
                                     repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:renderTimer
                             forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:renderTimer
                             forMode:NSEventTrackingRunLoopMode]; //Ensure timer fires during resize
}

// Timer callback method
- (void)timerFired:(id)sender
{

     [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)dirtyRect {
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    drawAnObject();
    glFlush();
    GLint swapInterval = 1;
    [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];


    CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
}

原版的

我正在寻找针对OS X的Cocoa应用程序,其中我有一个矩形(大约500px x 500px),我需要在25fps左右更改每个像素的颜色。

每个像素的颜色值将存储在NSDictionary中,可以在渲染每个像素时从中读取。

从最基本的意义上讲,我可以将正在绘制的View子类化,并覆盖drawRect方法。 但是,我随后需要每秒调用25次,并且我怀疑这要求太多了,而且会陷入困境,它也不保证渲染将在正确的时间进行。

Soi认为我需要使用Core Graphics或OpenGL在较低的级别上执行此操作,但是这些都是我以前没有花很多时间的大量主题。 因此,在我深入研究其中一个之前,是否有正确的方向指示?

线

 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0.1, 0.1, 0, GL_RGB, GL_FLOAT, pixels); 

没有按照您的想象做。 widthheight参数的类型为GLsizei ,它是一个整数类型-您应该在此处设置纹理的像素尺寸 将其设置为0.1 ,它将隐式转换为整数并最终为0。显然,此处应将2和2用于2 x 2纹理。

调用glPixelStorei(GL_UNPACK_ALIGNMENT, tex); 现在,根本没有任何意义,因为tex只是GL实现随机分配的某个数字(或多或少),并且您不需要将解压缩对齐设置为任何东西。 由于您将float用作基本数据类型(从性能的角度来看,您可能不应该这样做-但这是另一回事了),因此默认的4字节对齐将可以正常工作。

即使您修复了该问题,纹理也不会显示,因为它不是_mipmap完整的。 默认的缩小过滤器是GL_NEAREST_MIPMAP_LINEAR 如果您不想使用mipmapping,则必须相应地设置过滤器模式:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // or GL_LINEAR

我看到的第三个问题是,每次调用drawAnObject() ,您都将创建一个新的纹理对象 ,但从未删除它-随着时间的流逝,它将泄漏内存。

您应该考虑何时要创建纹理以及该纹理应具有的生命周期。 无需重新创建对象即可更改图像数据。

更新以回答问题中的UPTATE2:

您使用glTexSubImage2D错误,参数为:

targetlevelxoffsetyoffsetwidthheight

您基本上跳过了该level并在height位置插入了另一个0 ,因此您尝试更新4 by 0子区域。 正确的电话当然是

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGB, GL_FLOAT, cpixelArray);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM