[英]Why is my texture being rendered black?
我正在使用LWJGL 3編寫OpenGL應用程序。我能夠很好地渲染純色,但是一旦嘗試引入紋理采樣器,我所看到的只是黑色。
具體來說, 片段着色器中texture(texUnit,DataIn.texCoord)返回的值始終為vec4(0,0,0,1) 。
我什至嘗試用所有255手動填充傳遞給glTexImage2D的緩沖區,但得到的結果相同。 在這一點上,我完全陷入了困境!
初始化:
private void initGL() {
// Enable depth buffer
GL11.glEnable(GL11.GL_DEPTH_TEST);
// Set background colour
GL11.glClearColor(0.2f, 0.2f, 0.4f, 0.0f);
// Set viewport to the whole window
GL11.glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
// Enable alpha blending (transparency)
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// Enable back-face culling
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_BACK);
// Use linear filtering for texture scaling
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
// Clamp texture co-ordinates between 0 and 1
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
int errorCode = GL11.glGetError();
if (errorCode != GL11.GL_NO_ERROR) {
throw new RuntimeException(
"OpenGL error " + String.valueOf(errorCode)
+ " during initialisation");
}
}
紋理加載:
String filename = "terrain.png";
// Read image into a ByteBuffer
IntBuffer w = BufferUtils.createIntBuffer(1);
IntBuffer h = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer texelData =
STBImage.stbi_load(GFX_DIR + filename, w, h, comp, 4);
if (texelData == null) {
throw new RuntimeException("Error loading " + filename + ": " +
STBImage.stbi_failure_reason());
}
int width = w.get();
int height = h.get();
// Generate texture ID
terrainTexId = GL11.glGenTextures();
// Pass our texture to the shader
GL11.glBindTexture(GL11.GL_TEXTURE_2D, terrainTexId);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height,
0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, texelData);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); // Deselect
int errorCode = GL11.glGetError();
if (errorCode != GL11.GL_NO_ERROR) {
throw new RuntimeException(
"OpenGL error " + String.valueOf(errorCode)
+ " loading texture: " + filename);
}
渲染:
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// Use our shader program
GL20.glUseProgram(Shaders.programId);
// Set the projection matrix
FloatBuffer fb = BufferUtils.createFloatBuffer(16);
projection.setPerspective(
camera.getFovY(),
window.getAspectRatio(),
Camera.Z_NEAR,
Camera.Z_FAR);
GL20.glUniformMatrix4fv(
Shaders.projectionLoc, false, projection.get(fb));
// Set the model-view matrix.
modelView.setLookAt(
camera.getPos(),
camera.getTarget(),
camera.getUpVector());
GL20.glUniformMatrix4fv(Shaders.modelViewLoc, false, modelView.get(fb));
// Bind our texture to texture unit 0
GL13.glActiveTexture(GL13.GL_TEXTURE0 + 0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, terrainTexId);
// Tell the shader to sample from texture unit 0.
// This is the default anyway.
GL20.glUniform1i(Shaders.texUnitLoc, 0);
// Pass the lighting information to the shader
fb = BufferUtils.createFloatBuffer(3);
GL20.glUniform3fv(Shaders.lightAmbientColourLoc,
lighting.getAmbientColour().get(fb));
GL20.glUniform1f(Shaders.lightAmbientIntensityLoc,
lighting.getAmbientIntensity());
GL20.glUniform3fv(Shaders.lightDiffuseColourLoc,
lighting.getDiffuseColour().get(fb));
GL20.glUniform3fv(Shaders.lightDiffuseAngleLoc,
lighting.getDiffuseVector().get(fb));
GL20.glUniform1f(Shaders.lightDiffuseIntensityLoc,
lighting.getDiffuseIntensity());
// Bind to the VAO that has all the information about the vertices
GL30.glBindVertexArray(terrainSection.getVaoId());
GL20.glEnableVertexAttribArray(Shaders.PARAM_VERTEX);
GL20.glEnableVertexAttribArray(Shaders.PARAM_VERTEX_NORMAL);
GL20.glEnableVertexAttribArray(Shaders.PARAM_MATERIAL_AMBIENT_COLOUR);
GL20.glEnableVertexAttribArray(Shaders.PARAM_MATERIAL_DIFFUSE_COLOUR);
GL20.glEnableVertexAttribArray(Shaders.PARAM_TEXTURE_COORDS);
// Draw the vertices
GL11.glDrawArrays(
GL11.GL_TRIANGLES, 0, TerrainSection.NUM_VERTICES_FOR_BUFFERS);
// Put everything back to default (deselect)
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL20.glDisableVertexAttribArray(Shaders.PARAM_VERTEX);
GL20.glDisableVertexAttribArray(Shaders.PARAM_VERTEX_NORMAL);
GL20.glDisableVertexAttribArray(Shaders.PARAM_MATERIAL_AMBIENT_COLOUR);
GL20.glDisableVertexAttribArray(Shaders.PARAM_MATERIAL_DIFFUSE_COLOUR);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
頂點着色器:
#version 330
uniform mat4 projection;
uniform mat4 modelView;
uniform vec3 lightAmbientColour;
uniform float lightAmbientIntensity;
uniform vec3 lightDiffuseAngle;
uniform vec3 lightDiffuseColour;
uniform float lightDiffuseIntensity;
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 vertexNormal;
layout(location = 2) in vec3 materialAmbientColour;
layout(location = 3) in vec3 materialDiffuseColour;
layout(location = 4) in vec2 texCoord;
out Data {
vec4 colour;
vec2 texCoord;
} DataOut;
void main(void) {
gl_Position = projection * modelView * vec4(vertex, 1.0);
vec3 ambientComponent = lightAmbientIntensity *
(lightAmbientColour * materialAmbientColour);
ambientComponent = clamp(ambientComponent, 0.0, 1.0);
// The dot product gives us a measure of how "aligned" 2 vectors are,
// between 0 and 1. If the light direction and the vertex normal are
// well-aligned, the vertex should appear more brightly-lit.
float dotProduct = dot(lightDiffuseAngle, vertexNormal);
if (dotProduct < 0){
dotProduct = 0;
}
vec3 diffuseComponent = lightDiffuseIntensity * dotProduct *
(lightDiffuseColour * materialDiffuseColour);
diffuseComponent = clamp(diffuseComponent, 0.0, 1.0);
vec3 colourResult = max(diffuseComponent, ambientComponent);
DataOut.colour = vec4(colourResult, 1.0);
DataOut.texCoord = texCoord;
}
片段着色器:
#version 330
uniform sampler2D texUnit;
in Data {
vec4 colour;
vec2 texCoord;
} DataIn;
out vec4 fragColour;
void main() {
if (DataIn.colour.w == 0.0){
// Discard transparent fragments, so they don't affect the depth buffer
discard;
}
vec4 texColour = texture(texUnit, DataIn.texCoord);
fragColour = DataIn.colour * texColour;
}
你應該:
glTexParameteri
移至紋理加載/初始化中,因為它是紋理的一部分。 或使用采樣器 glActiveTexture
前glBindTexture
紋理加載 Shaders.texUnitLoc
!= -1 glVertexAttribPointer
glEnableVertexAttribArray
和glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
因為那些是vao的一部分 GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
當綁定vao時,將導致綁定的vao中的ebo / ibo解除綁定 glDrawArrays
),則無需取消綁定任何ebo / ibo enableVertexAttribArray
,因此還應該調用glDisableVertexAttribArray(Shaders.PARAM_TEXTURE_COORDS);
在着色器中定義相同的語義,例如:
#define VERTEX 0
#define VERTEX_NORMAL 1
#define MATERIAL_AMBIENT_COLOUR 2
#define MATERIAL_DIFFUSE_COLOUR 3
#define TEXTURE_COORDS 4
並將它們相應地分配到各個location
fragColour = texColour
寫上純色的fragColour = texColour
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.