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
C++ 创建原始OpenGL纹理数据(C+;+;)_C++_Opengl_Glsl_Glew - Fatal编程技术网

C++ 创建原始OpenGL纹理数据(C+;+;)

C++ 创建原始OpenGL纹理数据(C+;+;),c++,opengl,glsl,glew,C++,Opengl,Glsl,Glew,所以我基本上是在代码中创建自己的纹理。具体来说,我正在编写一个光线跟踪器,并希望将结果显示为渲染到屏幕上四边形的纹理 但是如何创建自己的纹理,然后将其应用到屏幕四边形呢?我已经做了几天了,没有任何特别的结果。我现在得到的是屏幕上的一个四边形,但纹理是整个四边形的一种颜色。但在我这里的例子中,我希望它是1/3白色和2/3黑色,这就是我想象的 我想让OpenGL尽可能的光明正大。我不打算扩展它,所以任何包含“丑陋的黑客”的答案只要有效就完全可以。我正在使用Glew、GLFW和GLM 我现在就是这样做

所以我基本上是在代码中创建自己的纹理。具体来说,我正在编写一个光线跟踪器,并希望将结果显示为渲染到屏幕上四边形的纹理

但是如何创建自己的纹理,然后将其应用到屏幕四边形呢?我已经做了几天了,没有任何特别的结果。我现在得到的是屏幕上的一个四边形,但纹理是整个四边形的一种颜色。但在我这里的例子中,我希望它是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)在右上角,依此类推。。。。?