使用着色器时纹理不渲染?
Texture not rendering when using shaders?
我目前正在用 GLSL 测试一些东西,但现在每当我使用着色器时,我的纹理都不会显示在屏幕上。我有 2 类。尽管它在没有着色器的情况下也能工作...
主要Class
public class Main {
private static final int WIDTH = 1280;
private static final int HEIGHT = 720;
private static int shaderProgram;
private static int vertexShader;
private static int fragmentShader;
private static Terrain terrain;
public static void main(String[] args) {
initDisplay();
initGL();
terrain = new Terrain();
terrain.createTerrain();
createShader();
gameLoop();
removeShader();
}
private static void gameLoop() {
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
terrain.drawTerrain();
glUseProgram(0);
Display.update();
Display.sync(60);
}
}
private static void initGL() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, 0, HEIGHT, -1, 1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glClearColor(0, 0, 0, 1);
}
private static void initDisplay() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
}
private static void createShader() {
shaderProgram = glCreateProgram();
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
StringBuilder vertexShaderSource = new StringBuilder();
StringBuilder fragmentShaderSource = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader("src/me/mateo226/shaders/vertexShader.txt"));
String line;
while ((line = reader.readLine()) != null) {
vertexShaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Vertex shader wasn't loaded properly!");
Display.destroy();
System.exit(1);
}
try {
BufferedReader reader = new BufferedReader(new FileReader("src/me/mateo226/shaders/fragmentShader.txt"));
String line;
while ((line = reader.readLine()) != null) {
fragmentShaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Fragment shader wasn't loaded properly!");
Display.destroy();
System.exit(1);
}
glShaderSource(vertexShader, vertexShaderSource);
glCompileShader(vertexShader);
if (glGetShader(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Vertex shader not compiled!");
}
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
if (glGetShader(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Fragment shader not compiled!");
}
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glValidateProgram(shaderProgram);
}
private static void removeShader() {
glDeleteProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
Display.destroy();
}
}
地形Class
public class Terrain {
private static List<Tile> tiles = new ArrayList<Tile>();
public Terrain() {
}
public void createTerrain() {
Random rand = new Random();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 15; j++) {
int r = rand.nextInt(2);
tiles.add(new Tile(i * 64, j * 64, r));
}
}
}
public void drawTerrain() {
for (Tile t : tiles) {
t.draw();
}
}
}
class Tile {
int type = 0;
private float x = 0;
private float y = 0;
private float width = 64;
private float height = 64;
private Texture tex;
public Tile(float x, float y, int type) {
this.type = type;
this.x = x;
this.y = y;
try {
if (this.type == 1) {
tex = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/grass.png")));
} else {
tex = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/grass.png")));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void draw() {
tex.bind();
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0);
glVertex2f(x, y);
glTexCoord2f(0, 1);
glVertex2f(x, y + height);
glTexCoord2f(1, 1);
glVertex2f(x + width, y + height);
glTexCoord2f(1, 0);
glVertex2f(x + width, y);
}
glEnd();
}
}
虽然看起来代码很多,但实际上不是,只是一个简单的程序。但是我仍然无法弄清楚是什么让它不起作用。我的顶点着色器只有:
gl_Position = ftransform();
我尝试将 gl_FragColor
添加到片段着色器,但它没有帮助。
干杯!
如果您不想对纹理做任何事情,例如光照,你只需要在片段着色器中将 texture2D(TexSampler, TexCoord)
分配给 gl_FragColor
。
这是因为片段着色器将处理屏幕上的每个像素(片段)(在当前着色器程序中)。
如果您不为 gl_FragColor
变量分配任何值,则不会绘制任何内容。你想要的是将你的纹理(一堆像素)分配给 gl_FragColor
并且你很高兴。
我目前正在用 GLSL 测试一些东西,但现在每当我使用着色器时,我的纹理都不会显示在屏幕上。我有 2 类。尽管它在没有着色器的情况下也能工作...
主要Class
public class Main {
private static final int WIDTH = 1280;
private static final int HEIGHT = 720;
private static int shaderProgram;
private static int vertexShader;
private static int fragmentShader;
private static Terrain terrain;
public static void main(String[] args) {
initDisplay();
initGL();
terrain = new Terrain();
terrain.createTerrain();
createShader();
gameLoop();
removeShader();
}
private static void gameLoop() {
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
terrain.drawTerrain();
glUseProgram(0);
Display.update();
Display.sync(60);
}
}
private static void initGL() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, 0, HEIGHT, -1, 1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glClearColor(0, 0, 0, 1);
}
private static void initDisplay() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
}
private static void createShader() {
shaderProgram = glCreateProgram();
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
StringBuilder vertexShaderSource = new StringBuilder();
StringBuilder fragmentShaderSource = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader("src/me/mateo226/shaders/vertexShader.txt"));
String line;
while ((line = reader.readLine()) != null) {
vertexShaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Vertex shader wasn't loaded properly!");
Display.destroy();
System.exit(1);
}
try {
BufferedReader reader = new BufferedReader(new FileReader("src/me/mateo226/shaders/fragmentShader.txt"));
String line;
while ((line = reader.readLine()) != null) {
fragmentShaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Fragment shader wasn't loaded properly!");
Display.destroy();
System.exit(1);
}
glShaderSource(vertexShader, vertexShaderSource);
glCompileShader(vertexShader);
if (glGetShader(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Vertex shader not compiled!");
}
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
if (glGetShader(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Fragment shader not compiled!");
}
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glValidateProgram(shaderProgram);
}
private static void removeShader() {
glDeleteProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
Display.destroy();
}
}
地形Class
public class Terrain {
private static List<Tile> tiles = new ArrayList<Tile>();
public Terrain() {
}
public void createTerrain() {
Random rand = new Random();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 15; j++) {
int r = rand.nextInt(2);
tiles.add(new Tile(i * 64, j * 64, r));
}
}
}
public void drawTerrain() {
for (Tile t : tiles) {
t.draw();
}
}
}
class Tile {
int type = 0;
private float x = 0;
private float y = 0;
private float width = 64;
private float height = 64;
private Texture tex;
public Tile(float x, float y, int type) {
this.type = type;
this.x = x;
this.y = y;
try {
if (this.type == 1) {
tex = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/grass.png")));
} else {
tex = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/grass.png")));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void draw() {
tex.bind();
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0);
glVertex2f(x, y);
glTexCoord2f(0, 1);
glVertex2f(x, y + height);
glTexCoord2f(1, 1);
glVertex2f(x + width, y + height);
glTexCoord2f(1, 0);
glVertex2f(x + width, y);
}
glEnd();
}
}
虽然看起来代码很多,但实际上不是,只是一个简单的程序。但是我仍然无法弄清楚是什么让它不起作用。我的顶点着色器只有:
gl_Position = ftransform();
我尝试将 gl_FragColor
添加到片段着色器,但它没有帮助。
干杯!
如果您不想对纹理做任何事情,例如光照,你只需要在片段着色器中将 texture2D(TexSampler, TexCoord)
分配给 gl_FragColor
。
这是因为片段着色器将处理屏幕上的每个像素(片段)(在当前着色器程序中)。
如果您不为 gl_FragColor
变量分配任何值,则不会绘制任何内容。你想要的是将你的纹理(一堆像素)分配给 gl_FragColor
并且你很高兴。