gpt4 book ai didi

c++ - 从 libpng 加载的 png 纹理在 OpenGL 中显示为黑色

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:55:01 25 4
gpt4 key购买 nike

我目前正在尝试使用 libpng 加载 png 图像,然后将其转换为 OpenGL 纹理,然后进行绘制。

现在,首先,为了快速测试一下是否有任何纹理可以绘制成一个简单的测试四边形,我制作了这个纹理:

glGenTextures(1, &textureHandle);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureHandle);

glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 4, 4);

const GLubyte myTexture[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, myTexture);

然后在我的四边形上绘制一个白色纹理。这非常有效。因此,它似乎表明片段着色器和顶点着色器以及我的其余绘图逻辑工作正常。

对于任何感兴趣的人,这是使用纹理进行绘图的主循环:

    glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(theProgram);

GLuint samplerLoc = glGetUniformLocation(theProgram, "tex");

if (samplerLoc == -1)
printf("Location name could not be found...\n");

glUniform1i(samplerLoc, 0);

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

glEnableVertexAttribArray(0);

glEnableVertexAttribArray(1);

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(16 * sizeof(float)));

glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

现在,我使用 libpng 从 png 加载 OpenGL 纹理的函数是这个函数:OpenGL Texture Load Function

我提供链接的原因是这篇文章不会变得无法阅读:)

基本上,我加载纹理并绑定(bind)它的代码部分是这样的:

GLuint myImage = png_texture_load("niks.png", &width, &height);    

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, myImage);

GLuint mySampler;

glGenSamplers(1, &mySampler);

glBindSampler(0, mySampler);

这发生在主循环之前。

同样值得注意的是,我已经使用 glGetError 函数进行了大量调试,它完全没有返回任何错误。此外,我还逐步执行了 png_texture_load 函数,它成功返回了 OpenGL 纹理。

此外,我正在加载的图像是 2 的幂。它的尺寸为 64x64。

我似乎完全不知所措,那么,当我自己的文本纹理显示得很好时,它只是一个黑色纹理?

编辑

这是 libpng 图像函数的一部分,它根据加载的数据创建纹理:

    // Generate the OpenGL texture object
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, format, temp_width, temp_height, 0, format, GL_UNSIGNED_BYTE, image_data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, temp_width, temp_height, GL_RGB, GL_UNSIGNED_BYTE, image_data);

最佳答案

喜欢的话可以试试吗?我很久以前写的..

#include <fstream>
#include <stdexcept>
#include <cstdint>

typedef union RGBA
{
std::uint32_t Colour;
struct
{
std::uint8_t R, G, B, A;
};
} *PRGB;

void ReadFromStream(png_structp PngPointer, std::uint8_t* Data, std::size_t Length)
{
std::ifstream* Stream = reinterpret_cast<std::ifstream*>(png_get_io_ptr(PngPointer));
Stream->read(reinterpret_cast<char*>(Data), Length);
}

void LoadPngImage(const char* FilePath, std::vector<RGBA> &Pixels, std::uint32_t &width, std::uint32_t &height, std::uint16_t &BitsPerPixel)
{
Pixels.clear();
std::fstream hFile(FilePath, std::ios::in | std::ios::binary);

if (!hFile.is_open())
{
throw std::invalid_argument("File Not Found.");
}

std::uint8_t Header[18] = {0};
hFile.read(reinterpret_cast<char*>(&Header), sizeof(Header));
hFile.seekg(8, std::ios::beg);

if (png_sig_cmp(Header, 0, 8))
{
hFile.close();
throw std::invalid_argument("Error: Invalid File Format. Required: Png.");
}

png_structp PngPointer = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!PngPointer)
{
hFile.close();
throw std::runtime_error("Error: Cannot Create Read Structure.");
}

png_infop InfoPointer = png_create_info_struct(PngPointer);
if (!InfoPointer)
{
hFile.close();
png_destroy_read_struct(&PngPointer, nullptr, nullptr);
throw std::runtime_error("Error: Cannot Create InfoPointer Structure.");
}

png_infop EndInfo = png_create_info_struct(PngPointer);
if (!EndInfo)
{
hFile.close();
png_destroy_read_struct(&PngPointer, &InfoPointer, nullptr);
throw std::runtime_error("Error: Cannot Create EndInfo Structure.");
}

if (setjmp(png_jmpbuf(PngPointer)))
{
hFile.close();
png_destroy_read_struct(&PngPointer, &InfoPointer, nullptr);
throw std::runtime_error("Error: Cannot Set Jump Pointer.");
}

png_set_sig_bytes(PngPointer, 8);
png_set_read_fn(PngPointer, &hFile, ReadFromStream);
png_read_info(PngPointer, InfoPointer);

channels = png_get_channels(PngPointer, InfoPointer);
png_get_IHDR(PngPointer, InfoPointer, &width, &height, &bitdepth, &colortype, &interlacetype, nullptr, nullptr);
png_set_interlace_handling(PngPointer);
png_set_strip_16(PngPointer);
png_set_packing(PngPointer);

switch (colortype)
{
case PNG_COLOR_TYPE_GRAY:
{
png_set_expand_gray_1_2_4_to_8(PngPointer);
png_set_gray_to_rgb(PngPointer);
png_set_bgr(PngPointer);
break;
}

case PNG_COLOR_TYPE_PALETTE:
{
png_set_palette_to_rgb(PngPointer);
if (png_get_valid(PngPointer, InfoPointer, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(PngPointer);
else
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
png_set_bgr(PngPointer);
BitsPerPixel = 24;
break;
}

case PNG_COLOR_TYPE_GRAY_ALPHA:
{
png_set_gray_to_rgb(PngPointer);
break;
}

case PNG_COLOR_TYPE_RGB:
{
png_set_bgr(PngPointer);
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
BitsPerPixel = 24;
break;
}

case PNG_COLOR_TYPE_RGBA:
{
png_set_bgr(PngPointer);
BitsPerPixel = 32;
break;
}

default:
png_destroy_read_struct(&PngPointer, &InfoPointer, nullptr);
throw std::runtime_error("Error: Png Type not supported.");
break;
}

png_read_update_info(PngPointer, InfoPointer);
channels = png_get_channels(PngPointer, InfoPointer);

int bitdepth, colortype, interlacetype;
png_get_IHDR(PngPointer, InfoPointer, &width, &height, &bitdepth, &colortype, &interlacetype, nullptr, nullptr);

Pixels.resize(width * height);
std::vector<std::uint8_t*> RowPointers(height);
std::uint8_t* BuffPos = reinterpret_cast<std::uint8_t*>(Pixels.data());

for (size_t I = 0; I < height; ++I)
{
RowPointers[I] = BuffPos + (I * width * sizeof(RGBA));
}

png_read_image(PngPointer, RowPointers.data());
png_read_end(PngPointer, InfoPointer);
png_destroy_read_struct(&PngPointer, &InfoPointer, nullptr);
hFile.close();
}

关于c++ - 从 libpng 加载的 png 纹理在 OpenGL 中显示为黑色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21030749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com