Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 使用顶点缓冲区对象渲染的四边形纹理仅为半透明_Opengl_Opengl Es_Textures_Vbo_Opengl Es 1.1 - Fatal编程技术网

Opengl 使用顶点缓冲区对象渲染的四边形纹理仅为半透明

Opengl 使用顶点缓冲区对象渲染的四边形纹理仅为半透明,opengl,opengl-es,textures,vbo,opengl-es-1.1,Opengl,Opengl Es,Textures,Vbo,Opengl Es 1.1,我正在将一些代码从OpenGL1.3转换为OpenGLES1.1。这是一个2D游戏,所以主要归结为在四边形上渲染纹理。OpenGL ES中没有即时模式,所以我不得不使用顶点缓冲区对象 但似乎组成每个四边形的两个三角形中只有一个处理透明度。以下是一个屏幕截图: 下面是我现在渲染纹理四边形的方式,这会导致: glBindTexture2D(GL_TEXTURE_2D, id); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(G

我正在将一些代码从OpenGL1.3转换为OpenGLES1.1。这是一个2D游戏,所以主要归结为在四边形上渲染纹理。OpenGL ES中没有即时模式,所以我不得不使用顶点缓冲区对象

但似乎组成每个四边形的两个三角形中只有一个处理透明度。以下是一个屏幕截图:

下面是我现在渲染纹理四边形的方式,这会导致:

glBindTexture2D(GL_TEXTURE_2D, id);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

const GLfloat texture_coordinates[] = {0, 0,
                                       0, 1,
                                       1, 1,
                                       1, 0};
glTexCoordPointer(2, GL_FLOAT, 0, texture_coordinates);

const GLfloat vertices[] = {0, 0,
                            0, height,
                            width, height,
                            width, 0};
glVertexPointer(2, GL_FLOAT, 0, vertices);

const GLubyte indices[] = {0, 1, 2,
                           0, 2, 3};
glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_BYTE, indices);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
下面是我如何使用即时模式渲染纹理四边形,效果很好:

glBindTexture2D(GL_TEXTURE_2D, id);

glBegin(GL_QUADS);

glTexCoord2i(0, 0);
glVertex2i(0, 0);

glTexCoord2i(1, 0);
glVertex2i(width, 0);

glTexCoord2i(1, 1);
glVertex2i(width, height);

glTexCoord2i(0, 1);
glVertex2i(0, height);

glEnd();
下面是重现该问题的示例程序

您可以在Linux上编译它,如下所示:

g++ `pkg-config --cflags --libs sdl gl libpng` reproduce.cpp
clang++ -framework OpenGL `pkg-config --cflags --libs sdl libpng` reproduce.cpp
在Mac OS X上,如下所示:

g++ `pkg-config --cflags --libs sdl gl libpng` reproduce.cpp
clang++ -framework OpenGL `pkg-config --cflags --libs sdl libpng` reproduce.cpp
这是一个512x256透明PNG图像,可以另存为“transparent.PNG”:

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义使用VBO 1
结构Pixmap{
整数宽度;
内部高度;
常量无符号字符*数据;
盂型;
};
Pixmap加载\u png(常量标准::字符串和路径)
{
FILE*const FILE=fopen(path.c_str(),“rb”);
如果(!文件)
抛出std::runtime_错误(“无法打开”+路径);
png_字节头[8];
fread(头,1,8,文件);
const bool是_png=!png_sig_cmp(头,0,8);
如果(!is_png)
抛出std::runtime_错误(路径+“不是PNG”);
png_structp png=png_create_read_struct(png_LIBPNG_VER_STRING,
空,空,空);
如果(!png)
抛出std::runtime_错误(“未能创建png结构”);
png\u infop info=png\u创建\u信息结构(png);
如果(!info){
png\u destroy\u read\u struct(&png,(png\u infopp)NULL,(png\u infopp)NULL);
抛出std::runtime_错误(“未能创建png信息结构”);
}
png\u infop info\u end=png\u创建信息结构(png);
如果(!info_end){
png\u destroy\u read\u struct(&png,&info,(png\u infopp)NULL);
抛出std::runtime_错误(“未能创建png信息结构”);
}
if(setjmp(png_jmpbuf(png))){
png\u destroy\u read\u struct(&png,&info,&info\u end);
抛出std::runtime_错误(“来自libpng的错误”);
}
png_init_io(png,文件);
png_set_sig_字节(png,8);
png_read_info(png,info);
整数位深度;
int色_型;
png_uint_32图像宽度、图像高度;
png获取IHDR(png、信息、图像宽度、图像高度和位深度、,
&颜色类型,空,空,空);
png_读取_更新_信息(png,信息);
盂型;
开关(彩色){
案例PNG\U颜色\U类型\U RGBA:
格式=GL_RGBA;
打破
案例PNG\U颜色\U类型\U RGB:
格式=GL_RGB;
打破
违约:
png\u destroy\u read\u struct(&png,&info,&info\u end);
std::ostringstream消息流;

message_stream看到你在四元网格中使用带简单三角形条带的索引绘图,我不禁想知道,事实上这是你的问题。你的索引数组看起来像是要绘制两个带索引的三角形,而不是一个三角形条带。因此,你绘制了一个带6个顶点的三角形条带,从而绘制了4个三角形,这意味着需要额外的三角形包裹不知何故,在你的另外两个后面,会导致双重绘制,然后导致较暗的部分

因此,最简单的解决方案是将
GL_三角形条带
更改为
GL_三角形
,但可能会对顶点/索引重新排序,否则将按顺时针顺序绘制三角形,而1.3四元示例使用逆时针顺序(这可能与您的情况无关,但这首先是错误的方法,永远不要忽略您的订单)

但是你知道吗,这是两个三角形的三角形条带,只需要4个顶点。因此根本不需要任何索引数组,只需使用好的old
glDrawArrays
并按顺序绘制顶点。但要对它们重新排序(三角形条带使用之字形图案,所以从左到右,从上到下排列):