0

三角形にテクスチャの一部を描画しようとしています。三角形は3点で定義されます。ポイントの1つは、常に画像の中心になります。次に、その三角形にテクスチャの一部を描画します。したがって、三角形は画像のその部分を切り取り、それ自体に描画します。しかし、私は描画時にテクスチャを拡大縮小したくありません。それは同じままでなければなりません。したがって、三角形の基点が画像の外側にある場合でも。画像を拡大縮小することはできません。これがどのようにできるのかわかりません。テクスチャリングをいじるたびに、画像は複数回拡大縮小または描画されます。

これが画像です。したがって、赤い三角形はopenGLの場合とまったく同じように描画されます。

ここに画像の説明を入力してください

4

1 に答える 1

0

フラグメント シェーダーで、texcoordのs&の値を確認し、どちらかが 0 未満か 1 より大きいかを確認します。tdiscard

編集:例:

// 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;
}
于 2013-02-04T13:45:50.097 に答える