Вывод спрайта и его прозрачность
afq Дата: Вторник, 03 Июля 2018, 06:18 | Сообщение # 1
Разработчик
Сейчас нет на сайте
Никак не могу понять, можно ли сделать прозрачность спрайта без шейдеров, а то я никак не могу понять как шейдеры использовать, почему нужно то и то писать и где вся инфа по шейдерам есть, раз уж на то пошло. Проблема вот в чем. Далее будет предоставлен код, это для 2d. Если я не устанавливаю glOrtho, то спрайт рисуется, но большого размера. Если установлю glOrtho, то рисуется только черный квадрат. Ещё была функция какая то, уже не помню как называется, он ещё двигается с помощью glRasterpos, она тоже рисует там где должно быть прозрачно, черным цветом. Из-за того, что не устанавливаю glortho, приходится координаты ставить в 0, 1 и тому подобное. Вот код.Код
#include "Sprite.hpp" Sprite::Sprite ( ) { } void Sprite::load ( long pos ) { init_texture ( ); std::FILE *fd = std::fopen ( "data", "r" ); if ( !fd ) { std::perror ( "sprite load" ); exit ( EXIT_FAILURE ); } std::fseek ( fd, pos, SEEK_SET ); std::fread ( &width, sizeof ( unsigned int ), 1, fd ); std::fread ( &height, sizeof ( unsigned int ), 1, fd ); std::fread ( &max_pixels, sizeof ( unsigned int ), 1, fd ); pixels = new unsigned char [ max_pixels ]; // for ( int i = 0; i < max_pixels; i++ ) { std::fread ( &pixels[0] , sizeof ( unsigned char ), max_pixels, fd ); // } #if 0 vertices = new float [ 8 ] { 0, 64, 0, 0, 64, 0, 64, 64 }; texture = new float [ 8 ] { 64, 0, 0, 0, 0, 64, 64, 64 }; #endif #if 1 vertices = new float [ 8 ] { 0, 1, 0, 0, 1, 0, 1, 1 }; texture = new float [ 8 ] { 1, 0, 0, 0, 0, 1, 1, 1 }; #endif indices.length = 6; indices.v = new unsigned char [ indices.length ] { 0, 1, 2, 0, 2, 3 }; std::fclose ( fd ); } void Sprite::render ( ) { #if 1 glEnable ( GL_TEXTURE_2D ); glBindTexture ( GL_TEXTURE_2D, tex ); glPushMatrix ( ); #if 0 glFrontFace ( GL_CCW ); glEnable ( GL_CULL_FACE ); glCullFace ( GL_BACK ); #endif glEnableClientState ( GL_VERTEX_ARRAY ); glEnableClientState ( GL_TEXTURE_COORD_ARRAY ); glVertexPointer ( 2, GL_FLOAT, 0, vertices ); glTexCoordPointer ( 2, GL_FLOAT, 0, texture ); glDrawElements ( GL_TRIANGLES, indices.length, GL_UNSIGNED_BYTE, indices.v ); glDisableClientState ( GL_VERTEX_ARRAY ); glDisableClientState ( GL_TEXTURE_COORD_ARRAY ); glDisable ( GL_CULL_FACE ); glTranslatef ( 0, 0, 2 ); glPopMatrix ( ); glFlush ( ); glDisable ( GL_TEXTURE_2D ); #endif } void Sprite::init_texture ( ) { glGenTextures ( 1, &tex ); glBindTexture ( GL_TEXTURE_2D, tex ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER ); glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); glEnable ( GL_TEXTURE_2D ); }
Snake174 Дата: Вторник, 03 Июля 2018, 07:00 | Сообщение # 2
участник
Сейчас нет на сайте
Мне кажется, или init_texture ( ); нужно вызывать после того, как ты заполнишь массив pixels?
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
afq Дата: Вторник, 03 Июля 2018, 07:12 | Сообщение # 3
Разработчик
Сейчас нет на сайте
Snake174 , да ты совершенно прав. Я это поменял в последний момент, подумал что в конструкторе лучше не создавать ничего, потому как если выясниться что файл отсутствует или другая ошибка, то освободить память я не смогу, потому что конструктор не выполнится до конца, а отсюда и то, что деструктор тогда не вызовется. Я init_texture перенес без задней мысли из конструктора в начало фунцкии и забыл о приоритетах, но если поместить эту функцию в конец, то будет работать, но так как я написал в начале темы, то есть без прозрачности и glOrtho.
Snake174 Дата: Вторник, 03 Июля 2018, 07:31 | Сообщение # 4
участник
Сейчас нет на сайте
Код вывода спрайта покажи. Вот процедура загрузки png изображений из моего старого проекта. Обрати внимание на цикл.Код
void CubeMapViewer::loadPNGTexture( const QString &fileName, unsigned int &id ) { QImage image = QImage( fileName ); glGenTextures( 1, &id ); glBindTexture( GL_TEXTURE_2D, id ); GLuint *pTexData = new GLuint[ image.width() * image.height() ]; GLuint *sdata = (GLuint *)image.bits(); GLuint *tdata = pTexData; for (int y = 0; y < image.height(); ++y) { for (int x = 0; x < image.width(); ++x) { *tdata = ((*sdata & 255) << 16) | (((*sdata >> 8) & 255) << 8) | (((*sdata >> 16) & 255) << 0) | (((*sdata >> 24) & 255) << 24); ++sdata; ++tdata; } } glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); delete[] pTexData; pTexData = 0; }
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Вторник, 03 Июля 2018, 07:50
afq Дата: Вторник, 03 Июля 2018, 08:07 | Сообщение # 5
Разработчик
Сейчас нет на сайте
Snake174 , я тоже раньше в int помещал все четыре цвета. А потом понел что можно по одному ( unsigned char ) для каждого цвета писать в массив, а потом за раз записать в data файл весь массив. И также прочесть одним разом без цикла. Я сегодня поменял и теперь за один раз считывает все цвета из data файла. Сначала размеры считываются, потом количество пикселей, а потом за раз требуемая длина, так лучше.Добавлено (03 Июля 2018, 08:07) ---------------------------------------------Snake174 , а почему ты показываешь старый проект? Как там рисунок отображается, с прозрачностью?
Snake174 Дата: Вторник, 03 Июля 2018, 08:56 | Сообщение # 6
участник
Сейчас нет на сайте
Цитата afq (
)
Snake174, а почему ты показываешь старый проект? Как там рисунок отображается, с прозрачностью?
Да, с прозрачностью. Старый потому что времени нет его допиливать ) Тут тоже всё разом считывается. В цикле то как раз и делается, чтобы было прозрачно. Без него у меня неправильно отображалось.
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Вторник, 03 Июля 2018, 08:58
afq Дата: Вторник, 03 Июля 2018, 11:08 | Сообщение # 7
Разработчик
Сейчас нет на сайте
Snake174 , можешь снимок предоставить прозрачного спрайта?
Snake174 Дата: Вторник, 03 Июля 2018, 13:08 | Сообщение # 8
участник
Сейчас нет на сайте
https://github.com/Snake174/PipmakAssistant/blob/master/res/ramka.png http://snake174.github.io/html/programs/pipmak_assistant.html - на первом скрине она. Да любой файл с прозрачностью скачай и всё.
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Вторник, 03 Июля 2018, 13:10
afq Дата: Среда, 11 Июля 2018, 12:14 | Сообщение # 9
Разработчик
Сейчас нет на сайте
Snake174 , я так понел ты с gl_Begin делал, у меня так тоже с прозрачностью рисовался. Но на нетбуке тормозило если несколько рисунков надо было нарисовать, потому что пока в цикле все поинты нарисуются, пройдет время.
Snake174 Дата: Среда, 11 Июля 2018, 17:11 | Сообщение # 10
участник
Сейчас нет на сайте
Да скинь ты уже весь код. Могу на java скинуть без glBegin если надо.
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
afq Дата: Среда, 11 Июля 2018, 17:58 | Сообщение # 11
Разработчик
Сейчас нет на сайте
Snake174 , давай на java. Весь код? Сюда? Или на github?
Snake174 Дата: Четверг, 12 Июля 2018, 07:34 | Сообщение # 12
участник
Сейчас нет на сайте
Код
package Media; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import main.Engine; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.ARBVertexBufferObject; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL13.*; import static org.lwjgl.opengl.GL15.*; import static org.lwjgl.util.glu.GLU.*; import org.lwjgl.util.vector.Vector2f; import org.lwjgl.util.vector.Vector4f; import org.newdawn.slick.opengl.ImageDataFactory; import org.newdawn.slick.opengl.InternalTextureLoader; import org.newdawn.slick.opengl.LoadableImageData; import org.newdawn.slick.opengl.TextureImpl; import org.newdawn.slick.util.ResourceLoader; public class Sprite { public static final int NORMAL = 0, FLIP_VERTICAL = 1, FLIP_HORIZONTAL = 2; private int texID = 0; private int texWidth = 0; private int texHeight = 0; private int imageWidth = 0; private int imageHeight = 0; private FloatBuffer quadVertices = null; private FloatBuffer quadTexVertices = null; private int vboQuadHandle = 0; private int vboQuadTexHandle = 0; public Sprite( String fileName ) { try { InputStream in = ResourceLoader.getResourceAsStream( fileName ); texID = InternalTextureLoader.createTextureID(); TextureImpl texture = new TextureImpl( fileName, GL_TEXTURE_2D, texID ); glBindTexture( GL_TEXTURE_2D, texID ); LoadableImageData imageData = ImageDataFactory.getImageDataFor( fileName ); ByteBuffer textureBuffer = imageData.loadImage( new BufferedInputStream( in ), false, null ); int width = imageData.getWidth(); int height = imageData.getHeight(); boolean hasAlpha = imageData.getDepth() == 32; texture.setTextureWidth( imageData.getTexWidth() ); texture.setTextureHeight( imageData.getTexHeight() ); texWidth = texture.getTextureWidth(); texHeight = texture.getTextureHeight(); IntBuffer temp = BufferUtils.createIntBuffer( 16 ); glGetInteger( GL_MAX_TEXTURE_SIZE, temp ); int max = temp.get(0); if ((texWidth > max) || (texHeight > max)) { System.err.println("Attempt to allocate a texture to big for the current hardware"); Engine.Ptr().Window.close(); } int srcPixelFormat = hasAlpha ? GL_RGBA : GL_RGB; int componentCount = hasAlpha ? 4 : 3; texture.setWidth( width ); texture.setHeight( height ); texture.setAlpha( hasAlpha ); imageWidth = texture.getImageWidth(); imageHeight = texture.getImageHeight(); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); gluBuild2DMipmaps( GL_TEXTURE_2D, componentCount, InternalTextureLoader.get2Fold( width ), InternalTextureLoader.get2Fold( height ), srcPixelFormat, GL_UNSIGNED_BYTE, textureBuffer ); glBindTexture( GL_TEXTURE_2D, 0 ); float[] vert = { 0.0f, 0.0f, (float)texWidth, 0.0f, (float)texWidth, (float)texHeight, 0.0f, (float)texHeight }; float[] texVertices = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; vboQuadHandle = glGenBuffers(); vboQuadTexHandle = glGenBuffers(); quadVertices = BufferUtils.createFloatBuffer( 4 * 2 ); quadVertices.put( vert ); quadVertices.flip(); quadTexVertices = BufferUtils.createFloatBuffer( 4 * 2 ); quadTexVertices.put( texVertices ); quadTexVertices.flip(); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboQuadHandle ); ARBVertexBufferObject.glBufferDataARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, quadVertices, ARBVertexBufferObject.GL_STREAM_DRAW_ARB ); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboQuadTexHandle ); ARBVertexBufferObject.glBufferDataARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, quadTexVertices, ARBVertexBufferObject.GL_STREAM_DRAW_ARB ); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0 ); } catch (IOException e) { System.out.println( "Can't load texture from file " + fileName + ": " + e.getLocalizedMessage() ); Engine.Ptr().Window.close(); } } public void use() { glBindTexture( GL_TEXTURE_2D, texID ); } public Vector2f size() { return new Vector2f( texWidth, texHeight ); } public int width() { return texWidth; } public int height() { return texHeight; } public Vector2f imageSize() { return new Vector2f( imageWidth, imageHeight ); } public int imageWidth() { return imageWidth; } public int imageHeight() { return imageHeight; } public int ID() { return texID; } public void destroy() { glDeleteTextures( texID ); ARBVertexBufferObject.glDeleteBuffersARB( vboQuadHandle ); ARBVertexBufferObject.glDeleteBuffersARB( vboQuadTexHandle ); } public void setTexEnvi( int param1, int param2 ) { glTexEnvi( GL_TEXTURE_ENV, param1, param2 ); } public static void activeTexture( int num ) { glActiveTexture( GL_TEXTURE0 + num ); glEnable( GL_TEXTURE_2D ); } public static void deactiveTextures( int count ) { for (int i = count - 1; i > -1; --i) { glActiveTexture( GL_TEXTURE0 + i ); glBindTexture( GL_TEXTURE_2D, 0 ); glDisable( GL_TEXTURE_2D ); } } public void draw( Vector4f geom, float angle, float alpha, boolean centered, int mode ) { float[] vert = { 0.0f, 0.0f, geom.getZ(), 0.0f, geom.getZ(), geom.getW(), 0.0f, geom.getW() }; if (centered) { vert = new float[] { -geom.getZ() / 2.0f, -geom.getW() / 2.0f, geom.getZ() / 2.0f, -geom.getW() / 2.0f, geom.getZ() / 2.0f, geom.getW() / 2.0f, -geom.getZ() / 2.0f, geom.getW() / 2.0f }; } quadVertices.clear(); quadVertices.put( vert ); quadVertices.flip(); // Normal render float[] texVertices = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; // Flip vertical if (mode == FLIP_VERTICAL) { texVertices = new float[] { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; } // Flip horizontal else if (mode == FLIP_HORIZONTAL) { texVertices = new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; } quadTexVertices.clear(); quadTexVertices.put( texVertices ); quadTexVertices.flip(); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboQuadHandle ); ARBVertexBufferObject.glBufferSubDataARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0L, quadVertices ); glVertexPointer( 2, GL_FLOAT, 0, 0L ); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboQuadTexHandle ); ARBVertexBufferObject.glBufferSubDataARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0L, quadTexVertices ); glTexCoordPointer( 2, GL_FLOAT, 0, 0L ); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0 ); glLoadIdentity(); if (centered) { glTranslatef( geom.getX(), geom.getY(), 0.0f ); glRotatef( angle, 0.0f, 0.0f, 1.0f ); } else { glTranslatef( geom.getX() + geom.getZ() / 2.0f, geom.getY() + geom.getW() / 2.0f, 0.0f ); glRotatef( angle, 0.0f, 0.0f, 1.0f ); glTranslatef( -geom.getZ() / 2.0f, -geom.getW() / 2.0f, 0.0f ); } glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, texID ); glColor4f( 1.0f, 1.0f, 1.0f, alpha ); glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glDrawArrays( GL_QUADS, 0, 4 ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_VERTEX_ARRAY ); glDisable( GL_TEXTURE_2D ); glDisable( GL_BLEND ); } public void drawPart( Vector4f geom, Vector4f partGeom, float angle, float alpha, boolean centered, int mode ) { float[] vert = { 0.0f, 0.0f, geom.getZ(), 0.0f, geom.getZ(), geom.getW(), 0.0f, geom.getW() }; if (centered) { vert = new float[] { -geom.getZ() / 2.0f, -geom.getW() / 2.0f, geom.getZ() / 2.0f, -geom.getW() / 2.0f, geom.getZ() / 2.0f, geom.getW() / 2.0f, -geom.getZ() / 2.0f, geom.getW() / 2.0f }; } quadVertices.clear(); quadVertices.put( vert ); quadVertices.flip(); float tx = partGeom.getX() / (float)texWidth; float ty = partGeom.getY() / (float)texHeight; float tw = partGeom.getZ() / (float)texWidth; float th = partGeom.getW() / (float)texHeight; // Normal render float[] texVertices = { tx, ty, tx + tw, ty, tx + tw, ty + th, tx, ty + th }; // Flip vertical if (mode == FLIP_VERTICAL) { texVertices = new float[] { tx, ty + th, tx + tw, ty + th, tx + tw, ty, tx, ty }; } // Flip horizontal else if (mode == FLIP_HORIZONTAL) { texVertices = new float[] { tx + tw, ty, tx, ty, tx, ty + th, tx + tw, ty + th }; } quadTexVertices.clear(); quadTexVertices.put( texVertices ); quadTexVertices.flip(); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboQuadHandle ); ARBVertexBufferObject.glBufferSubDataARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0L, quadVertices ); glVertexPointer( 2, GL_FLOAT, 0, 0L ); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboQuadTexHandle ); ARBVertexBufferObject.glBufferSubDataARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0L, quadTexVertices ); glTexCoordPointer( 2, GL_FLOAT, 0, 0L ); ARBVertexBufferObject.glBindBufferARB( ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0 ); glLoadIdentity(); if (centered) { glTranslatef( geom.getX(), geom.getY(), 0.0f ); glRotatef( angle, 0.0f, 0.0f, 1.0f ); } else { glTranslatef( geom.getX() + geom.getZ() / 2.0f, geom.getY() + geom.getW() / 2.0f, 0.0f ); glRotatef( angle, 0.0f, 0.0f, 1.0f ); glTranslatef( -geom.getZ() / 2.0f, -geom.getW() / 2.0f, 0.0f ); } glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, texID ); glColor4f( 1.0f, 1.0f, 1.0f, alpha ); glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glDrawArrays( GL_QUADS, 0, 4 ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_VERTEX_ARRAY ); glDisable( GL_TEXTURE_2D ); glDisable( GL_BLEND ); } }
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games