這是我呼叫所有繪制操作的函式。我還在函式中行內編譯著色器。當我只為每個頂點使用顏色但紋理根本不想作業時,它會正確顯示四邊形。
這是代碼:
void doGL2() {
glTranslatef(0.f, 0.f, 0.f);
const GLchar* vertShader[] = { R"glsl(
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexPos;
out vec3 col;
out vec2 texturePos;
void main()
{
gl_Position = vec4(aPos, 1.0);
col = aColor;
texturePos = aTexPos;
}
)glsl" };
const GLchar* fragShader[] = { R"glsl(
#version 330 core
out vec4 FragColor;
in vec3 col;
in vec2 texturePos;
uniform sampler2D t;
uniform vec2 iResolution;
void main()
{
vec2 uv = gl_FragCoord.xy / iResolution;
//FragColor = vec4(iResolution, 1., 1.);
FragColor = mix(vec4(col, 1.0f), texture(t, gl_FragCoord.xy / vec2(1200., 675.)), 1.);
}
)glsl" };
vShader2 = glCreateShader(GL_VERTEX_SHADER);
fShader2 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vShader2, 1, vertShader, NULL);
glCompileShader(vShader2);
GLint success;
GLchar infoLog[1024];
glGetShaderiv(vShader2, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vShader2, 1024, NULL, infoLog);
throw std::runtime_error("\noh no vert\n");
}
glShaderSource(fShader2, 1, fragShader, NULL);
glCompileShader(fShader2);
glGetShaderiv(fShader2, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fShader2, 1024, NULL, infoLog);
throw std::runtime_error("\noh no frag\n");
}
shaderProgram2 = glCreateProgram();
glAttachShader(shaderProgram2, vShader2);
glAttachShader(shaderProgram2, fShader2);
glLinkProgram(shaderProgram2);
GLfloat screen[2] = { 1200.0f, 675.0f };
glUseProgram(shaderProgram2);
glUniform2fv(glGetUniformLocation(shaderProgram2, "iResolution"), 2, screen);
glUniform1i(glGetUniformLocation(shaderProgram2, "t"), 10);
//not sure if I should do this on cleanup or now
glDeleteShader(vShader2);
glDeleteShader(fShader2);
//lets make a temporary test texture
int width, height, channels;
unsigned char* data = stbi_load("tex2.jpg", &width, &height, &channels, 0);
GLuint tempT = 1;
glActiveTexture(GL_TEXTURE10);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &tempT);
glBindTexture(GL_TEXTURE_2D, tempT);
// set texture options
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
GLfloat vertices[] = {
// positions // colors // texture positions
0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f // top right
,
0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top left
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f // top right
};
glGenVertexArrays(1, &VAO2);
glGenBuffers(1, &VBO2);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//positions
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//colors
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
//texture positions
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
float initTime = glutGet(GLUT_ELAPSED_TIME);
float prevTime = initTime;
float dt = 0.0f;
while (prevTime - initTime < 1000.0f) {
dt = (glutGet(GLUT_ELAPSED_TIME) - prevTime) / 1000.0f;
prevTime = glutGet(GLUT_ELAPSED_TIME);
glClearColor(1.f, 1.f, 1.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO2);
glBindTexture(GL_TEXTURE_2D, tempT);
glDrawArrays(GL_TRIANGLES, 0, 6);
SwapBuffers(GetDC(w));
glFlush();
}
}
出于某種原因,當我改為將紋理系結到GL_TEXTURE0
它時會顯示紋理。
編輯:我正在做進一步的編輯,因為我原來問題的內容沒有正確解決問題。似乎我無法將任何紋理系結到除GL_TEXTURE0
. 我在其他論壇上看到過這個問題,但這些問題的答案都解決了這里不存在的其他問題。如您所見,我正在嘗試將此紋理系結到GL_TEXTURE10
,但輸出全為黑色。但是,當我系結到GL_TEXTURE0
時,紋理顯示得很好。我已更改代碼以反映 Rabbid 的答案,因為這些確實是錯誤,但不是影響此問題的錯誤;代碼是最新的,反映了當前的問題。
另外,我列印tempT
了它,它總是回傳為 1,這意味著它GL_TEXTURE0
每次都系結到,盡管我呼叫了glActiveTexture()
.
uj5u.com熱心網友回復:
如果您不生成mipmap(使用glGenerateMipmap
),那么設定GL_TEXTURE_MIN_FILTER
. 由于默認過濾器是GL_NEAREST_MIPMAP_LINEAR
,因此如果您不將最小化函式更改為GL_NEAREST
或,則紋理將是“Mipmap Incomplete” GL_LINEAR
。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
此外,必須指定影像的大小 ( with
, ) 而不是 (1, 1):height
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
不保證stbi_load
生成具有 4 個顏色通道的紋理。通過顯式將 4 傳遞給最后一個引數,強制stbi_load
生成具有 4 個顏色通道的影像:
unsigned char* data = stbi_load("tex2.jpg", &width, &height, &channels, 0);
unsigned char* data = stbi_load("tex2.jpg", &width, &height, &channels, 4);
如果您使用著色器程式,則無需啟用紋理。是否使用紋理由著色器程式決定。glEnable(GL_TEXTURE_2D);
是舊版 OpenGL,洗掉它。
除了您的代碼運行良好之外,我還對其進行了測驗。但是,紋理單元的數量是有限的。確保在系統范圍內使用紋理單元。您可以使用 獲取紋理單元的數量GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
。例如:
int max_units;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_units);
std::cout << "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS " << max_units << std::endl;
另外,我列印
tempT
了它,它總是回傳為 1,這意味著它每次都系結到 GL_TEXTURE0,盡管我在glActiveTexture()
.
紋理單元與紋理物件 ID 無關。的值tempT
不指示紋理將在其中系結的紋理單元。在將紋理與 系結之前必須設定紋理單元glBindTexture
,但它對 沒有影響glGenTextures
。您可以將紋理系結到多個紋理單元,或在不同時間系結到不同的紋理單元。紋理單元是紋理物件和紋理采樣器制服之間的系結點。
如果要在著色器程式中使用紋理,則需要確保紋理系結到紋理單元,并且該單元設定為紋理采樣器統一。
我建議在系結紋理并使用它來繪制物件之前設定紋理單元:
GLint t_location = glGetUniformLocation(shaderProgram2, "t")
glUseProgram(shaderProgram2);
glUniform1i(t_location, 10);
glActiveTexture(GL_TEXTURE10);
glBindTexture(GL_TEXTURE_2D, tempT);
glDrawArrays(GL_TRIANGLES, 0, 6);
uj5u.com熱心網友回復:
在著色器中使用多個紋理有 3 個步驟
1)選擇你要系結的紋理單元
glActiveTexture(GL_TEXTURE1);
2)系結實際的Texture
glBindTexture(GL_TEXTURE_2D,&textureID);
3)告訴著色器它需要從哪個紋理單元讀取到它的sampler2D。您將統一的 int 傳遞給該變數 0 是紋理單元 0,1 是紋理單元 1,依此類推
GLInt samplerID=glGetUniformLocation(shaderProgram,"your sampler name");
glUniform1i(samplerID,1);
通過 glUniform1i 設定紋理
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/470851.html
上一篇:接受大寫和小寫命令作為輸入的程式