2013-02-04 39 views
0

我想绘制在三角形上的纹理的一部分。三角形由3个点定义。其中一点将永远是图像的中心。现在我想绘制该三角形上的纹理的一部分。所以这个三角形会切掉这部分图像并将其自行绘制。但是我不希望纹理在绘制时缩放。它必须保持不变。所以即使三角形的基点落在图像之外。图像不能缩放。我不明白如何做到这一点。每当我玩弄纹理时,图像都会缩放或绘制多次。绘制在OpenGL中的三角形上的纹理的一部分

这里是一个图像:所以红色三角形将被绘制成与openGL完全相同。

enter image description here

+2

固定功能或可编程管线? – genpfault

+0

可编程管道 –

回答

0

在您的片段着色器检查您的texcoord和discards & t值如果任一小于零或大于1。

编辑:示例:

// g++ main.cpp -o main -lglut -lGLEW 
#include <GL/glew.h> 
#include <GL/glut.h> 
#include <vector> 
#include <iostream> 

using namespace std; 

void CheckStatus(GLuint obj) 
{ 
    GLint status = GL_FALSE, len = 10; 
    if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status); 
    if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status); 
    if(status == GL_TRUE) return; 
    if(glIsShader(obj)) glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len); 
    if(glIsProgram(obj)) glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len); 
    vector<char> log(len, 'X'); 
    if(glIsShader(obj)) glGetShaderInfoLog(obj, len, NULL, &log[0]); 
    if(glIsProgram(obj)) glGetProgramInfoLog(obj, len, NULL, &log[0]); 
    cerr << &log[0] << endl; 
    exit(-1); 
} 

GLuint LoadShader(GLenum type, const char* src) 
{ 
    GLuint shader = glCreateShader(type); 
    glShaderSource(shader, 1, &src, NULL); 
    glCompileShader(shader); 
    CheckStatus(shader); 
    return shader; 
} 

GLuint LoadProgram(const char* vert, const char* geom, const char* frag) 
{ 
    GLuint program = glCreateProgram(); 
    if(vert) glAttachShader(program, LoadShader(GL_VERTEX_SHADER, vert)); 
    if(geom) glAttachShader(program, LoadShader(GL_GEOMETRY_SHADER, geom)); 
    if(frag) glAttachShader(program, LoadShader(GL_FRAGMENT_SHADER, frag)); 
    glLinkProgram(program); 
    CheckStatus(program); 
    return program; 
} 

#define GLSL(version, shader) "#version " #version "\n" #shader 

const GLchar* vert = GLSL 
(
    120, 
    void main() 
    { 
     gl_TexCoord[0] = gl_MultiTexCoord0; 
     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    } 
); 

const GLchar* frag = GLSL 
(
    120, 
    uniform sampler2D texture; 
    void main() 
    { 
     if(any(lessThan(gl_TexCoord[0].st, vec2(0.0, 0.0))) || 
      any(greaterThan(gl_TexCoord[0].st, vec2(1.0, 1.0)))) 
     { 
      gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); 
      //discard; 
     } 
     else 
     { 
      gl_FragColor = texture2D(texture, gl_TexCoord[0].st); 
     } 
    } 
); 

GLuint prog = 0; 
GLuint tex = 0; 
void init() 
{ 
    prog = LoadProgram(vert, NULL, frag); 

    unsigned char bits[ 32 * 32 * 4 ]; 
    for(unsigned int i = 0; i < 32*32; ++i) 
    { 
     bits[i*4 + 0] = rand() % 255; 
     bits[i*4 + 1] = rand() % 255; 
     bits[i*4 + 2] = rand() % 255; 
     bits[i*4 + 3] = 255; 
    } 

    glGenTextures(1, &tex); 
    glBindTexture(GL_TEXTURE_2D, tex); 
    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); 
    glTexImage2D(GL_TEXTURE_2D, 0, 4, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits); 
} 

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    double w = glutGet(GLUT_WINDOW_WIDTH); 
    double h = glutGet(GLUT_WINDOW_HEIGHT); 
    double ar = w/h; 
    glOrtho(-3 * ar, 3 * ar, -3, 3, -1, 1); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glUseProgram(prog); 
    glUniform1i(glGetUniformLocation(prog, "texture"), 0);  
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, tex); 

    glBegin(GL_TRIANGLES); 
    glTexCoord2f(0.5, 0.5); 
    glVertex2f(0, 0); 
    glTexCoord2f(1.5, 0.5); 
    glVertex2f(2, 0); 
    glTexCoord2f(0.5, 1.5); 
    glVertex2f(0, 2); 
    glEnd(); 

    glutSwapBuffers(); 
} 

int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
    glutInitWindowSize(640,480); 
    glutCreateWindow("test"); 
    glutDisplayFunc(display); 
    glewInit(); 
    init(); 
    glutMainLoop(); 
    return 0; 
} 
+0

我不认为我明白该怎么做。 u和v值对应于我的片段着色器中的texcoord [0] .st [0]和texcoord [0] .st [1]?为了让我的三角形首先绑定纹理,然后调用glBegin(GL_TRIANGLES); 然后,我为每个点设置这样的texcoord。 其中p2x和p2y被计算。 glTexCoord2f(p2x,p2y); glVertex2f(l.p2.x,l.p2.y); 但是这是正确的做事方式还是我完全错了,如果我错了,你可能会指导我一个很好的教程。 –

+0

@DavidMaes:在一个例子中编辑。很抱歉无法使用已弃用功能的混搭搭配。 – genpfault

+0

是的,在回顾了GLSL规范之后,我应该说''''''而不是'u'&'v'。编辑。 – genpfault