我正在尝试在三角形上绘制部分纹理。三角形由3个点定义。其中一个点将始终是图像的中心。现在我想在该三角形上绘制一部分纹理。因此,三角形将切出图像的那一部分并将其绘制在自身上。但我不希望在绘制时纹理缩放。它必须保持不变。即使三角形的基点落在图像之外。图像无法缩放。我不明白如何做到这一点。每当我使用纹理时,图像会被缩放或绘制多次。
这是一张图片:所以红色三角形的绘制方式与openGL中的完全相同。
答案 0 :(得分:0)
在片段着色器中,检查s
&您的texcoord和t
上的discard
值,如果小于零或大于一。
编辑:示例:
// 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;
}