这两个OpenGL调用之间有什么区别(Basic OpenGL Question)?

时间:2010-12-18 02:40:04

标签: opengl-es

这是一个非常愚蠢的基本问题,但是:有人可以告诉我区别:

glBegin(GL_QUADS);
glTexCoord3f(0, 0, 0); glVertex3f(0, 1, 0);
glTexCoord3f(1, 0, 0); glVertex3f(1, 1, 0);
glTexCoord3f(1, 1, 0); glVertex3f(1, 0, 0);
glTexCoord3f(0, 1, 0); glVertex3f(0, 0, 0);        
glEnd();

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
const GLfloat vertexData[] = {
    0,  0,  0,
    width,  0,  0,
    0,  height, 0,
    width,  height, 0
};
const GLfloat texCoords[] = {
    0,      0,
    1,      0,
    0,      1,
    1,      1
};  
glVertexPointer(3, GL_FLOAT, 0, &vertexData);
glTexCoordPointer(2, GL_FLOAT, 0, &texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

(宽度和高度是像素中的纹理大小)

我无法理解为什么,但如果我使用第二个代码(因为OpenGL ES兼容),我的纹理在y轴上反转。我做错了什么?

编辑:

我不知道,如果它相关 - 也许我在初始化视口进行2D绘图时犯了错误?

GLint iViewport[4];
glGetIntegerv( GL_VIEWPORT, iViewport );
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();   
glOrtho( iViewport[0], iViewport[0]+iViewport[2], iViewport[1]+iViewport[3], iViewport[1], -1, 1 );
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

3 个答案:

答案 0 :(得分:3)

坚持最简单,你有4个顶点与texcoords。在这里他们是平行的:

texcoord/vert
0, 0, / 0, 1
1, 0, / 1, 1
1, 1, / 1, 0
0, 1, / 0, 0

0, 0 /  0,  0
1, 0 /  width,  0
0, 1 /  0,  height
1, 1 /  width,  height

现在,如果我们按顶点重新排序,您可以看到texcoords不对应

// sorted verts by "alphabetical" position. 
0, 1, / 0, 0
0, 0, / 0, 1
1, 1, / 1, 0
1, 0, / 1, 1

0, 0 /  0,  0
0, 1 /  0,  height
1, 0 /  width,  0
1, 1 /  width,  height

如您所见,对于每个等效位置,第二个纹理坐标在2之间反转。这解释了为什么纹理被y翻转。

因此,如果你想修复它,只需将它们翻回第二种方法:

const GLfloat texCoords[] = {
    0,      1,
    1,      1,
    0,      0,
    1,      0
}; 

答案 1 :(得分:0)

尝试在每种情况下使用相同的几何体:

立即模式:

glBegin(GL_TRIANGLES);
glTexCoord2f(0, 0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(1, 0, 0); glVertex3f(1, 0, 0);
glTexCoord2f(1, 1, 0); glVertex3f(1, 1, 0);
glTexCoord2f(1, 1, 0); glVertex3f(1, 1, 0);
glTexCoord2f(0, 1, 0); glVertex3f(0, 1, 0);        
glTexCoord2f(0, 0, 0); glVertex3f(0, 0, 0);
glEnd();

顶点数组:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
const GLfloat vertexData[] = {
    0,  0,  0,
    width,  0,  0,
    width,  height, 0
    width,  height, 0
    0,  height, 0,
    0,  0,  0,
};
const GLfloat texCoords[] = {
    0,      0,
    1,      0,
    1,      1
    1,      1
    0,      1,
    0,      0,
};  
glVertexPointer(3, GL_FLOAT, 0, &vertexData);
glTexCoordPointer(2, GL_FLOAT, 0, &texCoords);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

答案 2 :(得分:0)

好的,试试这个完整的GLUT计划。我这次实际测试了它:)

#include <vector>
#include <GL/glut.h>

using namespace std;

size_t win_w = 0;
size_t win_h = 0;
double aspect_ratio = 0;

GLuint tex_obj;

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10*aspect_ratio, 10*aspect_ratio, -10, 10, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex_obj);

    glPushMatrix();
    glScalef(5,5,0);

    /*
    glBegin(GL_TRIANGLES);
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
    glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
    glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
    glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
    glTexCoord2f(0, 1); glVertex3f(0, 1, 0);        
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
    glEnd();
    */

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    const GLfloat vertexData[] = {
        0,  0,  0,
        1,  0,  0,
        1,  1,  0,
        1,  1,  0,
        0,  1,  0,
        0,  0,  0,
    };
    const GLfloat texCoords[] = {
        0,      0,
        1,      0,
        1,      1,
        1,      1,
        0,      1,
        0,      0,
    };  
    glVertexPointer(3, GL_FLOAT, 0, &vertexData);
    glTexCoordPointer(2, GL_FLOAT, 0, &texCoords);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glPopMatrix();

    glFlush();
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    win_w = w;
    win_h = h;
    aspect_ratio = (double)win_w / (double)win_h;
    glViewport(0, 0, w, h);
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

    glutInitWindowSize(800,600);
    glutCreateWindow("Aspect Ratio");

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &tex_obj);
    glBindTexture(GL_TEXTURE_2D, tex_obj);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

    vector< unsigned char > pixels(4 * 3);
    pixels[3*0+0] = 255;    
    pixels[3*0+1] = 0;    
    pixels[3*0+2] = 0;    

    pixels[3*1+0] = 0;    
    pixels[3*1+1] = 255;    
    pixels[3*1+2] = 0;    

    pixels[3*2+0] = 0;    
    pixels[3*2+1] = 0;    
    pixels[3*2+2] = 255;    

    pixels[3*3+0] = 255;    
    pixels[3*3+1] = 255;    
    pixels[3*3+2] = 255;    

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}