我正在编写一个概念验证程序来更熟悉纹理,但它的行为很奇怪,因为它对1x1纹理有效,但对所有其他纹理都无效。我多次扫描了程序,查看了每个函数的参数,但不明白为什么它对1x1纹理(或更大纹理中的第一个像素)正确工作,但在其他情况下显示一个白色方块。
这是同一个程序运行的图片,分别使用glTexImage2D的宽度和高度参数(1,1)和(2,2)。
这是显示白色正方形的代码(而预期绘制2x2红、绿、蓝、黄行主纹理)。
注意:in(Comment,Arg)
宏等同于Arg
,它只用于这个特定的程序,因为它很难记住你头顶上的glTexImage2D的参数。
#include <GL/glut.h>
// | reminder decorator macro.
#define in(Comment, Arg) Arg
GLubyte bm[16] = {
0xff, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff,
0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0xff
};
GLuint tex;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, tex);
glLoadIdentity();
// | make the square smaller to contrast our target from the background.
glScalef(.5f, .5f, 1.f);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.f, 0.f);
glVertex2f(-1.f, 1.f);
glTexCoord2f(0.f, 1.f);
glVertex2f(1.f, 1.f);
glTexCoord2f(1.f, 1.f);
glVertex2f(1.f, -1.f);
glTexCoord2f(1.f, 0.f);
glVertex2f(-1.f, -1.f);
glEnd();
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutCreateWindow("");
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D (
in(target, GL_TEXTURE_2D),
in(level, 0),
in(internalFormat, GL_RGBA),
in(width, 2),
in(height, 2),
in(border, 0),
in(format, GL_RGBA),
in(type, GL_UNSIGNED_BYTE),
in(data, bm)
);
glTexParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
如果我将(width,2)中的< code >更改为(width,1)中的< code >,将(height,2)中的< code >更改为(height,1)中的< code >,它会显示一个红色方块,并且更改< code>bm数组的前三个值,它会将该颜色映射到预期的立方体。
#include <GL/glut.h>
// | reminder decorator macro.
#define in(Comment, Arg) Arg
GLubyte bm[16] = {
0xff, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff,
0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0xff
};
GLuint tex;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, tex);
glLoadIdentity();
// | make the square smaller to contrast our target from the background.
glScalef(.5f, .5f, 1.f);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.f, 0.f);
glVertex2f(-1.f, 1.f);
glTexCoord2f(0.f, 1.f);
glVertex2f(1.f, 1.f);
glTexCoord2f(1.f, 1.f);
glVertex2f(1.f, -1.f);
glTexCoord2f(1.f, 0.f);
glVertex2f(-1.f, -1.f);
glEnd();
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutCreateWindow("");
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D (
in(target, GL_TEXTURE_2D),
in(level, 0),
in(internalFormat, GL_RGBA),
in(width, 1),
in(height, 1),
in(border, 0),
in(format, GL_RGBA),
in(type, GL_UNSIGNED_BYTE),
in(data, bm)
);
glTexParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
有人可以解释发生了什么以及我如何解决这个问题吗?
解决方案:将tex传递给glTexParameteri,而不是GL_TEXTURE_2D(旁注:在glVertex2f中输入1.1到1.f)
#include <GL/glut.h>
// | reminder decorator macro.
#define in(Comment, Arg) Arg
GLubyte bm[16] = {
0xff, 0x00, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff,
0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x00, 0xff
};
GLuint tex;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, tex);
glLoadIdentity();
// | make the square smaller to contrast our target from the background.
glScalef(.5f, .5f, 1.f);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.f, 0.f);
glVertex2f(-1.f, 1.f);
glTexCoord2f(1.f, 0.f);
glVertex2f(1.f, 1.f);
glTexCoord2f(1.f, 1.f);
glVertex2f(1.f, -1.f);
glTexCoord2f(0.f, 1.f);
glVertex2f(-1.f, -1.f);
glEnd();
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutCreateWindow("");
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D (
in(target, GL_TEXTURE_2D),
in(level, 0),
in(internalFormat, GL_RGBA),
in(width, 2),
in(height, 2),
in(border, 0),
in(format, GL_RGBA),
in(type, GL_UNSIGNED_BYTE),
in(data, bm)
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
当您指定2x2纹理时,您的纹理不是mipmap完整的,但您使用mip-map缩小过滤器。根据规范,您得到的结果是正确的结果。
您的错误在于试图设置非mipmappingGL_NEAREST
过滤器:
glTexParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameter
期望纹理绑定点,它将是GL_texture_2D
,而不是纹理名称。因此,此调用将生成GL_INVALID_ENUM
错误,并且没有其他影响。
因此,我正在构建这个游戏和一个地图编辑器/sdk类型的协议。在我运行w7的台式电脑和我的朋友运行w10的笔记本电脑上,一切都工作得非常好。我可以添加对象并四处移动它们(每个对象都有一个自动更新属性窗口),一切都很好。 我目前正在旅行,所以我决定将项目复制到我的macbook上。UI上的一切都仍然有效,除了停止渲染的东西。我知道对象存在于应用程序中,因为我可以单击它们所在的位置,属性更新就像在我的桌
我需要在着色器中使用两个纹理,一个在顶点着色器中,另一个在片段着色器中。在这两种情况下,它们都在着色器中引用,例如
你能帮忙找出哪一部分错了吗,多谢。:)
当我在Android手机上调试应用程序时,我绝对没有遇到任何错误,但在AVD上,我一开始就得到了一个NullPointerException()。我的Android设备在22 API的Lollipop(5.1.1)上运行,我的AVD在28 API的Pie(9.0)上运行。我在gradle中将最小SDK设置为21,编译SDK设置为28。 这是错误: E/AndroidRuntime:致命异常:主进程
我创建了一个OpenGL(GL_TEXTURE_2D)纹理,使用clCreateFromGLTexture()制作了一个OpenCLimage2d_t缓冲区,我运行我的OpenCL内核来绘制纹理,使用clEnqueueAcquireGLObject和clEnqueueReleaseGLObject之前和之后,然后我通过这样做在OpenGL中显示结果(我试图简单地将我的帧缓冲区纹理绘制到没有缩放的窗
我试图在OpenGL中制作一个场景,从太空模拟地球。我现在有两个球体,一个用于地球,另一个稍大一些用于云层。地球和云球体对象都有自己的着色器程序来保持简单。地球着色器程序采用4种纹理(白天、夜晚、specmap和normalmap),而云着色器程序采用2种纹理(cloudmap和normalmap)。我有一个对象类,它有一个渲染函数,在该函数中我使用以下逻辑: 它从第0个纹理单元开始,从GL_TE