简体   繁体   English

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

[英]Creating raw OpenGL texture data (C++)

So basically I'm trying to create my own texture in code. 所以基本上我想在代码中创建自己的纹理。 Specifically I'm writing a ray tracer and want to display the result as a texture rendered to a quad on the screen. 具体来说,我正在编写光线跟踪器,并希望将结果显示为渲染到屏幕上的四边形的纹理。

But how does one exactly go about creating your own texture and then applying it to the screen quad? 但是,如何准确地创建自己的纹理,然后将其应用于屏幕四边形呢? I've been at this for days without any particular results. 我已经待了好几天没有任何特别的结果了。 What I get now is a quad onto the screen but the texture is one color for the entire quad. 我现在得到的是屏幕上的一个四边形,但是纹理是整个四边形的一种颜色。 But in my example here I want it to be 1/3 white and 2/3 black and this is how I imagine it to be done. 但是在我的示例中,我希望它是1/3白色和2/3黑色,这就是我想象的那样。

I want to keep OpenGL as barebone as possible. 我想让OpenGL尽可能保持准系统。 I'm not planning on expanding it so any answer that contains an "ugly hack" is totally fine for as long as it works. 我不打算对其进行扩展,因此只要它可行,任何包含“丑陋hack”的答案都是可以的。 I'm using Glew, GLFW and GLM. 我正在使用Glew,GLFW和GLM。

This is how I'm currently doing it: 这是我目前正在做的事情:

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 );

GLSL shader code: GLSL着色器代码:

#version 450

in vec2 Texcoord;

out vec4 outColor;

uniform sampler2D tex;

void main(){
    outColor = texture(tex, Texcoord);
}

And the vertex shader: 以及顶点着色器:

#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;
}

EDIT: Internals of creating the screenquad: https://raw.githubusercontent.com/ddavidtran/Fishualization/master/OpenGL/Objects.cpp 编辑:创建screenquad的内部: https ://raw.githubusercontent.com/ddavidtran/Fishualization/master/OpenGL/Objects.cpp

The tex uniform is not set in the code. 代码中未设置tex制服。 It could be done roughly like this: 可以大致这样完成:

GLint texUniformLocation = glGetUniformLocation(programID, "tex");
glUniform1i(texUniformLocation, 0);

Here, 0 in glUniform1i is the current active texture image unit , which is GL_TEXTURE0 by default. 在这里, glUniform1i中的0是当前的活动纹理图像单位 ,默认情况下为GL_TEXTURE0 You can change it via glActiveTexture . 您可以通过glActiveTexture对其进行更改

However, as BDL noticed, 0 is actually the default value, so you may skip this part. 但是,正如BDL所注意到的, 0实际上是默认值,因此您可以跳过此部分。

Another problem is that your texture coordinates are wrong. 另一个问题是纹理坐标错误。 As seen in the file you linked , in function Objects::createBox , the vertex data is 链接文件中可以看到,在函数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
};

The last two floats in each row are the texture coordinates. 每行的最后两个浮点是纹理坐标。 As you can see, all of them are 0. The normals are also strange, but you don't use them anyway. 如您所见,它们全都是0。 法线也很奇怪,但是您还是不要使用它们。

I have no idea what texture coordinates for a box you would like, but for a quad I'd do something like this: 我不知道您想要一个盒子的纹理坐标是什么,但是对于四边形,我会做这样的事情:

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
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM