gpt4 book ai didi

c++ - 尝试实现渲染到纹理

转载 作者:行者123 更新时间:2023-11-28 03:46:23 32 4
gpt4 key购买 nike

我在使用 OpenGL 3 实现纹理渲染时遇到问题。

我的问题是,在渲染到帧缓冲区之后,渲染的对象看起来变形了,这可能意味着某处发生了错误的转换。这没有意义,因为当使用我的帧缓冲区时对象渲染良好(见帖子底部)。

目前的结果是这样的:

Current result http://k.minus.com/jZVgUuLYRtapv.jpg

预期的结果是这样的(或类似的东西,这刚刚被 GIMP 处理过): Expected http://k.minus.com/jA5rLM8lmXQYL.jpg

因此这意味着我在我的帧缓冲区设置代码或其他地方做错了什么。但是我看不到什么。


FBO是通过以下函数设置的:

unsigned int fbo_id;
unsigned int depth_buffer;
int m_FBOWidth, m_FBOHeight;
unsigned int m_TextureID;

void initFBO() {
m_FBOWidth = screen_width;
m_FBOHeight = screen_height;

glGenRenderbuffers(1, &depth_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_FBOWidth, m_FBOHeight);

glGenTextures(1, &m_TextureID);
glBindTexture(GL_TEXTURE_2D, m_TextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_FBOWidth, m_FBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glGenFramebuffers(1, &fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TextureID, 0);

assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

这是我的绘图框代码,它只需要一个变换矩阵并调用适当的函数。 P的当前值是一个投影矩阵,是 View 矩阵(V)的单位矩阵。

void drawBox(const Matrix4& M) {
const Matrix4 MVP = M * V * P;

if (boundshader) {
glUniformMatrix4fv((*boundshader)("MVP"), 1, GL_FALSE, &MVP[0]);
}

glBindVertexArray(vaoID);
glDrawElements(GL_TRIANGLES, sizeof(cube.polygon)/sizeof(cube.polygon[0]), GL_UNSIGNED_INT, 0);
}

void drawStaticBox() {
Matrix4 M(1);
translate(M, Vector3(0,0,-50));

drawBox(M);
}

void drawRotatingBox() {
Matrix4 M(1);
rotate(M, rotation(Vector3(1, 0, 0), rotation_x));
rotate(M, rotation(Vector3(0, 1, 0), rotation_y));
rotate(M, rotation(Vector3(0, 0, 1), rotation_z));
translate(M, Vector3(0,0,-50));

drawBox(M);
}

以及GLUT调用的显示函数。

void OnRender() {
/////////////////////////////////////////
// Render to FBO

glClearColor(0, 0, 0.2f,0);

glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
glViewport(0, 0, m_FBOWidth, m_FBOHeight);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
GL_CHECK_ERRORS

colorshader.Use();
boundshader = &colorshader;

drawRotatingBox();

colorshader.UnUse();

/////////////////////////////////////////
// Render to Window

glClearColor(0, 0, 0, 0);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, screen_width, screen_height);
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
GL_CHECK_ERRORS

texshader.Use();
boundshader = &texshader;

glBindTexture(GL_TEXTURE_2D, m_TextureID);
drawStaticBox();

texshader.UnUse();

// Swap le buffers
glutSwapBuffers();
}

还有...强制性纹理着色器代码

顶点

#version 330

in vec2 vUV;
in vec3 vVertex;
smooth out vec2 vTexCoord;

uniform mat4 MVP;
void main()
{
vTexCoord = vUV;
gl_Position = MVP*vec4(vVertex,1);
}

片段

#version 330
smooth in vec2 vTexCoord;
out vec4 vFragColor;

uniform sampler2D textureMap;

void main(void)
{
vFragColor = texture(textureMap, vTexCoord);
}

以下是不使用 FBO 逻辑时呈现的内容: What is rendered to the FBO http://k.minus.com/jiP7kTOSLLvHk.jpg


...帮助?

关于我可能做错了什么的任何想法?可应要求提供更多来源。

最佳答案

无需仔细查看您的代码,这是一些肯定有效的示例 FBO 代码(将茶壶设置为纹理动画,将纹理绘制到旋转立方体的侧面)。

#include <GL/glew.h>
#include <GL/glut.h>

#include <cmath>
#include <iostream>

using namespace std;

namespace render
{
int width, height;
float aspect;

void init();
void reshape(int width, int height);
void display();

int const fbo_width = 512;
int const fbo_height = 512;

GLuint fb, color, depth;
};

void idle();

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );

glutCreateWindow("FBO test");
glutDisplayFunc(render::display);
glutReshapeFunc(render::reshape);
glutIdleFunc(idle);

glewInit();

render::init();
glutMainLoop();

return 0;
}

void idle()
{
glutPostRedisplay();
}

void CHECK_FRAMEBUFFER_STATUS()
{
GLenum status;
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
break;

case GL_FRAMEBUFFER_UNSUPPORTED:
/* choose different formats */
break;

default:
/* programming error; will fail on all hardware */
throw "Framebuffer Error";
}
}

namespace render
{
float const light_dir[]={1,1,1,0};
float const light_color[]={1,0.95,0.9,1};

void init()
{
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glGenRenderbuffers(1, &depth);

glBindFramebuffer(GL_FRAMEBUFFER, fb);

glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
fbo_width, fbo_height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbo_width, fbo_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);

CHECK_FRAMEBUFFER_STATUS();
}

void reshape(int width, int height)
{
render::width=width;
render::height=height;
aspect=float(width)/float(height);
glutPostRedisplay();
}

void prepare()
{
static float a=0, b=0, c=0;

glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);

glViewport(0,0,fbo_width, fbo_height);

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

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 1, 1, 10);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);

glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);

glLightfv(GL_LIGHT0, GL_POSITION, light_dir);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);

glTranslatef(0,0,-5);

glRotatef(a, 1, 0, 0);
glRotatef(b, 0, 1, 0);
glRotatef(c, 0, 0, 1);

glutSolidTeapot(0.75);

a=fmod(a+0.1, 360.);
b=fmod(b+0.5, 360.);
c=fmod(c+0.25, 360.);
}

void final()
{
static float a=0, b=0, c=0;

glBindFramebuffer(GL_FRAMEBUFFER, 0);

glViewport(0,0, width, height);

glClearColor(1.,1.,1.,0.);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1, 10);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-5);

glRotatef(b, 0, 1, 0);

b=fmod(b+0.5, 360.);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, color);

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glDisable(GL_LIGHTING);

float cube[][5]=
{
{-1, -1, -1, 0, 0},
{ 1, -1, -1, 1, 0},
{ 1, 1, -1, 1, 1},
{-1, 1, -1, 0, 1},

{-1, -1, 1, -1, 0},
{ 1, -1, 1, 0, 0},
{ 1, 1, 1, 0, 1},
{-1, 1, 1, -1, 1},
};
unsigned int faces[]=
{
0, 1, 2, 3,
1, 5, 6, 2,
5, 4, 7, 6,
4, 0, 3, 7,
3, 2, 6, 7,
4, 5, 1, 0
};

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(3, GL_FLOAT, 5*sizeof(float), &cube[0][0]);
glTexCoordPointer(2, GL_FLOAT, 5*sizeof(float), &cube[0][3]);

glCullFace(GL_BACK);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces);

glCullFace(GL_FRONT);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, faces);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}

void display()
{
prepare();
final();

glutSwapBuffers();
}
}

仅供引用。

关于c++ - 尝试实现渲染到纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7510257/

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