C++ 创建原始OpenGL纹理数据(C+;+;)
所以我基本上是在代码中创建自己的纹理。具体来说,我正在编写一个光线跟踪器,并希望将结果显示为渲染到屏幕上四边形的纹理 但是如何创建自己的纹理,然后将其应用到屏幕四边形呢?我已经做了几天了,没有任何特别的结果。我现在得到的是屏幕上的一个四边形,但纹理是整个四边形的一种颜色。但在我这里的例子中,我希望它是1/3白色和2/3黑色,这就是我想象的 我想让OpenGL尽可能的光明正大。我不打算扩展它,所以任何包含“丑陋的黑客”的答案只要有效就完全可以。我正在使用Glew、GLFW和GLM 我现在就是这样做的:C++ 创建原始OpenGL纹理数据(C+;+;),c++,opengl,glsl,glew,C++,Opengl,Glsl,Glew,所以我基本上是在代码中创建自己的纹理。具体来说,我正在编写一个光线跟踪器,并希望将结果显示为渲染到屏幕上四边形的纹理 但是如何创建自己的纹理,然后将其应用到屏幕四边形呢?我已经做了几天了,没有任何特别的结果。我现在得到的是屏幕上的一个四边形,但纹理是整个四边形的一种颜色。但在我这里的例子中,我希望它是1/3白色和2/3黑色,这就是我想象的 我想让OpenGL尽可能的光明正大。我不打算扩展它,所以任何包含“丑陋的黑客”的答案只要有效就完全可以。我正在使用Glew、GLFW和GLM 我现在就是这样做
GLFWwindow* window;
//Create a texture that should be 1 third black and 2 thirds white?
unsigned char texdata[SCREEN_HEIGHT * SCREEN_WIDTH * 3];
for(int i=0; i<SCREEN_HEIGHT * SCREEN_WIDTH * 3; i++)
{
if(i < SCREEN_HEIGHT * SCREEN_WIDTH)
texdata[i] = 255;
else
texdata[i] = 0;
}
//cam.createTexture(texdata);
initOpenGL(window);
GLuint t = 0;
glEnable(GL_TEXTURE_2D); // Required for glBuildMipmap() to work (!)
glGenTextures( 1, &t );
glBindTexture(GL_TEXTURE_2D, t);
// Set parameters to determine how the texture is resized
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
// Set parameters to determine how the texture wraps at edges
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_REPEAT );
// Read the texture data from file and upload it to the GPU
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCREEN_WIDTH, SCREEN_HEIGHT, 0,
GL_RGB, GL_UNSIGNED_BYTE, texdata);
glGenerateMipmap(GL_TEXTURE_2D);
GLuint programID = LoadShaders("vertex.glsl", "fragment.glsl");
glUseProgram(programID);
// Create and compile our GLSL program from the shaders
Objects screenquad;
screenquad.createBox(1.0, 1.0, 0.0);
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
screenquad.render();
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
和顶点着色器:
#version 450
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec2 texcoord;
out vec2 Texcoord;
void main(){
Texcoord = texcoord;
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
编辑:
创建screenquad的内部步骤:
代码中未设置
tex
制服。大致可以这样做:
GLint texUniformLocation = glGetUniformLocation(programID, "tex");
glUniform1i(texUniformLocation, 0);
const GLfloat vertex_array_data[] = {
-xsize, -ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 0
xsize, -ysize, -zsize, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // Vertex 1
-xsize, ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // Vertex 2
xsize, ysize, -zsize, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Vertex 3
};
此处,0
in是当前活动的,默认情况下为GL\u TEXTURE0
。你可以通过
但是,正如BDL所注意到的,0
实际上是默认值,因此您可以跳过这一部分
另一个问题是纹理坐标错误。如中所示,在函数Objects::createBox
中,顶点数据为
const GLfloat vertex_array_data[] = {
-xsize, -ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 0
xsize, -ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 1
-xsize, ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 2
xsize, ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 3
-xsize, -ysize, zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 0
xsize, -ysize, zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 1
-xsize, ysize, zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 2
xsize, ysize, zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f // Vertex 3
};
每行中的最后两个浮动是纹理坐标。如您所见,它们都是0。法线也很奇怪,但无论如何都不会使用它们
我不知道长方体的纹理坐标是什么,但对于四边形,我会这样做:
GLint texUniformLocation = glGetUniformLocation(programID, "tex");
glUniform1i(texUniformLocation, 0);
const GLfloat vertex_array_data[] = {
-xsize, -ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Vertex 0
xsize, -ysize, -zsize, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // Vertex 1
-xsize, ysize, -zsize, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // Vertex 2
xsize, ysize, -zsize, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Vertex 3
};
你确定你的纹理坐标是正确的吗?如果所有纹理坐标为[0,0],则可能会产生一个完全白色的纹理。
screenquad
内部的源代码可能会有所帮助。此外,您没有将纹理绑定到着色器程序,这可能是错误的原因。我不是100%确定,但我用于创建屏幕四边形的代码我以前在项目中使用过,它会生成纹理坐标,就像您一样。我已经试着研究纹理坐标是否错误,但我对OpenGL的了解还不足以得出任何结论……我编辑并包含了创建screenquad的cpp的链接。这是我上一个项目中的一个文件,在那里效果很好。完全正确的是,应该始终设置纹理单位。但是请注意,0是采样器的默认值,因此不需要设置它。@BDL True,没有想到默认值,谢谢。好的,我尝试添加了您的代码,但没有任何效果。问题是,我在创建的“纹理”和输出之间仍然有一些联系。如果我改变其中的一个值,它会改变我看到的东西的颜色,但不会以人们期望的方式改变,而且只会改变灰度值。@JakobBertlin是的,我错了,它不应该改变任何东西。我用另一个问题更新了答案。所以如果我想硬编码,我可以在调用createBox()时将纹理坐标设置在我想要的位置?(0,0)在左下角,(1,1)在右上角,依此类推。。。。?