有纹理的三角形,只渲染一种颜色
Textured triangle, rendering only one color
在这个例子中,我尝试使用 lwjgl 在 java 中渲染一个简单的带纹理的三角形,但我根本不明白为什么它渲染三角形填充一种颜色。
颜色似乎是整个纹理的平均颜色或只是纹理的一个像素,如果我将图像设为例如绿色,它会使三角形呈现绿色。
在此先感谢您的帮助。
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryUtil.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import org.joml.Matrix4f;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import de.matthiasmann.twl.utils.PNGDecoder;
import de.matthiasmann.twl.utils.PNGDecoder.Format;
public class TEST
{
public int WIDTH = 1000;
public int HEIGHT = 1000;
public float vertices[] = new float[]
{
//COORDINATES
0.0f, 0.8f, 0.0f,1.0f,
//COLOR NOT USED
0.0f,1.0f,0.0f,1.0f,
//TEXTURE COORDINATES
0.5f, 1.0f,
//COORDINATES
-0.8f,-0.8f, 0.0f,1.0f,
//COLOR NOT USED
1.0f,0.0f,0.0f,1.0f,
//TEXTURE COORDINATES
0.0f, 0.0f,
//COORDINATES
0.8f,-0.8f, 0.0f,1.0f,
//COLOR NOT USED
0.0f,0.0f,1.0f,1.0f,
//TEXTURE COORDINATES
1.0f, 0.0f
};
public TEST()
{
}
public int start() throws IOException
{
glfwInit();
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GL11.GL_TRUE);
long window = glfwCreateWindow(WIDTH, HEIGHT, "HAHA", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
GL.createCapabilities();
//CALLBACKS
GLFWKeyCallback keycallback = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
if(key==GLFW_KEY_ESCAPE&&action==GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
};
glfwSetKeyCallback(window,keycallback );
GLFWErrorCallback errorcallback = new GLFWErrorCallback()
{
@Override
public void invoke(int error, long description)
{
System.out.println("ERROR CODE: " + error + " ERROR DESCRITPION: "+description);
}
};
glfwSetErrorCallback(errorcallback);
GLFWWindowSizeCallback windowsizecallback = new GLFWWindowSizeCallback()
{
@Override
public void invoke(long window, int width, int height)
{
glViewport(0, 0, width, height);
System.out.println(width+" "+height);
}
};
glfwSetWindowSizeCallback(window, windowsizecallback);
//////////////////////////
int VAO = glGenVertexArrays();
glBindVertexArray(VAO);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
floatBuffer.clear();
floatBuffer.put(vertices);
floatBuffer.flip();
int VBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, floatBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 40, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 40, 16);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, false, 40, 24);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
///////////////////////
///////////////////////
LoadFile loader = new LoadFile("res/shader.vs", "res/shader.frag");
int vertexshader = glCreateShader(GL_VERTEX_SHADER);
int fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexshader, loader.readVertex());
glShaderSource(fragmentshader, loader.readFragment());
glCompileShader(vertexshader);
glCompileShader(fragmentshader);
System.out.println(glGetShaderInfoLog(vertexshader));
System.out.println(glGetShaderInfoLog(fragmentshader));
int program = glCreateProgram();
glAttachShader(program, vertexshader);
glAttachShader(program, fragmentshader);
glLinkProgram(program);
glDeleteShader(vertexshader);
glDeleteShader(fragmentshader);
System.out.println(glGetProgramInfoLog(program));
///////////////////////////
int texture1 = glGenTextures();
InputStream texture1inputstream = new FileInputStream("res/container2.png");
PNGDecoder texture1decoder = new PNGDecoder(texture1inputstream);
ByteBuffer texture1buffer = ByteBuffer.allocateDirect(4*texture1decoder.getWidth()*texture1decoder.getHeight()).order(ByteOrder.nativeOrder());
texture1decoder.decode(texture1buffer, texture1decoder.getWidth()*4, Format.RGBA);
texture1buffer.flip();
glBindTexture(GL_TEXTURE_2D, texture1);
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_RGBA,
texture1decoder.getWidth(),
texture1decoder.getHeight(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
texture1buffer
);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
int textureloc = glGetUniformLocation(program, "texture");
//MAKE UNIFORM SETTER
UniformSetter uniformsetter = new UniformSetter(program, "model", "projection","view");
/////////////////////
glEnable(GL_DEPTH_TEST);
boolean running=true;
while(running&&glfwWindowShouldClose(window)==GLFW_FALSE)
{
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glUseProgram(program);
glBindVertexArray(VAO);
///////////////////////
for(int a = 0;a<4;a++)
{
//MAKE MATRIX MODEL
Matrix4f model = new Matrix4f();
model.translate(0.0f,0.0f,0.0f);
float xang = 0f;
float yang = 0f;
float zang = 0f;
model.rotate((float) Math.toRadians(xang), 1.0f, 0.0f, 0.0f);
model.rotate((float) Math.toRadians(yang), 0.0f, 1.0f, 0.0f);
model.rotate((float) Math.toRadians(zang), 0.0f, 0.0f, 1.0f);
model.scale(0.5f);
uniformsetter.setModel(model);
////////////////////
//MAKE MATRIX VIEW
Matrix4f view = new Matrix4f();
view.lookAt(0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
uniformsetter.setView(view);
//////////////////
//MAKE MATRIX PROJECTION
Matrix4f projection = new Matrix4f();
projection.ortho(-1.0f, 1.0f, -1.0f, 1.0f,1.0f,-1.0f);
uniformsetter.setProjection(projection);
/////////////////////////
//ACTIVATE AND BIND TEXTURE
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(textureloc, 0);
///////////////////////////
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindTexture(GL_TEXTURE_2D, 0);
}
///////////////////////
glBindVertexArray(0);
glUseProgram(0);
glfwSwapInterval(1);
glfwSwapBuffers(window);
}
System.out.println(glGetError());
glfwTerminate();
return 0;
}
}
顶点着色器:
#version 440
layout (location = 0) in vec4 position;
//NOT USED layout (location = 1) in vec4 colorin;
layout (location = 2) in vec2 texturecoordiantesin;
//NOT USED out vec4 colorout;
out vec2 texturecoordinatesout;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection*view*model*position;
//NOT USED colorout=colorin;
}
片段着色器:
#version 440
out vec4 color;
//NOT USED in vec4 colorout;
in vec2 texturecoordinatesout;
uniform sampler2D texture;
void main()
{
color = texture2D(texture,texturecoordinatesout);
}
您缺少顶点着色器中纹理坐标的传播。在顶点着色器的任何地方添加:
texturecoordinatesout = texturecoordinatesin;
另外,你在设置顶点数组指针时犯了一个错误。属性 2 的 glVertexAttribPointer 的最后一个参数应该是 32。位置的 4 个浮点偏移和颜色的 4 个浮点偏移总共是 8 个浮点偏移,即 32 个字节:
glVertexAttribPointer(0, 4, GL_FLOAT, false, 40, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 40, 16);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, false, 40, 32);
glEnableVertexAttribArray(2);
在这个例子中,我尝试使用 lwjgl 在 java 中渲染一个简单的带纹理的三角形,但我根本不明白为什么它渲染三角形填充一种颜色。
颜色似乎是整个纹理的平均颜色或只是纹理的一个像素,如果我将图像设为例如绿色,它会使三角形呈现绿色。
在此先感谢您的帮助。
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryUtil.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import org.joml.Matrix4f;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import de.matthiasmann.twl.utils.PNGDecoder;
import de.matthiasmann.twl.utils.PNGDecoder.Format;
public class TEST
{
public int WIDTH = 1000;
public int HEIGHT = 1000;
public float vertices[] = new float[]
{
//COORDINATES
0.0f, 0.8f, 0.0f,1.0f,
//COLOR NOT USED
0.0f,1.0f,0.0f,1.0f,
//TEXTURE COORDINATES
0.5f, 1.0f,
//COORDINATES
-0.8f,-0.8f, 0.0f,1.0f,
//COLOR NOT USED
1.0f,0.0f,0.0f,1.0f,
//TEXTURE COORDINATES
0.0f, 0.0f,
//COORDINATES
0.8f,-0.8f, 0.0f,1.0f,
//COLOR NOT USED
0.0f,0.0f,1.0f,1.0f,
//TEXTURE COORDINATES
1.0f, 0.0f
};
public TEST()
{
}
public int start() throws IOException
{
glfwInit();
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GL11.GL_TRUE);
long window = glfwCreateWindow(WIDTH, HEIGHT, "HAHA", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
GL.createCapabilities();
//CALLBACKS
GLFWKeyCallback keycallback = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
if(key==GLFW_KEY_ESCAPE&&action==GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}
};
glfwSetKeyCallback(window,keycallback );
GLFWErrorCallback errorcallback = new GLFWErrorCallback()
{
@Override
public void invoke(int error, long description)
{
System.out.println("ERROR CODE: " + error + " ERROR DESCRITPION: "+description);
}
};
glfwSetErrorCallback(errorcallback);
GLFWWindowSizeCallback windowsizecallback = new GLFWWindowSizeCallback()
{
@Override
public void invoke(long window, int width, int height)
{
glViewport(0, 0, width, height);
System.out.println(width+" "+height);
}
};
glfwSetWindowSizeCallback(window, windowsizecallback);
//////////////////////////
int VAO = glGenVertexArrays();
glBindVertexArray(VAO);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
floatBuffer.clear();
floatBuffer.put(vertices);
floatBuffer.flip();
int VBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, floatBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 40, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 40, 16);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, false, 40, 24);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
///////////////////////
///////////////////////
LoadFile loader = new LoadFile("res/shader.vs", "res/shader.frag");
int vertexshader = glCreateShader(GL_VERTEX_SHADER);
int fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexshader, loader.readVertex());
glShaderSource(fragmentshader, loader.readFragment());
glCompileShader(vertexshader);
glCompileShader(fragmentshader);
System.out.println(glGetShaderInfoLog(vertexshader));
System.out.println(glGetShaderInfoLog(fragmentshader));
int program = glCreateProgram();
glAttachShader(program, vertexshader);
glAttachShader(program, fragmentshader);
glLinkProgram(program);
glDeleteShader(vertexshader);
glDeleteShader(fragmentshader);
System.out.println(glGetProgramInfoLog(program));
///////////////////////////
int texture1 = glGenTextures();
InputStream texture1inputstream = new FileInputStream("res/container2.png");
PNGDecoder texture1decoder = new PNGDecoder(texture1inputstream);
ByteBuffer texture1buffer = ByteBuffer.allocateDirect(4*texture1decoder.getWidth()*texture1decoder.getHeight()).order(ByteOrder.nativeOrder());
texture1decoder.decode(texture1buffer, texture1decoder.getWidth()*4, Format.RGBA);
texture1buffer.flip();
glBindTexture(GL_TEXTURE_2D, texture1);
glTexImage2D
(
GL_TEXTURE_2D,
0,
GL_RGBA,
texture1decoder.getWidth(),
texture1decoder.getHeight(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
texture1buffer
);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
int textureloc = glGetUniformLocation(program, "texture");
//MAKE UNIFORM SETTER
UniformSetter uniformsetter = new UniformSetter(program, "model", "projection","view");
/////////////////////
glEnable(GL_DEPTH_TEST);
boolean running=true;
while(running&&glfwWindowShouldClose(window)==GLFW_FALSE)
{
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glUseProgram(program);
glBindVertexArray(VAO);
///////////////////////
for(int a = 0;a<4;a++)
{
//MAKE MATRIX MODEL
Matrix4f model = new Matrix4f();
model.translate(0.0f,0.0f,0.0f);
float xang = 0f;
float yang = 0f;
float zang = 0f;
model.rotate((float) Math.toRadians(xang), 1.0f, 0.0f, 0.0f);
model.rotate((float) Math.toRadians(yang), 0.0f, 1.0f, 0.0f);
model.rotate((float) Math.toRadians(zang), 0.0f, 0.0f, 1.0f);
model.scale(0.5f);
uniformsetter.setModel(model);
////////////////////
//MAKE MATRIX VIEW
Matrix4f view = new Matrix4f();
view.lookAt(0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
uniformsetter.setView(view);
//////////////////
//MAKE MATRIX PROJECTION
Matrix4f projection = new Matrix4f();
projection.ortho(-1.0f, 1.0f, -1.0f, 1.0f,1.0f,-1.0f);
uniformsetter.setProjection(projection);
/////////////////////////
//ACTIVATE AND BIND TEXTURE
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(textureloc, 0);
///////////////////////////
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindTexture(GL_TEXTURE_2D, 0);
}
///////////////////////
glBindVertexArray(0);
glUseProgram(0);
glfwSwapInterval(1);
glfwSwapBuffers(window);
}
System.out.println(glGetError());
glfwTerminate();
return 0;
}
}
顶点着色器:
#version 440
layout (location = 0) in vec4 position;
//NOT USED layout (location = 1) in vec4 colorin;
layout (location = 2) in vec2 texturecoordiantesin;
//NOT USED out vec4 colorout;
out vec2 texturecoordinatesout;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection*view*model*position;
//NOT USED colorout=colorin;
}
片段着色器:
#version 440
out vec4 color;
//NOT USED in vec4 colorout;
in vec2 texturecoordinatesout;
uniform sampler2D texture;
void main()
{
color = texture2D(texture,texturecoordinatesout);
}
您缺少顶点着色器中纹理坐标的传播。在顶点着色器的任何地方添加:
texturecoordinatesout = texturecoordinatesin;
另外,你在设置顶点数组指针时犯了一个错误。属性 2 的 glVertexAttribPointer 的最后一个参数应该是 32。位置的 4 个浮点偏移和颜色的 4 个浮点偏移总共是 8 个浮点偏移,即 32 个字节:
glVertexAttribPointer(0, 4, GL_FLOAT, false, 40, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 40, 16);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, false, 40, 32);
glEnableVertexAttribArray(2);