- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个名为 Texture
的类。此类负责管理纹理。在程序启动中,OpenGL 上下文被正确初始化(这就是使这个问题不同于大多数涉及意外 glGenTextures 行为的问题)。 Texture
从 glGenTextures()
获取纹理名称,然后通过函数 texGLInit()
将图像数据加载并绑定(bind)到该纹理名称的内存中。 这有效,并且纹理显示完全符合预期。
但是,我还希望我的纹理能够更改它在用户单击按钮并从 OpenFileDiaglog
中的 HDD 中选择一个时显示的纹理。此函数称为 reloadTexture()
。此函数尝试从内存中删除旧图像/像素数据,并用用户选择的文件中的新数据替换它。 然而,当发生这种情况时,它会使用 glDeleteTextures
删除纹理名称,然后分配一个新的纹理名称并使用函数 texGLInit()
将新像素数据加载到内存中。但是纹理名称在 100% 的情况下与之前的名称(通常为“1”)完全相同。
发生这种情况后显示的图像很奇怪。它具有新的图像尺寸,但仍然是旧图像的像素。简而言之,它将旧图像扭曲到新图像的大小。它仍在使用据称已删除的像素数据进行绘制。应该发生的是屏幕现在在屏幕上显示新的图像文件。我相信这与纹理名称不唯一有关。
代码如下:
Texture::Texture(string filename)//---Constructor loads in the initial image. Works fine!
{
textureID[0]=0;
const char* fnPtr = filename.c_str(); //our image loader accepts a ptr to a char, not a string
//printf(fnPtr);
lodepng::load_file(buffer, fnPtr);//load the file into a buffer
unsigned error = lodepng::decode(image,w,h,buffer);//lodepng's decode function will load the pixel data into image vector from the buffer
//display any errors with the texture
if(error)
{
cout << "\ndecoder error " << error << ": " << lodepng_error_text(error) <<endl;
}
//execute the code that'll throw exceptions to do with the images size
checkPOT(w);
checkPOT(h);
//image now contains our pixeldata. All ready for OpenGL to do its thing
//let's get this texture up in the video memory
texGLInit();
Draw_From_Corner = CENTER;
}
void Texture::reloadTexture(string filename)//Reload texture replaces the texture name and image/pixel data bound to this texture
{
//first and foremost clear the image and buffer vectors back down to nothing so we can start afresh
buffer.clear();
image.clear();
w = 0;
h = 0;
//also delete the texture name we were using before
glDeleteTextures(1, &textureID[0]);
const char* fnPtr = filename.c_str(); //our image loader accepts a ptr to a char, not a string
//printf(fnPtr);
lodepng::load_file(buffer, fnPtr);//load the file into a buffer
unsigned error = lodepng::decode(image,w,h,buffer);//lodepng's decode function will load the pixel data into image vector from the buffer
//display any errors with the texture
if(error)
{
cout << "\ndecoder error " << error << ": " << lodepng_error_text(error) <<endl;
}
//execute the code that'll throw exceptions to do with the images size
checkPOT(w);
checkPOT(h);
//image now contains our pixeldata. All ready for to do its thing
//let's get this texture up in the video memoryOpenGL
texGLInit();
Draw_From_Corner = CENTER;
}
void Texture::texGLInit()//Actually gets the new texture name loads the pixeldata into openGL
{
glGenTextures(1, &textureID[0]);
////printf("\ntextureID = %u", textureID[0]);
glBindTexture(GL_TEXTURE_2D, textureID[0]);//evrything we're about to do is about this texture
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//glDisable(GL_COLOR_MATERIAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,w,h,0, GL_RGBA, GL_UNSIGNED_BYTE, &image[0]);
//we COULD free the image vectors memory right about now. But we'll do it when there's a need to. At the beginning of the reloadtexture func, makes sure it happens when we need it to.
}
这里值得一提的是 Texture 类中的绘制函数。
void Texture::draw(point* origin, ANCHOR drawFrom)
{
//let us set the DFC enum here.
Draw_From_Corner = drawFrom;
glEnable(GL_TEXTURE_2D);
//printf("\nDrawing texture at (%f, %f)",centerPoint.x, centerPoint.y);
glBindTexture(GL_TEXTURE_2D, textureID[0]);//bind the texture
//create a quick vertex array for the primitive we're going to bind the texture to
////printf("TexID = %u",textureID[0]);
GLfloat vArray[8];
#pragma region anchor switch
switch (Draw_From_Corner)
{
case CENTER:
vArray[0] = origin->x-(w/2); vArray[1] = origin->y-(h/2);//bottom left i0
vArray[2] = origin->x-(w/2); vArray[3] = origin->y+(h/2);//top left i1
vArray[4] = origin->x+(w/2); vArray[5] = origin->y+(h/2);//top right i2
vArray[6] = origin->x+(w/2); vArray[7] = origin->y-(h/2);//bottom right i3
break;
case BOTTOMLEFT:
vArray[0] = origin->x; vArray[1] = origin->y;//bottom left i0
vArray[2] = origin->x; vArray[3] = origin->y+h;//top left i1
vArray[4] = origin->x+w; vArray[5] = origin->y+h;//top right i2
vArray[6] = origin->x+w; vArray[7] = origin->y;//bottom right i3
break;
case TOPLEFT:
vArray[0] = origin->x; vArray[1] = origin->y-h;//bottom left i0
vArray[2] = origin->x; vArray[3] = origin->y;//top left i1
vArray[4] = origin->x+w; vArray[5] = origin->y;//top right i2
vArray[6] = origin->x+w; vArray[7] = origin->y-h;//bottom right i3
break;
case TOPRIGHT:
vArray[0] = origin->x-w; vArray[1] = origin->y-h;//bottom left i0
vArray[2] = origin->x-w; vArray[3] = origin->y;//top left i1
vArray[4] = origin->x; vArray[5] = origin->y;//top right i2
vArray[6] = origin->x; vArray[7] = origin->y-h;//bottom right i3
break;
case BOTTOMRIGHT:
vArray[0] = origin->x-w; vArray[1] = origin->y;//bottom left i0
vArray[2] = origin->x-w; vArray[3] = origin->y+h;//top left i1
vArray[4] = origin->x-h; vArray[5] = origin->y;//top right i2
vArray[6] = origin->x; vArray[7] = origin->y;//bottom right i3
break;
default: //same as center
vArray[0] = origin->x-(w/2); vArray[1] = origin->y-(h/2);//bottom left i0
vArray[2] = origin->x-(w/2); vArray[3] = origin->y+(h/2);//top left i1
vArray[4] = origin->x+(w/2); vArray[5] = origin->y+(h/2);//top right i2
vArray[6] = origin->x+(w/2); vArray[7] = origin->y-(h/2);//bottom right i3
break;
}
#pragma endregion
//create a quick texture array (we COULD create this on the heap rather than creating/destoying every cycle)
GLfloat tArray[8] =
{
//this has been tinkered with from my normal order. I think LodePNG is bringing the PD upside down. SO A QUICK FIX HERE WAS NECESSARY.
0.0f,1.0f,//0
0.0f,0.0f,//1
1.0f,0.0f,//2
1.0f,1.0f//3
};
//and finally.. the index array...remember, we draw in triangles....(and we'll go CW)
GLubyte iArray[6] =
{
0,1,2,
0,2,3
};
//Activate arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//Give openGL a pointer to our vArray and tArray
glVertexPointer(2, GL_FLOAT, 0, &vArray[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &tArray[0]);
//Draw it all
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &iArray[0]);
//glDrawArrays(GL_TRIANGLES,0,6);
//Disable the vertex arrays
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}
谁能告诉我为什么 OpenGL 不会加载我加载到其中的新像素数据并从中绘制?正如我所说,我怀疑这与 glGenTextures 没有给我新的纹理名称有关。
最佳答案
您正在调用 glTexImage2D
并将指针传递给客户端内存。当心,文档说:
If a non-zero named buffer object is bound to the
GL_PIXEL_UNPACK_BUFFER
target (seeglBindBuffer
) while a texture image is specified,data
is treated as a byte offset into the buffer object's data store.
为了安全起见,您可能希望调用 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)
解除绑定(bind)任何缓冲区对象。
关于c++ - glGenTextures 有效但每次都返回相同的纹理名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17729088/
简单的问题:当我调用 glGenTextures(0, someptr); 时会发生什么? ,生成零纹理?我有一个函数可以根据参数给出的数字生成纹理,该数字可能为 0。我在 OpenGL 引用页面、G
我将 OpenGL ES 1.1 与 NDK 一起使用,偶尔当我打电话时 glGenTextures它不会更改我传入的名称持有者的值(甚至没有将其设置为 0)。 glGetError返回0,没有错误。
可以在 OpenGL 中创建的纹理数量是否有限制 - 即使用 glGenTextures? 我知道 GL 施加了一些限制,例如。可以在片段着色器中使用的纹理数量。但是,我一直无法找到有关可用整数“纹理
我需要在 OpenGL ES 的后台线程中加载纹理。但在后台线程中调用时,glGenTextures 始终返回零。 -(void) someMethodInMainThread { [self
在 C 中我会执行以下操作: GLuint a; glGenTextures(1, &a); Haskell 中 glGenTextures 的类型是: GLsizei -> Ptr GLuint -
我正在学习 OpenGL,最近发现了 glGenTextures。尽管有几个网站解释了它的作用,但我不得不想知道它在速度,特别是内存方面的表现如何。 调用 glGenTextures 时我到底应该考虑
我有一个名为 Texture 的类。此类负责管理纹理。在程序启动中,OpenGL 上下文被正确初始化(这就是使这个问题不同于大多数涉及意外 glGenTextures 行为的问题)。 Texture
这听起来很简单,但我查看了各种网站,它只给了我两个参数: void glGenTextures(GLsizei n, GLuint * textures) .. 有解释。 然而,当在 Android
我在 iOS 6.1.4、OpenGL ES 2 上,遇到 glGenTextures 返回纹理“名称”的奇怪行为,这些名称以前由 glGenTextures 返回。 具体来说,在初始化时,我遍历我的
我之前已经将纹理加载到 openGL 中,效果很好。但是这次我想在渲染类的构造函数中加载纹理。 (我使用带有抽象基类作为接口(interface)的 MVC)。我最初试图加载一个 png 文件而不是像
问题来了:当我调用 glGenTextures 时出现段错误。 我在 linux 上,这是我目前用来调查这个的代码: #include #include #include #include i
首先,我对 C/C++ 知之甚少,因此我的知识中可能存在一个黑点,但我目前正在尝试将 OpenGL 的一些功能移植到 AS3 并查看 glGenTextures() 方法OpenGL的 http://
我一直在尝试创建一个可以打开窗口并能够显示图像的程序(我想制作一个游戏)。由于我之前在 C++ 中使用过 OGL,所以这次我决定学习一些 Java 并获得 LWJGL。我在官方教程的帮助下设置了窗口,
我正在尝试生成这样的纹理: #define checkImageWidth 64 #define checkImageHeight 64 static GLubyte checkImage[check
谁能告诉我为什么 glGenTextures() 在我的构造函数中不起作用? 这是我的项目的设置方式: 使用自定义渲染器在当前 Activity 舞台上调用 .draw。 创建阶段时,它会将自身(其构
我有这个问题: Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) [GCC 4.4.3] on linux2 Type "help", "copyrig
我遇到了一个奇怪的问题,我以未定义但不知何故有效的纹理结尾。应用此纹理的网格是黑色的。此纹理的 glIsTexture(textureId) 方法返回 1 (!) 但纹理显然是错误的。它具有未定义的大
我在 android 中使用 FBO 实现渲染到纹理,作为我创建纹理的第一步,但我通过调用 GLES20.glGenTextures 方法得到错误 1280。 Texture Creator 函数如下
使用 SDL2 和 SDL2_image 尝试一些 C++ 和 OpenGL,基于 http://open.gl 一旦到达 glGenTextures 调用,我就会收到主题错误。我的大部分搜索都提到尚
我正在学习一个处理纹理加载的教程,里面有这个方法: void CTexture::CreateEmptyTexture(int a_iWidth, int a_iHeight, GLenum form
我是一名优秀的程序员,十分优秀!