我想绘制在三角形上的纹理的一部分。三角形由3个点定义。其中一点将永远是图像的中心。现在我想绘制该三角形上的纹理的一部分。所以这个三角形会切掉这部分图像并将其自行绘制。但是我不希望纹理在绘制时缩放。它必须保持不变。所以即使三角形的基点落在图像之外。图像不能缩放。我不明白如何做到这一点。每当我玩弄纹理时,图像都会缩放或绘制多次。绘制在OpenGL中的三角形上的纹理的一部分
这里是一个图像:所以红色三角形将被绘制成与openGL完全相同。
我想绘制在三角形上的纹理的一部分。三角形由3个点定义。其中一点将永远是图像的中心。现在我想绘制该三角形上的纹理的一部分。所以这个三角形会切掉这部分图像并将其自行绘制。但是我不希望纹理在绘制时缩放。它必须保持不变。所以即使三角形的基点落在图像之外。图像不能缩放。我不明白如何做到这一点。每当我玩弄纹理时,图像都会缩放或绘制多次。绘制在OpenGL中的三角形上的纹理的一部分
这里是一个图像:所以红色三角形将被绘制成与openGL完全相同。
在您的片段着色器检查您的texcoord和discard
的s
& 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;
}
我不认为我明白该怎么做。 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); 但是这是正确的做事方式还是我完全错了,如果我错了,你可能会指导我一个很好的教程。 –
@DavidMaes:在一个例子中编辑。很抱歉无法使用已弃用功能的混搭搭配。 – genpfault
是的,在回顾了GLSL规范之后,我应该说''''''而不是'u'&'v'。编辑。 – genpfault
固定功能或可编程管线? – genpfault
可编程管道 –