OpenGL渲染结果发生了奇怪的拉伸和奇怪的彩条

部分代码如下:

	// Load, create texture and generate mipmaps
	int width, height;
	unsigned char* image = SOIL_load_image("1.jpg", &width, &height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
	glGenerateMipmap(GL_TEXTURE_2D);

渲染结果
在这里插入图片描述
在这里插入图片描述
查看纹理图片尺寸发现宽度为奇数,修改为偶数之后解决了问题。
渲染结果
在这里插入图片描述
在这里插入图片描述
为什么会这样?
由于窗口大小和纹理图片大小不匹配,纹理会被放大或者缩小。

### 回答1: 如果要在 C 语言中使用 OpenGL 渲染 YUV 并且能够等比例拉伸,需要先将 YUV 数据转换为 RGB 格式,再在 OpenGL 中进行渲染。在渲染之前,需要配置投影矩阵和视图矩阵,以实现等比例拉伸效果。在绘制矩形时,需要注意纹理坐标的映射关系,以保证正确地显示图像。 以下是一份简化的代码示例: ``` #include <GL/gl.h> #include <GL/glu.h> void draw_yuv(int width, int height, const unsigned char *yuv) { // 将 YUV 数据转换为 RGB 数据 // ... // 启用 2D 纹理 glEnable(GL_TEXTURE_2D); // 创建纹理对象 GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); // 设置纹理参数 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 上传纹理数据 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb); // 设置投影矩阵和视图矩阵,实现等比例拉伸 // ... // 开始绘制 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0 ### 回答2: 使用C语言结合OpenGL渲染YUV图像并实现等比例拉伸的主要步骤如下: 1. 导入OpenGL的库文件和头文件,并创建一个OpenGL的窗口。 2. 读取YUV图像的数据,并将其存储到内存中。 3. 创建一个纹理对象,并将YUV图像数据通过纹理映射到OpenGL中。 4. 设置OpenGL纹理参数,包括采样方式和拉伸方式。 5. 在OpenGL的绘制回调函数中,绑定纹理对象并绘制一个矩形。 6. 在绘制矩形之前,根据窗口的宽高和YUV图像的宽高比例,计算出矩形的坐标和尺寸,从而实现等比例拉伸。 7. 在绘制结束后,交换绘制缓冲区的数据并更新窗口的显示。 具体实现代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <GL/glut.h> unsigned char* yuvData; // 存储YUV图像数据 GLuint textureID; // 纹理ID int windowWidth = 640; // 窗口宽度 int windowHeight = 480; // 窗口高度 int yuvWidth = 352; // YUV图像宽度 int yuvHeight = 288; // YUV图像高度 void display() { glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, textureID); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0); glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0); glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); glutSwapBuffers(); } void reshape(int width, int height) { glViewport(0, 0, width, height); // 计算等比例拉伸后的矩形尺寸 float aspectRatio = (float)yuvWidth / (float)yuvHeight; float windowRatio = (float)width / (float)height; int newWidth, newHeight; if (windowRatio > aspectRatio) { newWidth = height * aspectRatio; newHeight = height; } else { newWidth = width; newHeight = width / aspectRatio; } // 计算等比例拉伸后的矩形位置 int posX = (width - newWidth) / 2; int posY = (height - newHeight) / 2; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1, 1, -1, 1, -1, 1); glMatrixMode(GL_MODELVIEW); glViewport(posX, posY, newWidth, newHeight); } int main(int argc, char **argv) { // 读取YUV图像数据 FILE *yuvFile = fopen("input.yuv", "rb"); yuvData = (unsigned char*)malloc(yuvWidth * yuvHeight * 3 / 2); fread(yuvData, 1, yuvWidth * yuvHeight * 3 / 2, yuvFile); fclose(yuvFile); // 初始化OpenGL glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(windowWidth, windowHeight); glutCreateWindow("YUV rendering with OpenGL"); // 创建纹理对象并绑定YUV图像数据 glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, yuvWidth, yuvHeight, 0, GL_YUV420_EXT, GL_UNSIGNED_BYTE, yuvData); // 设置纹理参数 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 注册绘制和窗口调整回调函数 glutDisplayFunc(display); glutReshapeFunc(reshape); // 进入主循环 glutMainLoop(); // 释放内存 free(yuvData); return 0; } ``` 以上代码使用OpenGL绘制一个矩形,并将YUV图像通过纹理映射到矩形上,实现了等比例拉伸。在reshape回调函数中,根据窗口的宽高和YUV图像的宽高比例,计算出了矩形的位置和尺寸,从而实现了等比例拉伸效果。 ### 回答3: 使用C语言结合OpenGL库可以实现YUV渲染并且能够等比例拉伸的功能。 首先,我们需要读取YUV数据文件,并将其解析为Y、U、V三个分量。 然后,创建OpenGL窗口并设置好OpenGL环境。 接下来,在窗口创建之后,我们需要创建OpenGL纹理对象,并将YUV数据绑定到纹理上。这可以通过使用glTexImage2D函数实现,其中的格式参数应设置为GL_LUMINANCE、GL_LUMINANCE_ALPHA或GL_RGB,具体取决于输入的YUV数据类型。同时,需要注意设置纹理宽度和高度,即拉伸的比例。 接下来,我们需要在OpenGL窗口中绘制纹理。我们可以使用glBegin和glEnd函数配合glTexCoord和glVertex等函数,将纹理映射到窗口上进行绘制。同时,为了实现等比例拉伸,需要在绘制之前设置glMatrixMode函数为GL_PROJECTION,并使用glOrtho函数设置视口的宽度和高度。 最后,通过调用glutMainLoop函数进入主循环中,以便持续渲染窗口。 综上所述,通过使用C语言和OpenGL库,我们可以实现以YUV格式渲染图像,并且能够进行等比例拉伸的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值