【问题标题】:OpenGL trying to stretch quad with texture but stretches triangles?OpenGL试图用纹理拉伸四边形但拉伸三角形?
【发布时间】:2014-07-21 18:56:22
【问题描述】:

我编写了代码来重塑已纹理化的四边形。当我拉伸四边形时,图像确实会按照我的预期拉伸。当我拉伸图像时,我似乎有两个不同的三角形被拉伸,而不是一个单一的四边形。左上角的像素拉伸在一起,但它们不会影响右下角的像素。反之亦然。有没有我应该设置的设置来延伸整个四边形。

这是一张图片:

要使用我的代码,您可以使用箭头键来移动角落。按空格键切换控制哪个角。

我的代码

// textureMapping.cpp
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>


static GLuint texName;
int mode = 0;
double tol = 0.2f;

double xLoc = 0.0;
double yLoc = 0.0;

double xLocLL = 0.0;
double yLocLL = 0.0;

double xLocUL = 0.0;
double yLocUL = 0.0;

double xLocLR = 0.0;
double yLocLR = 0.0;

double xLocUR = 0.0;
double yLocUR = 0.0;

void init(void)
{    

   cv::Mat image = cv::imread("lena.tiff");
  //cv::Mat flipped;
  //cv::flip(image, flipped, 0);
  //image = flipped;
  if(image.empty()){
      std::cout << "image empty" << std::endl;
  }else{
      cv::flip(image, image, 0);
      glGenTextures(1, &texName);
      glBindTexture(GL_TEXTURE_2D, texName);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // Set texture clamping method
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);


      glTexImage2D(GL_TEXTURE_2D,     // Type of texture
                     0,                 // Pyramid level (for mip-mapping) - 0 is the top level
                     GL_RGB,            // Internal colour format to convert to
                     image.cols,          // Image width  i.e. 640 for Kinect in standard mode
                     image.rows,          // Image height i.e. 480 for Kinect in standard mode
                     0,                 // Border width in pixels (can either be 1 or 0)
                     GL_BGR, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
                     GL_UNSIGNED_BYTE,  // Image data type
                     image.ptr());        // The actual image data itself

      glGenerateMipmap(GL_TEXTURE_2D);
  }
}

void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glEnable(GL_TEXTURE_2D);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
   glBindTexture(GL_TEXTURE_2D, texName);
   glBegin(GL_QUADS);
   glTexCoord2f(0.0, 0.0); glVertex3f(-1.0+xLoc+xLocLL, -1.0+yLoc+yLocLL, 0.0);
   glTexCoord2f(0.0, 1.0); glVertex3f(-1.0+xLoc+xLocUL, 1.0+yLoc+yLocUL, 0.0);
   glTexCoord2f(1.0, 1.0); glVertex3f(1.0+xLoc+xLocUR, 1.0+yLoc+yLocUR, 0.0);
   glTexCoord2f(1.0, 0.0); glVertex3f(1.0+xLoc+xLocLR, -1.0+yLoc+yLocLR, 0.0);
   //glTexCoord2f(0.0, 0.0); glVertex3f(-1.0+xLoc, -1.0+yLoc, 0.0);
   //glTexCoord2f(0.0, 1.0); glVertex3f(-1.0+xLoc, 1.0+yLoc, 0.0);
   //glTexCoord2f(1.0, 1.0); glVertex3f(1.0+xLoc, 1.0+yLoc, 0.0);
   //glTexCoord2f(1.0, 0.0); glVertex3f(1.0+xLoc, -1.0+yLoc, 0.0);
   glEnd();
   glFlush();
   glDisable(GL_TEXTURE_2D);
   glutSwapBuffers();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glTranslatef(0.0, 0.0, -3.6);
}

void keyboard (unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
      case 32:
         mode += 1;
         if (mode == 5)
         {
            mode = 0;
         }
         break;
      default:
         break;
   }
}

void processSpecialKeys(int key, int x, int y) {

   switch(key) {
      case GLUT_KEY_LEFT:
         switch(mode)
         {
            case 0:
               xLoc -= tol;
               break;
            case 1:
               xLocLL -= tol;
               break;
            case 2:
               xLocUL -= tol;
               break;
            case 3:
               xLocUR -= tol;
               break;
            case 4:
               xLocLR -= tol;
               break;
         }
         break;
      case GLUT_KEY_RIGHT:
         switch(mode)
         {
            case 0:
               xLoc += tol;
               break;
            case 1:
               xLocLL += tol;
               break;
            case 2:
               xLocUL += tol;
               break;
            case 3:
               xLocUR += tol;
               break;
            case 4:
               xLocLR += tol;
               break;
         }
         break;
      case GLUT_KEY_DOWN:
         switch(mode)
         {
            case 0:
               yLoc -= tol;
               break;
            case 1:
               yLocLL -= tol;
               break;
            case 2:
               yLocUL -= tol;
               break;
            case 3:
               yLocUR -= tol;
               break;
            case 4:
               yLocLR -= tol;
               break;
         }
         break;
      case GLUT_KEY_UP:
         switch(mode)
         {
            case 0:
               yLoc += tol;
               break;
            case 1:
               yLocLL += tol;
               break;
            case 2:
               yLocUL += tol;
               break;
            case 3:
               yLocUR += tol;
               break;
            case 4:
               yLocLR += tol;
               break;
         }
         break;
   }
}


int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize(500, 500);
   glutInitWindowPosition(100, 100);
   glutCreateWindow(argv[0]);
   init();
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutIdleFunc(display);
   glutKeyboardFunc(keyboard);
   glutSpecialFunc(processSpecialKeys);

   glutMainLoop();
   return 0; 
}

生成文件

textureMapping: textureMapping.cpp
    g++ -o textureMapping textureMapping.cpp -L/usr/local/lib -I/usr/local/include -lopencv_core -lopencv_highgui -framework GLUT -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo

【问题讨论】:

  • 你不能那样做映射。您需要使用投影纹理空间来定义投影纹理映射。 This page 解释问题和解决方案。

标签: c++ opengl


【解决方案1】:

不,这是正确的行为。 GL 规范(3.0 之前的版本)允许将四边形绘制为成对的三角形,这就是您所看到的。 Quads 在 3.0 中完全从规范中移除。

如果您希望它看起来像一个有透视的四边形,那么您实际上需要提供 3d 坐标。

如果您希望 OpenGL 猜测将应用什么透视变换来使矩形弯曲到您正在推动的 2d 形状,那么您就看不出来了。这是一个高度特定于应用程序的功能。你应该查一下单应性。

【讨论】:

    猜你喜欢
    • 2015-01-28
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多