Buenas! Estaba buscando un foro como este.. donde tubieran programación grafica y me pudieran ayudar.. y me acabo de registrar!
Ya se que visual basic 6 es uno de los peores lenguajes.. u_u pero bueno, algo bueno podré hacer con él ^^
Mi problema es..
estoy haciendo un motor isometrico.. hice la carga de texturas.. todo perfecto, tambien hice que calculara los cuadrados de diferentes perspectivas isométricas.. etc.. por ahora el motor beta está todo bien.. excepto mi error..
Yo uso de esta forma las funciones para limpiar la pantalla, y hacer .present:
Private Sub deviceBeginScene()
With D3DDevice
If (eWindowed = True) Then
.Clear 1, DirectxRect, D3DCLEAR_TARGET, 0, 1#, 0
Else
.Clear 0, ByVal 0&, D3DCLEAR_TARGET, 0, 1#, 0
End If
.BeginScene
End With
End Sub
Private Sub deviceEndScene()
With D3DDevice
.EndScene
If (eWindowed = True) Then
.Present RenderRect, RenderRect, frmMain.hwnd, ByVal 0
Else
.Present ByVal 0&, ByVal 0&, frmMain.hwnd, ByVal 0&
End If
End With
End Sub
El .clear me funciona perfectamente en full screen y windowed.. pero el .present, me da error en modo windowed.. me da error de automatización.. y no lo he podido arreglar.. he probado jugando bastante.. y nada.. siempre el mismo error..
entonces.. envez de usar esa forma que tengo arriba.. me gutaria usar el modo de full screen para los dos modos sin que me de error.. hay alguna posibilidad? porque me da este error?
Gracias a todos los interesados en ayudar ;)
edit: aclaro.. el error me lo da cuando le doy al debugger..
la iniciación del directx la tengo asi:
Public Function engineInitializing(ByRef Top As Integer, ByRef Left As Integer, ByRef Width As Integer, ByRef Height As Integer, Frm As Form, Optional ByRef BitsPerPixel As Byte = 32, Optional ByRef Windowed As Boolean = True) As Boolean
On Error GoTo ErrHandle
Set DX = New DirectX8
Set D3D = DX.Direct3DCreate
Set D3DX = New D3DX8
eWindowed = Windowed
With RenderRect
.Top = Top
.Left = Left
.Right = Width
.bottom = Height
End With
With DirectxRect
.X1 = Left
.X2 = Width
.Y1 = Top
.Y2 = Height
End With
'*******************************
'Initialize video device
'*******************************
Dim DevType As CONST_D3DDEVTYPE
Dim D3DCreate As CONST_D3DCREATEFLAGS
DevType = D3DDEVTYPE_HAL
D3D.GetDeviceCaps D3DADAPTER_DEFAULT, DevType, DevCaps
D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispMode
With D3DWindow
If (Windowed = False) Then
.SwapEffect = D3DSWAPEFFECT_FLIP
.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT
.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE
'Fullscreen mode stuff here
Select Case BitsPerPixel
Case 32
.BackBufferFormat = D3DFMT_A8R8G8B8
Case 24
.BackBufferFormat = D3DFMT_R8G8B8
Case 16
.BackBufferFormat = D3DFMT_R5G6B5
Case Else
.BackBufferFormat = D3DFMT_A8R8G8B8
End Select
.BackBufferWidth = 800
.BackBufferHeight = 600
.BackBufferCount = 1
Else
.Windowed = 1
.SwapEffect = D3DSWAPEFFECT_COPY
.BackBufferFormat = DispMode.Format
End If
.hDeviceWindow = Frm.hwnd
End With
'To check the rest we use:
If Not D3D.CheckDeviceType(D3DADAPTER_DEFAULT, DevType, DispMode.Format, DispMode.Format, 1) = D3D_OK Then
DevType = D3DDEVTYPE_REF
ElseIf Not D3D.CheckDeviceType(D3DADAPTER_DEFAULT, DevType, DispMode.Format, DispMode.Format, 1) = D3D_OK Then
DevType = D3DDEVTYPE_SW
End If
'For Hardware vertex processing:
If Not (DevCaps.DevCaps And D3DDEVCAPS_HWTRANSFORMANDLIGHT) Then
D3DCreate = D3DCREATE_SOFTWARE_VERTEXPROCESSING
Else
D3DCreate = D3DCREATE_HARDWARE_VERTEXPROCESSING
End If
'Set the D3DDevices
If Not D3DDevice Is Nothing Then Set D3DDevice = Nothing
Set D3DDevice = D3D.CreateDevice(D3DADAPTER_DEFAULT, DevType, Frm.hwnd, D3DCreate, D3DWindow)
'Reset the device's rendering state
deviceResetRenderStates
fontInitializing (GetVar(App.Path & "\Init\Fonts.ini", "Info", "Size"))
'Clear the back buffer
D3DDevice.Clear 0, ByVal 0&, D3DCLEAR_TARGET, 0, 0, 0
'Initialize DB
If (texInitialize() = False) Then GoTo ErrHandle
'Initialize Index
loadGrh
engineInitializing = True
Exit Function
ErrHandle:
MsgBox "Error al iniciar el motor grafico"
engineInitializing = False
End Function
Cita de: •Parra en 02 de Junio de 2009, 09:52:19 PM
Ya se que visual basic 6 es uno de los peores lenguajes.. u_u pero bueno, algo bueno podré hacer con él ^^
Me lo vas a contar a mi :P
Lo primero, si te empeñas en programar a pelo con DirectX, visita el sitio DirectX4VB (http://directx4vb.vbgamer.com/). Alli encontaras tutoriales a tutiplen sobre DirectX8 en VB6.0.
Lo segundo, si te animas, te recomiendo que eches un vistazo a mi libreria y asi pases de pegarte con DirectX y perder tiempo acondicionando tu motor a su API. dx_lib32 hace de puente entre DirectX y VB6.0 simplificando muchas tareas comunes en cuanto a graficos, audio, input, video y mas cosas que te pueden servir de ayuda. No es una maravilla en ciertos aspectos pero seguro que te ahorra trabajo para rato, sobre todo con errores como este.
Respondiendo a tu post, yo en mi codigo de render solo tengo una llamada a Clear() y Present() para ventana y pantalla completa ya que ambas sirven por igual. El fallo quizas lo tengas por introducir el parametro RenderRect en la llamada a Present(). El metodo si mal no recuerdo por la documentacion no permite mas parametros que el color de fondo con el que se borrara el buffer y el hwnd de la ventana. Los otros parametros deben ir a 0. En resumen, la misma llamada a Present() en pantalla completa te de funcionar en modo ventana. Prueba y me cuentas.
Salu2...
Si, es verdad, me funciona perfectamente, pero el problema que tengo es que no le puedo poner que haga .present solo en una zona.. debo de hacer .present en toda la pantalla y eso es lo que no quiero hacer
alguna solución?
PD: estaba buscando tu email.. y vi que eres moderador de aqui..
he visto tu dll tambien, pero prefiero hacer mi motor.. ya que tengo varios diferentes armados.. y las bases son buenas..
la web que mencionaste ya la conocia.. la usé sobre todo cuando estube jugando con dx7..
otra cosa.. como reproduces en tu dll los mp3? usas la api de windows?
Lo de realizar varios Present() en distintas partes de la pantalla, no se si te refieres a crear un sistema de DirtyRects o similar, pero creo que esa funcionalidad (no me hagas mucho caso que aunque lo parezca no estoy tan puesto como me gustaria en materia :P) esta deshabilitado en las ultimas versiones de Direct3D, pero aun asi recuerdo algo sobre las SwapsChains que creo que es el sistema que implementa D3D8/9 para poder realizar varios renders al mismo tiempo, lo que no recuerdo si eso era para usar en un mismo contexto (una pantalla o ventana) o en varios (multiples pantallas o ventanas). Creo que mas bien lo segundo que lo primero.
Sobre lo de los MP3, al igual que para el video, utilizo DirectShow ya que este utiliza los codecs instalados en el sistema, incluidos codecs para OGG Vorbis que encontraras en las descargas de mi web. Para ello me base en este tutorial (http://directx4vb.vbgamer.com/DirectX4VB/Tutorials/DirectX8/DXS_MP3Playback.asp) de DirectX4VB.
Cita de: •Parra en 03 de Junio de 2009, 03:23:15 PM
he visto tu dll tambien, pero prefiero hacer mi motor.. ya que tengo varios diferentes armados.. y las bases son buenas..
Tiene gracia, asi estoy desarrollando yo el motor de mi
eterno proyecto juego, usando retales de intentos anteriores :D y es una lastima, dx_lib32 tiene una funcion de dibujo con proyecciones que seguro te vendria de perlas para tu render isometrico :)
Pues nada, suerte con el desarrollo del motor, y paciencia, VB 6.0 suele ser un poco tocapelotas con errores raros y excepciones de memoria a la hora de complicar el codigo en este tipo de desarrollos, sobre todo con algunas llamadas a la API de DirectX (Direct3D para ser mas concretos).
Salu2...
si! exactamente.. eso es.. DirtyRects.
Es lo que quiero hacer =/ pero no puedo.. gracias por toda la informacion sobre tu mp3..
entonces.. no tengo solución para hacer present en un rect? :(
edit: ah si.. acabo de ver el tutorial.. yo ya hice un programa tipo este.. fué facil.. el problema que me encontré fue.. que necesito reproducir distintos mp3 a la vez.. y no pude hacerlo.. =/
el otro problema.. aunque es una tonteria.. es el molesto iconzito.. que te sale cada vez que reproduces algo..
edit2: el unico remedio que veo contra eso.. si no puedo arreglar.. seria hacer un modulo como este:
Option Explicit
'Module to management textures(GUI)
Private Type structGUI
Tex As Direct3DTexture8
Path As String
Width As Integer
Height As Integer
vert(3) As TLVERTEX
End Type
Private Texture() As structGUI
Public Function GuiInitialize() As Boolean
On Error GoTo ErrHandle
Dim i As Long
ReDim Preserve Texture(1 To 1) As structGUI
'Provisional
Texture(1).Path = "\Graphics\frmmain.jpg"
Texture(1).Width = 800
Texture(1).Height = 600
For i = 1 To UBound(Texture)
If GuiLoadTexture(i) = False Then GoTo ErrHandle
GuiSetGeometry (i)
Next i
GuiInitialize = True
Exit Function
ErrHandle:
GuiInitialize = False
Exit Function
End Function
Private Function GuiLoadTexture(ByRef Index As Long) As Boolean
On Error GoTo ErrHandle
With Texture(Index)
Set .Tex = D3DX.CreateTextureFromFileEx(D3DDevice, _
App.Path & .Path, .Width, .Height, _
D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, _
D3DPOOL_MANAGED, D3DX_FILTER_POINT, _
D3DX_FILTER_POINT, D3DColorXRGB(255, 0, 128), _
ByVal 0, ByVal 0)
End With
GuiLoadTexture = True
Exit Function
ErrHandle:
GuiLoadTexture = False
End Function
Private Sub GuiSetGeometry(ByRef Index As Long)
With Texture(Index)
.vert(0) = setVertex(0, 0, 0, 1, -1, 0, 0, 0)
.vert(1) = setVertex(CSng(.Width), 0, 0, 1, -1, 0, 1, 0)
.vert(2) = setVertex(0, CSng(.Height), 0, 1, -1, 0, 0, 1)
.vert(3) = setVertex(CSng(.Width), CSng(.Height), 0, 1, -1, 0, 1, 1)
End With
End Sub
Public Sub GuiDelete()
Dim i As Long
For i = 1 To UBound(Texture)
Set Texture(i).Tex = Nothing
Next i
End Sub
Public Sub GuiRender()
If (testCooperative = False) Then Exit Sub
Dim i As Long
For i = 1 To UBound(Texture)
If Texture(i).Tex Is Nothing Then
If (GuiLoadTexture(i) = False) Then Exit Sub
End If
With D3DDevice
.Clear 0, ByVal 0&, D3DCLEAR_TARGET, 0, 1#, 0
.BeginScene
.SetTexture 0, Texture(i).Tex
.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, Texture(i).vert(0), Len(Texture(i).vert(0))
.EndScene
.Present ByVal 0&, ByVal 0&, frmMain.hwnd, ByVal 0&
End With
Next i
End Sub
aunque no me convence demasiado.. renderizar texturas de 800x600 es mortal..
Cita de: •Parra en 03 de Junio de 2009, 06:06:09 PM
edit: ah si.. acabo de ver el tutorial.. yo ya hice un programa tipo este.. fué facil.. el problema que me encontré fue.. que necesito reproducir distintos mp3 a la vez.. y no pude hacerlo.. =/
El codigo del tutorial se puede aplicar de forma aislada, como un objeto independiente, y reproducir tantos mp3 como quieras. Yo de por si tengo implementado reproduccion dual en dx_lib32 para poder implementar fades entre dos musicas.
Cita de: •Parra en 03 de Junio de 2009, 06:06:09 PM
el otro problema.. aunque es una tonteria.. es el molesto iconzito.. que te sale cada vez que reproduces algo..
A mi no me aparece ningun icono al reproducir audio con DirectShow, pero si es cierto que el otro dia en el ordenador de la oficina me salto la ventana de configuracion del codec ffdshow ya que tiene instalado el K-Lite CodePack, pero solo salio una vez, no ha vuelto a salir. Aun asi debe tener alguna forma de evitar eso. Si no, te tocaria tirar de librerias como FMod para el tema de musica sin pasar por los codecs de DirectShow.
Cita de: •Parra en 03 de Junio de 2009, 06:06:09 PM
aunque no me convence demasiado.. renderizar texturas de 800x600 es mortal..
Por? A mi no me da problemas renderizar texturas grandes, me da problemas, tal y como lo tengo implementado (y creo que lo tienes igual) el pintar un numero alto de sprites, sin importar el tamaño, ya que pinto cada uno como una llamada independiente en vez de agruparlos en un vertexBuffer o similar, que lograria mas rendimiento al dibujar todo en una llamada (aunque para mi al menos es mas complicado de programar). Seria similar a dibujar una malla de poligonos.
Salu2...
Edit:
For i = 1 To UBound(Texture)
If Texture(i).Tex Is Nothing Then
If (GuiLoadTexture(i) = False) Then Exit Sub
End If
With D3DDevice
.Clear 0, ByVal 0&, D3DCLEAR_TARGET, 0, 1#, 0
.BeginScene
.SetTexture 0, Texture(i).Tex
.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, Texture(i).vert(0), Len(Texture(i).vert(0))
.EndScene
.Present ByVal 0&, ByVal 0&, frmMain.hwnd, ByVal 0&
End With
Next i
Estas haciendo un present por cada textura que pintas? 8o Solo necesitas llamar una sola vez a present y clear, justo cuando hayas pintado toda la escena, no en cada llamada a DrawPrimitiveUP. Lo mismo con BeginScene y EndScene. Asi si que baja el rendimiento por los suelos, es como si estuvieras dibujando varias escenas una sobre otra ^_^' En dx_lib32, salvo que uses RenderTarget, solo llama una vez a BeginScene y EndScene, justo antes y despues de llamar a Clear y Present en la funcion de Render.
eso lo hice pensando en actualizar independientemente cuando necesitara actualizar las interfaces.. pero es todo un lio increible.. solo solucionando lo de RECT en .persent me bastaria!
tu tienes lo de los rects implementados en tu libreria? si es asi.. me sabrias decir porque tengo ese error? =/
No entiendo lo del lio. Teniendo bien estructurado el codigo seria simplemente llamar a Clear y Present justo al final del bucle principal:
bucle
{
// Todas las llamadas graficas que se hagan en la escena:
...
dibujar textura
dibujar textura
dibujar textura
...
// Enviamos las escena a la tarjeta grafica para renderizarse:
present
clear
}
Yo lo de los dirtyrect lo olvidaria ya que te vas a complicar mas que otra cosa. Yo implemente nada de DirtyRects, simplemente intente descartar el numero posible de llamadas redundantes, como por ejemplo configurar la misma textura varias veces o aplicar el mismo estado en la textura haciendolo solo una vez. Ten encuenta que D3D8 no es un API 2D y por lo tanto no se comporta igual a la hora de aplicar ciertas tecnicas que si son validas en API's 2D. En 3D lo optimo es agrupar elementos comunes, por ejemplo, los sprites, lo suyo seria poder agruparlos por textura y estados del render por ejemplo, que suelen ser operaciones muy costosas. Agrupas y envias toda la geometria con una sola llamada. Dado que lo estas implementando por el mismo camino que yo hice en su dia, te interesa complicarte lo minimo posible la estructura del motor. Lo suyo seria que hicieras una estructura secuencial como la de arriba. Tus funciones de dibujo u objetos sprite configuren la textura y sus estados y llamen a DrawPrimitiveUP y al final del todo tener preparado un metodo Render() que haga la llamada a Present() y Clear().
Salu2...
listo!! ya lo arreglé.. era todo culpa del spaweffect :P
muchas gracias por interesarse.. y por los consejos.. saludos! (pueden cerrar..)
Pues nada, ya nos contaras que tal tus andaduras con VB6.0, DX8 y tu motor isometrico :)
Salu2...
ok, cuando vaya haciendo el mapeado.. postearé alguna imagen ;)