Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何在OpenGL中正确地正交渲染纹理?_Objective C_Macos_Cocoa_Opengl - Fatal编程技术网

Objective c 如何在OpenGL中正确地正交渲染纹理?

Objective c 如何在OpenGL中正确地正交渲染纹理?,objective-c,macos,cocoa,opengl,Objective C,Macos,Cocoa,Opengl,我正在尝试在正交投影中渲染2D纹理。 告诉我怎么了。 宽度和高度为128,视图的宽度和高度为256px,因此我希望纹理缩放为2x。 但我得到的只是: 代码: @interface ModNesOpenGLView : NSOpenGLView { @public char *pixels; int width; int height; int zoom; } - (void) drawRect: (NSRect) bounds; - (vo

我正在尝试在正交投影中渲染2D纹理。
告诉我怎么了。
宽度和高度为128,视图的宽度和高度为256px,因此我希望纹理缩放为2x。
但我得到的只是:

代码:

@interface ModNesOpenGLView : NSOpenGLView {
   @public
      char *pixels;
      int width;
      int height;
      int zoom;
}
- (void) drawRect: (NSRect) bounds;
- (void) free;
@end

@implementation ModNesOpenGLView

-(void) awakeFromNib {
   self->pixels = malloc( self->width * self->height * 3 );
   memset( (void *)self->pixels, 0, self->width * self->height * 3 );

   for( int y=0; y<self->height; ++y )
   {
      for( int x=0; x<self->width; ++x )
      {
         char r=0,g=0,b=0;
         switch( y%3 ) {
            case 0: r=0xFF; break;
            case 1: g=0xFF; break;
            case 2: b=0xFF; break;
         }
         [self setPixel_x:x y:y r:r g:g b:b];
      }
   }
}

-(void) setPixel_x:(int)x y:(int)y r:(char)r g:(char)g b:(char)b
{
   self->pixels[ ( y * self->width + x ) * 3 ] = r;
   self->pixels[ ( y * self->width + x ) * 3 + 1 ] = g;
   self->pixels[ ( y * self->width + x ) * 3 + 2 ] = b;
}

-(void) drawRect: (NSRect) bounds
{
   glClearColor(0, 0, 0, 0);
   glClear(GL_COLOR_BUFFER_BIT );

   glTexImage2D( GL_TEXTURE_2D, 0, 3, self->width, self->height, 0,GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*) self->pixels );
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
   glEnable(GL_TEXTURE_2D);

//   glTexSubImage2D(GL_TEXTURE_2D, 0 ,0, 0, self->width, self->height, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*) self->pixels );

   glBegin( GL_QUADS );
      glTexCoord2d(0.0, 0.0); glVertex2d(0.0,   0.0);
      glTexCoord2d(1.0, 0.0); glVertex2d(self->width, 0.0);
      glTexCoord2d(1.0, 1.0); glVertex2d(self->width, self->height);
      glTexCoord2d(0.0, 1.0); glVertex2d(0.0,   self->height);
   glEnd();

   glFlush();
}

- (void)prepareOpenGL
{
   // Synchronize buffer swaps with vertical refresh rate
   GLint swapInt = 1;
   [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
然后我得到这个:

我很困惑


下面是我从中获得代码的地方:

您的问题在于坐标系及其范围。查看用于绘图的坐标:

glTexCoord2d(0.0, 0.0); glVertex2d(0.0,   0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(self->width, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(self->width, self->height);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0,   self->height);
如果不应用变换,OpenGL坐标系在x方向和y方向上的范围均为[-1.0,1.0]。这意味着(0.0,0.0),即正在绘制的四边形的左下角,位于屏幕的中心。然后它会延伸到右侧和顶部。四边形的大小实际上比窗口大得多,但它显然会被剪裁

这解释了您发布的原始版本和生成的图片。最后,右上象限被填充,纹理的一小部分(大约一个texel)被填充

然后在更新的代码中添加以下内容:

glViewport(0, 0, self->width, self->height);
视口确定绘制到的窗口部分。由于您说
width
height
为128,窗口大小为256x256,因此此调用指定您只希望绘制到窗口的左下象限

由于所有其他内容都保持不变,因此仍将绘制绘图区域的右上象限。最后填充窗口左下象限的右上象限,这正是第二张图像中的内容

要解决此问题,最简单的方法是将视口设置为非默认值(删除
glViewport()
调用),并在两个方向上使用[-1.0,1.0]范围内的坐标:

glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
另一个选项是设置变换,将坐标范围更改为所使用的值。在您正在使用的传统OpenGL中,类似这样的功能应该可以工作:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, self->width, 0.0, self->height, -1.0, 1.0);

您的问题在于坐标系及其范围。查看用于绘图的坐标:

glTexCoord2d(0.0, 0.0); glVertex2d(0.0,   0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(self->width, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(self->width, self->height);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0,   self->height);
如果不应用变换,OpenGL坐标系在x方向和y方向上的范围均为[-1.0,1.0]。这意味着(0.0,0.0),即正在绘制的四边形的左下角,位于屏幕的中心。然后它会延伸到右侧和顶部。四边形的大小实际上比窗口大得多,但它显然会被剪裁

这解释了您发布的原始版本和生成的图片。最后,右上象限被填充,纹理的一小部分(大约一个texel)被填充

然后在更新的代码中添加以下内容:

glViewport(0, 0, self->width, self->height);
视口确定绘制到的窗口部分。由于您说
width
height
为128,窗口大小为256x256,因此此调用指定您只希望绘制到窗口的左下象限

由于所有其他内容都保持不变,因此仍将绘制绘图区域的右上象限。最后填充窗口左下象限的右上象限,这正是第二张图像中的内容

要解决此问题,最简单的方法是将视口设置为非默认值(删除
glViewport()
调用),并在两个方向上使用[-1.0,1.0]范围内的坐标:

glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
另一个选项是设置变换,将坐标范围更改为所使用的值。在您正在使用的传统OpenGL中,类似这样的功能应该可以工作:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, self->width, 0.0, self->height, -1.0, 1.0);

您的问题在于坐标系及其范围。查看用于绘图的坐标:

glTexCoord2d(0.0, 0.0); glVertex2d(0.0,   0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(self->width, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(self->width, self->height);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0,   self->height);
如果不应用变换,OpenGL坐标系在x方向和y方向上的范围均为[-1.0,1.0]。这意味着(0.0,0.0),即正在绘制的四边形的左下角,位于屏幕的中心。然后它会延伸到右侧和顶部。四边形的大小实际上比窗口大得多,但它显然会被剪裁

这解释了您发布的原始版本和生成的图片。最后,右上象限被填充,纹理的一小部分(大约一个texel)被填充

然后在更新的代码中添加以下内容:

glViewport(0, 0, self->width, self->height);
视口确定绘制到的窗口部分。由于您说
width
height
为128,窗口大小为256x256,因此此调用指定您只希望绘制到窗口的左下象限

由于所有其他内容都保持不变,因此仍将绘制绘图区域的右上象限。最后填充窗口左下象限的右上象限,这正是第二张图像中的内容

要解决此问题,最简单的方法是将视口设置为非默认值(删除
glViewport()
调用),并在两个方向上使用[-1.0,1.0]范围内的坐标:

glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
另一个选项是设置变换,将坐标范围更改为所使用的值。在您正在使用的传统OpenGL中,类似这样的功能应该可以工作:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, self->width, 0.0, self->height, -1.0, 1.0);

您的问题在于坐标系及其范围。查看用于绘图的坐标:

glTexCoord2d(0.0, 0.0); glVertex2d(0.0,   0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(self->width, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(self->width, self->height);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0,   self->height);
如果不应用变换,OpenGL坐标系在x方向和y方向上的范围均为[-1.0,1.0]。这意味着(0.0,0.0),即正在绘制的四边形的左下角,位于屏幕的中心。然后它会延伸到右侧和顶部。四边形的大小实际上比窗口大得多,但它显然会被剪裁

这解释了您发布的原始版本和生成的图片。最后,右上角的象限被填满,有一个